Why How to Use Codable with a Project Language Version of Swift 3.3

Why can I use Codable with a project language version of Swift 3.3?

I think may be you are using latest Swift compiler.

iOS Generic type for codable property in Swift

T must also conform to Codable

struct BaseJsonStruct<T : Codable> : Codable {
let info: String
let data: T
}

Conditional Conformance to Hashable

The conditional compilation statement #if swift(...) checks against the language version you're running with – which can differ from the compiler (and therefore standard library) version.

In your case, it sounds like you're using a Swift 4.2 compiler in Swift 4 compatibility mode, which gives you a language version of 4.1.50. This therefore passes the conditional compilation statement and your extension is compiled, giving you a duplicate conformance.

In order to check for a compiler version less than 4.2, you want the following:

// less than 4.2 in Swift 4 compat mode and (less than 4.2 in 3 compat mode or
// greater than 4).
#if !swift(>=4.1.50) && (!swift(>=3.4) || swift(>=4.0))
extension Array : Hashable where Element : Hashable {
public var hashValue: Int {
let prime = 31
var result = 1
for element in self {
result = prime * result + element.hashValue
}
return result
}
}
#endif

Things will be much better with the new #if compiler directive, which is available in Swift 4.2 from Xcode 10 beta 4 onwards (confirmed by @MartinR). With that, you can directly test for the compiler version, ignoring any compatibility modes it might be running in.

This doesn't help your specific case as you need the code to be understood by both Swift 4.2 and 4.1 compilers (as also pointed out by Martin), but for future compatibility problems, you could for example use #if !compiler(>=5) in order to only compile a block of code if using a 4.2 compiler.

How to add Firebase Functions v8 to a Swift iOS project and use Codable in httpsCallable?

Add FirebaseFunctionsSwift-Beta framework to the build target:

Sample Image

Odd Generics & Optional Behavior in Swift 4.2 after upgrading to iOS 12.2 (Xcode 10.2)

This is due to SE-0213: Literal initialization via coercion which means that Optional(nil) is now treated as nil as Optional by the compiler. Previously with Optional(nil), you'd get a wrapped nil value e.g Int??.some(nil), however now you get just nil.

So for the following:

let phone: Phone<Int?> = Phone.create(initial: Optional(nil))

the compiler is treating it as:

let phone: Phone<Int?> = Phone.create(initial: nil as Optional)

which is equivalent to:

let phone: Phone<Int?> = Phone.create(initial: nil)

Because you've specified the generic parameter T to be Int?, the initial: parameter takes an Int??. Therefore by passing nil you're passing Int??.none, and therefore the unwrapping fails.

One way to restore the old behaviour is to specify .init explicitly in order to force the compiler to call the initialiser:

let phone: Phone<Int?> = Phone.create(initial: Optional.init(nil))

Now you're passing an Int??.some(nil) to the parameter and the unwrapping succeeds.

However I would question why you're dealing with doubly wrapped optionals in the first place – I would strongly encourage avoiding them unless absolutely necessary.



Related Topics



Leave a reply



Submit