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:
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
Write and Read a Plist in Swift with Simple Data
What's the Difference Between If Nil != Optional … and If Let _ = Optional …
Working with C Strings in Swift, Or: How to Convert Unsafepointer<Cchar> to Cstring
Bool Being Seen as Int When Using Anyobject
How to Copy a Struct and Modify One of Its Properties at the Same Time
What's the Equivalent to String.Localizedstringwithformat(_:_:) for Swiftui's Localizedstringkey
Getting Country Name from Country Code
Use Cocoapods With an App Extension
iOS 8 Beta Today Extension Widget Not Showing in a Swift App
Swift: How to Delete Part of Audio
Can't Create a Range in Swift 3
Unsaferawpointer Assumingmemorybound VS. Bindmemory
Firebase Storage Downloadurl()' Is Deprecated: Use 'Storagereference.Downloadurlwithcompletion()