This code worked before Swift 3. (Curse you Swift 3!)
Now it's showing this error against the Flurry.logEvent(eventName, withParameters: userData!)
line:
Cannot convert value of type 'NSMutableDictionary' to expected argument type '[AnyHashable : Any]!'
Casting userData!
to [AnyHashable : Any]
produces this error:
Cannot convert value of type 'NSMutableDictionary' to type '[AnyHashable : Any]' in coercion
func logEvent(_ eventName: String, userData: NSMutableDictionary?) {
// Use <userData> or create new one?
var userData = userData
if userData == nil {
userData = NSMutableDictionary()
}
// Set base properties
userData!.setObject(gUser.tofus.count, forKey: "Num Tofus" as NSCopying)
userData!.setObject(gUser.getLifetimeTofus(), forKey: "Num Lifetime Tofus" as NSCopying)
// Call Flurry
DispatchQueue.main.async {
Flurry.logEvent(eventName, withParameters: userData! as [AnyHashable:Any])
}
}
What's the right syntax for Swift 3?
If that
Flurry.logEvent(_:withParameters:)
takes[AnyHashable: Any]
, why don't you use it as your localuserData
?UPDATE
Xcode 8.1 GM seed including SE-0139 and SE-0140 is out, so the list below is updated.
These are the Objective-C safe types, when set to a
[AnyHashable: Any]
dictionary (or set in a[Any]
array, or simply passed toAny
which is a non-nullid
in Objective-C) in which is passed to Objective-C world:Swift 3.0.1/Xcode 8.1
nil
nil
is converted toNSNull
, all non-nil Optionals are unwrapped.(
NSNull
may not be what you want. Still be careful about nil-checking.)Bool
Int8
,UInt8
,Int16
,UInt16
,Int32
,UInt32
,Int64
,UInt64
, as well asInt
,UInt
,Double
,Float
,CGFloat
andBool
. These are converted toNSNumber
.String
Converted to
NSString
.Array
, whereElement
is Objective-C safeConverted to
NSArray
.Dictionary
, whereKey
andValue
are Objective-C safeConverted to
NSDictionary
.Set
, whereElement
is Objective-C safeConverted to
NSSet
NSObject
descendent typesNot converted, used as is.
See the list here.
NSValue
has an initializer forNSRange
,CGPoint
,CGVector
,CGSize
,CGRect
,CGAffineTransform
,UIEdgeInsets
,UIOffset
,CATransform3D
,CMTime
,CMTimeRange
,CMTimeMapping
,CLLocationCoordinate2D
,MKCoordinateSpan
,SCNVector3
,SCNVector4
,SCNMatrix4
. These types are converted toNSValue
. (NSRange
was already convertible toNSValue
in older Swifts, but not well-documented.)Bad things (example)
Still some values may be converted to
_SwiftValue
even in Swift 3.0.1.(See this list.)
I haven't checked all wrapper enums and structs, but some of them (for example,
Notification.Name
toNSString
) seem to be safely converted.Swift 3.0.0/Xcode 8.0
Bool
Int
,UInt
,Double
,Float
,CGFloat
andBool
. These are converted toNSNumber
.String
Converted to
NSString
.Array
, whereElement
is Objective-C safeConverted to
NSArray
.Dictionary
, whereKey
andValue
are Objective-C safeConverted to
NSDictionary
.Set
, whereElement
is Objective-C safeConverted to
NSSet
NSObject
descendent typesNot converted, used as is.
See the list here. (The linked article is updated for Swift 3.0.1.)
Bad things (example)
These may be converted to
_SwiftValue
, which is completely useless and disastrous in Objective-C world.Int8
,UInt8
,Int16
,UInt16
,Int32
,UInt32
,Int64
,UInt64
nil