Re: [swift-users] Codable Range in Xcode 9 playground
Thank you Brent for your effort. I will try this way. By the way I thought that the protocol conformance with conditions were already retained/adopted in Swift 4. You seem to say that it was postponed. It’s too bad in my opinion. But thanks again for the info. > On 18 Oct 2017, at 23:38, Brent Royal-Gordon <br...@architechies.com> wrote: > >> On Oct 17, 2017, at 10:00 AM, Thierry Passeron via swift-users >> <swift-users@swift.org> wrote: >> >> Hi everyone, >> >> In the process of familiarising myself with Encodable/Decodable protocols I >> was trying to apply it to the Range struct in order to persist a Range in >> CoreData records. However, I seem to hit the wall with it and keep getting >> errors. This happens in the Xcode 9.0.1 playground, not sure which swift >> version is used if it’s 4 or 3.x but anyways, I get “Ambiguous reference to >> member ‘encode(_:forKey:)’ on every encode/decode method calls. >> >> extension Range { >> enum CodingKeys : String, CodingKey { >> case upperBound >> case lowerBound >> } >> } >> >> extension Range: Codable { >> >> public func encode(to encoder: Encoder) throws { >> var container = encoder.container(keyedBy: CodingKeys.self) >> try container.encode(upperBound, forKey: .upperBound) >> try container.encode(lowerBound, forKey: .lowerBound) >> } >> >> public init(from decoder: Decoder) throws { >> let values = try decoder.container(keyedBy: CodingKeys.self) >> self.upperBound = try values.decode(Bound.self, forKey: .upperBound) >> self.lowerBound = try values.decode(Bound.self, forKey: .lowerBound) >> } >> >> } >> >> How would one add Codable support to such a struct? I’m feeling it may >> require a bit of “where” clauses in extension because of the Generic aspect >> of this struct but I fail to make the compiler happy. > > What you'd *like* to be able to do is say that a Range is codable only when > its bounds are also codable: > > extension Range: Codable where Bound: Codable { > … > } > > But this isn't currently supported in Swift. (The compiler team is working on > it right now, and it'll probably be here in Swift 5, if not in 4.1.) So for > the time being, you have to fake it dynamically. Unless you want to use > private APIs, the easiest way is probably to use a dictionary: > > extension Range: Decodable /* where Bound: Decodable */ { > public init(from decoder: Decoder) throws { > let dict = try [String: Bound](from: decoder) > > guard let lower = > dict[CodingKey.lowerBound.stringValue] else { > throw DecodingError.valueNotFound(Bound.self, > .init(codingPath: decoder.codingPath + [CodingKey.lowerBound], > debugDescription: "lowerBound not found") > } > guard let lower = > dict[CodingKey.upperBound.stringValue] else { > throw DecodingError.valueNotFound(Bound.self, > .init(codingPath: decoder.codingPath + [CodingKey.upperBound], > debugDescription: "upperBound not found") > } > > self.init(uncheckedBounds: (lower: lower, upper: upper)) > } > } > > extension Range: Encodable /* where Bound: Encodable */ { > public func encode(to encoder: Encoder) throws { > try [CodingKey.lowerBound.stringValue: lowerBound, > CodingKey.upperBound.stringValue: upperBound].encode(to: encoder) > } > } > > This should mimic the structure you'll eventually be able to generate with a > keyed container; when Swift becomes able to do this properly, you can update > the code to encode and decode directly. > > Hope this helps, > -- > Brent Royal-Gordon > Architechies ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
[swift-users] Codable Range in Xcode 9 playground
Hi everyone, In the process of familiarising myself with Encodable/Decodable protocols I was trying to apply it to the Range struct in order to persist a Range in CoreData records. However, I seem to hit the wall with it and keep getting errors. This happens in the Xcode 9.0.1 playground, not sure which swift version is used if it’s 4 or 3.x but anyways, I get “Ambiguous reference to member ‘encode(_:forKey:)’ on every encode/decode method calls. extension Range { enum CodingKeys : String, CodingKey { case upperBound case lowerBound } } extension Range: Codable { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(upperBound, forKey: .upperBound) try container.encode(lowerBound, forKey: .lowerBound) } public init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) self.upperBound = try values.decode(Bound.self, forKey: .upperBound) self.lowerBound = try values.decode(Bound.self, forKey: .lowerBound) } } How would one add Codable support to such a struct? I’m feeling it may require a bit of “where” clauses in extension because of the Generic aspect of this struct but I fail to make the compiler happy. Any help appreciated. Best regards, Thierry ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
Re: [swift-users] ThreadSanitizer: data race
Thanks Devin, that was the problem! After initialising with the recursive type attribute, it is now working. This list is my saviour. Thank you guys! I hope I can make it up to you someday. > Le 25 juil. 2017 à 22:37, Devin Coughlina écrit : > > pthread_mutex_init(, nil) ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
[swift-users] ThreadSanitizer: data race
Hi everyone, I don’t know if it’s the good place to ask for this, so if it’s not, please be kind enough to tell me where I should post this question. I’m having a hard time figuring out why, since I activated ThreadSanitizer to my Xcode 9 scheme, I keep seeing race conditions when using OperationQueue and a custom BlockOperation subclass I made to deal with Asynchronous operations. If I refer to the documentation on Operation, it says that isCancelled, isFinished, isExecuting properties must be thread safe since you never know from which thread they can be invoked. So I decided to go for a pthread_mutex_lock/unlock to protect the critical parts. For instance isFinished looks like this: class AsyncBlockOperation : BlockOperation { enum State: String { case ready = "Ready", executing = "Executing", finished = "Finished" fileprivate var keyPath: String { return "is" + self.rawValue } } private var state: State = .ready { willSet { willChangeValue(forKey: state.keyPath) willChangeValue(forKey: newValue.keyPath) } didSet { didChangeValue(forKey: oldValue.keyPath) didChangeValue(forKey: state.keyPath) } } private var mutex = pthread_mutex_t() override var isFinished: Bool { pthread_mutex_lock() defer { pthread_mutex_unlock() } return state == .finished } /* Same goes for isCancelled, and isExecuting… */ } I thought that the problem of « thread-safe » would be solved with these lock/unlock mutex but when an other thread accesses one of the these properties I get a data race warning by the ThreadSanitizer. What do I do wrong? Is it possible that ThreadSanitizer reports a false positive? How should I debug this kind of issue? Any help would be much appreciated. I can provide a Xcode test project with a running example of this issue. Thanks in advance. Best regards, Thierry ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
Re: [swift-users] UserDefaults with generic keys
Nice! The key is to have a non generic base class as storage for statics and a subclass for generic types… brilliant. I am definitely going to try this one. Vladimir’s solution is also a nice fact to know. The key point of the compile error message seems to be « static __stored__ « hence, with computed it works. Thanks for the posting. > Le 7 juil. 2017 à 15:54, Kim Burgestrand <k...@burgestrand.se> a écrit : > > Here's yet another alternative. I read an article doing this very thing a > while back, it might be interesting to you: > http://radex.io/swift/nsuserdefaults/static/ > <http://radex.io/swift/nsuserdefaults/static/>. It makes the key type a class > instead, and inherits from a non-generic parent class to which it adds the > static properties. > > The gist of it is roughly like this (although the article uses subscript, > which does not allow for a generic implementation so I use a get/set approach > here for brevity): > > ``` > class DefaultsKeys {} > final class DefaultsKey: DefaultsKeys { > let value: String > > init(_ value: String) { > self.value = value > } > } > > extension UserDefaults { > func get(_ key: DefaultsKey) -> T? { > return object(forKey: key.value) as? T > } > > func set(_ key: DefaultsKey, to value: T) { > set(value, forKey: key.value) > } > } > > extension DefaultsKeys { > static let version = DefaultsKey("version") > } > > let defaults = UserDefaults.standard > defaults.set(.version, to: "1.0") > let version = defaults.get(.version) > print(version ?? "N/A") > ``` > > On Fri, 7 Jul 2017 at 14:00 Vladimir.S via swift-users <swift-users@swift.org > <mailto:swift-users@swift.org>> wrote: > On 07.07.2017 14:02, Thierry Passeron via swift-users wrote: > > Hi Everyone, > > > > Using Swift 3.1, I was wondering if I could come up with something largely > > inspired by Notification.Name to help me deal with UserDefaults so I > > started by doing something like: > > The only kind of solution I was able to implement, is with calculated > properties in > extension. Hope this have any sense and most likely can be improved(code from > swift > sandbox): > > struct DefaultsKey { > var rawValue : String > > init(_ name: String) { > rawValue = name > } > } > > extension DefaultsKey { > static var version : DefaultsKey { return > DefaultsKey("version") } > static var code : DefaultsKey { return DefaultsKey("code") } > } > > func UserDefaults_standard_object(forKey: String) -> Any? { > switch forKey { > case "version" : return "1.0.0" > case "code" : return 12345 > default : return nil > } > } > > func Defaults(_ key: DefaultsKey) -> T? { >return UserDefaults_standard_object(forKey: key.rawValue) as? T > } > > let version = Defaults(.version) > let code = Defaults(.code) > > print(version ?? "-no value-", type(of: version)) // 1.0.0 Optional > print(code ?? "-no value-", type(of: code)) // 12345 Optional > > > > > > > public struct DefaultsKey: RawRepresentable, Equatable, Hashable, > > Comparable { > > > >public var rawValue: String > >public var hashValue: Int { return rawValue.hash } > > > >public init(_ rawValue: String) { self.rawValue = rawValue } > >public init(rawValue: String) { self.rawValue = rawValue } > > > >/* Protocols implementation .. */ > > } > > > > Now I can make extensions like: > > > > extension DefaultsKey { > >static let version = DefaultsKey("version ») > > } > > > > And use it to query the UserDefaults. > > > > public func Defaults(_ key: DefaultsKey) -> T? { > >return UserDefaults.standard.object(forKey: key.rawValue) as? T > > } > > > > let version: String? = Defaults(.version) > > > > Nice, concise, I love it… > > > > But It could be even better to let the compiler check the return type of > > the UserDefault for the DefaultKey that I ask if only I could create the > > key and bind it to a type. So I tried this: > > > > public struct DefaultsKey: RawRepresentable, Equatable, Hashable, > > Comparable { > > … > > } > > > > extension DefaultsKey { > >static let version = DefaultsKey("version ») > > } > > > > But this doesn’t co
[swift-users] UserDefaults with generic keys
Hi Everyone, Using Swift 3.1, I was wondering if I could come up with something largely inspired by Notification.Name to help me deal with UserDefaults so I started by doing something like: public struct DefaultsKey: RawRepresentable, Equatable, Hashable, Comparable { public var rawValue: String public var hashValue: Int { return rawValue.hash } public init(_ rawValue: String) { self.rawValue = rawValue } public init(rawValue: String) { self.rawValue = rawValue } /* Protocols implementation .. */ } Now I can make extensions like: extension DefaultsKey { static let version = DefaultsKey("version ») } And use it to query the UserDefaults. public func Defaults(_ key: DefaultsKey) -> T? { return UserDefaults.standard.object(forKey: key.rawValue) as? T } let version: String? = Defaults(.version) Nice, concise, I love it… But It could be even better to let the compiler check the return type of the UserDefault for the DefaultKey that I ask if only I could create the key and bind it to a type. So I tried this: public struct DefaultsKey: RawRepresentable, Equatable, Hashable, Comparable { … } extension DefaultsKey { static let version = DefaultsKey("version ») } But this doesn’t compile: error: static stored properties not supported in generic types I guess I could keep all the keys outside an extension scope but then it would not be as concise as with Notification.Name Please let me know if there is indeed a generic way to solve this. Any help would be greatly appreciated. Thanks in advance. Thierry. ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
[swift-users] Migrating to Swift 3 Dispatch
Hello All, I’m in the process of migrating older code to Swift 3 and I’m stuck on this one. How do you create a timer dispatch source? Old code: let source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue) dispatch_source_set_timer(source, dispatch_time(DISPATCH_TIME_NOW, 0), UInt64(interval * 1000_000_000), 0) dispatch_source_set_event_handler(source) { // Do something useful } dispatch_resume(source) New code: ??? Xcode is not helping me with any of the required refactoring. The convert tool throws many errors but no proposition. I have tried to explore the New Dispatch headers with no luck. DISPATCH_SOURCE_TYPE_TIMER can’t be found… ok so It seems to be replaced with a protocol DispatchSourceTimer and … no initializer… I think I don’t yet catch with the whole philosophy of this new version. I’d be pleased if anyone cared to enlighten me. Thanks and regards, Thierry ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users