A fairly simple piece of code
var dict: [String: AnyObject] = [:]
dict["key"] = "value"
generates the following compile-time error
Cannot assign value of type 'String' to type 'AnyObject?'
Simple type checks tell me that String
is AnyObject
"value" is AnyObject // returns true
I could change AnyObject
to Any
and everything would work
var dict: [String: Any] = [:]
dict["key"] = "value"
but I want to understand why do I get the error? Is String
no longer AnyObject
? Or is this a bug?
In b6, String no longer magically bridges to NSString. String is not a class; it's a struct. You need to do the bridging by hand:
dict["key"] = "value" as AnyObject
The fact that is
still seems to be bridging is likely a bug and should be reported.
It goes without saying that [String: AnyObject]
and [String: Any]
should be used as little as possible in your code.
(Make sure to follow the link Hamish provides in the comments below.)
I'll complement to @RobNapier's answer with some official sources.
The removal of the implicit bridging mechanisms was accepted in the following Swift evolution proposal, to be implemented for Swift 3
Previously, implicit conversions were available from some Swift native types to associated Objective-C types (Swift types conforming to private protocol _ObjectiveCBridgeable
, e.g. natively Int
, String
, )
For this reason, we decided to make a compromise. We would require explicit bridging casts when converting from a bridged Objective-C type to its associated Swift value type (E.g., NSString -> String), but not the other way around.
... [From SE-0072]
With Swift 3, such implicit conversion mechanisms will no longer be available.
With the introduction of Objective-C generics last year, along with all of the awesome improvements to API importing happening for Swift 3, I think it’s time that we take another look at completing this work.
...
I propose that we fully eliminate implicit bridging conversions in Swift 3. This would mean that some users might have to introduce more explicit casts in their code, but we would remove another special case from Swift's type system and be able to further simplify the compiler.
...
Code that previously relied on implicit conversions between Swift value types and their associated bridged Objective-C type will now require a manual coercion via an
as
cast.
Finally, the release notes for Xcode 8 beta 6 (login required) states that this proposal has now been implemented for beta 6:
New in Xcode 8 beta 6 - Swift Compiler: Swift Language
...
- Bridging conversions are no longer implicit. The conversion from a Swift value type to its corresponding object can be forced with
as
. For example:string as NSString
. Any Swift value can also be converted to its boxed id representation withas AnyObject
. (SE-0072)
W.r.t. new "boxed id" allowing explicit conversion for any Swift value to AnyObject
, see e.g. the following thread:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With