Re: [swift-users] UserDefaults with generic keys

2017-07-07 Thread Kim Burgestrand via swift-users
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/. 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> 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 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 mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Why does casting to Any make my forced downcast not crash?

2017-03-15 Thread Kim Burgestrand via swift-users
Oh, wow, the reported bug is quite similar but not exactly.

Anyway, I reported the problem here https://bugs.swift.org/browse/SR-4248.
I guess the discussion will continue in there.

Thanks again!

On Wed, 15 Mar 2017 at 12:51 Kim Burgestrand  wrote:

> Found the answer to my follow-up question! It's a known and reported bug:
> https://bugs.swift.org/browse/SR-912
>
> Thanks!
>
> On Wed, 15 Mar 2017 at 12:47 Kim Burgestrand  wrote:
>
> On Tue, 14 Mar 2017 at 19:50 Joe Groff  wrote:
>
>
> It shouldn't. Please file a bug, if you haven't already.
>
>
> Will do! I'll file a bug that casting to `Any` first causes different
> behavior.
>
> Follow-up question, looking at the expression `name as! T`, is it
> expected to cause a nil-unwrapping runtime error when `name == nil` and `T
> == Optional`? Mind you, `(nil as! Optional)` does not
> cause an error.
>
> If the nil-unwrapping error is expected, how can I write it so that it
> doesn't, and instead returns nil?
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Why does casting to Any make my forced downcast not crash?

2017-03-15 Thread Kim Burgestrand via swift-users
On Tue, 14 Mar 2017 at 19:50 Joe Groff  wrote:

>
> It shouldn't. Please file a bug, if you haven't already.
>

Will do! I'll file a bug that casting to `Any` first causes different
behavior.

Follow-up question, looking at the expression `name as! T`, is it expected
to cause a nil-unwrapping runtime error when `name == nil` and `T ==
Optional`? Mind you, `(nil as! Optional)` does not cause an
error.

If the nil-unwrapping error is expected, how can I write it so that it
doesn't, and instead returns nil?
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Why does casting to Any make my forced downcast not crash?

2017-03-13 Thread Kim Burgestrand via swift-users
Here are two implementations that I'd expect to be equivalent, but
something's different because the first example crashes, whereas the second
example does not crash.

What's the difference between these two? Why does casting to Any before the
forced downcast to T have any effect?

Example 1: (`unexpectedly found nil while unwrapping an Optional value`)
```
func cast(_ name: String?) -> T {
return name as! T
}

debugPrint((cast(nil) as String?) as Any))
```

Example 2: (prints `nil`)
```
func cast(_ name: String?) -> T {
return (name as Any) as! T
}


debugPrint((cast(nil) as String?) as Any)
```
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users