Re: [swift-users] Codable Range in Xcode 9 playground

2017-10-20 Thread Thierry Passeron via swift-users
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

2017-10-17 Thread Thierry Passeron via swift-users
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

2017-07-26 Thread Thierry Passeron via swift-users
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 Coughlin  a é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

2017-07-25 Thread Thierry Passeron via swift-users
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

2017-07-07 Thread Thierry Passeron via swift-users
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

2017-07-07 Thread Thierry Passeron via swift-users
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

2016-10-16 Thread Thierry Passeron via swift-users
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