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 local userData?
func logEvent(_ eventName: String, userData: NSMutableDictionary?) {
// Use <userData> or create new one?
var userData = userData as NSDictionary? as? [AnyHashable: Any] ?? [:]
// Set base properties
userData["Num Tofus"] = gUser.tofus.count
userData["Num Lifetime Tofus"] = gUser.getLifetimeTofus()
// Call Flurry
DispatchQueue.main.async {
Flurry.logEvent(eventName, withParameters: userData)
}
}
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 to Any which is a non-null id in Objective-C) in which is passed to Objective-C world:
nil
nil is converted to NSNull, 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 as
Int, UInt, Double, Float, CGFloat and Bool. These are converted to NSNumber.
StringConverted to NSString.
Array, where Element is Objective-C safeConverted to NSArray.
Dictionary, where Key and Value are Objective-C safeConverted to NSDictionary.
Set, where Element 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 to NSValue. (NSRange was already convertible to NSValue in older Swifts, but not well-documented.)
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 to NSString) seem to be safely converted.
Bool
Int, UInt, Double, Float, CGFloat and Bool. These are converted to NSNumber.
String
Converted to NSString.
Array, where Element is Objective-C safeConverted to NSArray.
Dictionary, where Key and Value are Objective-C safeConverted to NSDictionary.
Set, where Element 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.)
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
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