Swift 3: Cannot Convert Value of Type 'Nsmutabledictionary' to Expected Argument Type '[Anyhashable:Any]!'

Swift 3: Cannot convert value of type 'NSMutableDictionary' to expected argument type '[AnyHashable : Any]!'

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:

Swift 3.0.1/Xcode 8.1

  • Optional values including 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.)

  • All numeric types and Bool

Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, as well as
Int, UInt, Double, Float, CGFloat and Bool. These are converted to NSNumber.

  • String

Converted to NSString.

  • Array, where Element is Objective-C safe

Converted to NSArray.

  • Dictionary, where Key and Value are Objective-C safe

Converted to NSDictionary.

  • Set, where Element is Objective-C safe

Converted to NSSet

  • NSObject descendent types

Not converted, used as is.

  • Value types which have counter-part reference types

See the list here.

  • Value types where NSValue has an initializer for

NSRange,
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.)

Bad things (example)

Still some values may be converted to _SwiftValue even in Swift 3.0.1.

  • Swift only types such as (Swift-only)enum, struct, tuple...

(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.



Swift 3.0.0/Xcode 8.0

  • Non-Optional numeric types and Bool

Int, UInt, Double, Float, CGFloat and Bool. These are converted to NSNumber.

  • Non-Optional String

Converted to NSString.

  • Non-Optional Array, where Element is Objective-C safe

Converted to NSArray.

  • Non-Optional Dictionary, where Key and Value are Objective-C safe

Converted to NSDictionary.

  • Non-Optional Set, where Element is Objective-C safe

Converted to NSSet

  • Non-Optional NSObject descendent types

Not converted, used as is.

  • Non-Optional value types which have counter-part reference types

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
  • Any Optional values including nil
  • Swift only types such as (Swift-only)enum, struct, tuple...

Cannot convert value of type NSMutableDictionary? to expected argument type [NSObject: AnyObject]!

You need to make a variable to hold your NSMutableDictionary then pass it to send() method.

let dictionary = (builder?.build())! as NSMutableDictionary
tracker?.send(dictionary as [NSObject: AnyObject]!)

UPDATE: Another clean way to use in Swift 3

guard let tracker = GAI.sharedInstance().defaultTracker else { return }
tracker.set(kGAIScreenName, value: "ViewController")
guard let builder = GAIDictionaryBuilder.createScreenView() else {
return }
tracker.send(builder.build() as [NSObject:AnyObject])

Cannot convert value of type 'NSMutableDictionary' to expected argument type '[String: AnyObject]?'

Unlike immutable NSDictionary the mutable NSMutableDictionary is not related to a Swift Dictionary and cannot be bridged nor casted.

There is a simple rule to avoid those problems:

In Swift use always Swift native collection types whenever possible.

var addressDict = [String:AnyObject]()
...
addressDict[kSubAdministrativeArea] = self.subAdministrativeArea
...

Cannot convert value of type 'NSArray' to expected argument type '[Any]!'

  1. Replace NSArray with [NSValue], as @vadian suggested
  2. Use optional conversion as?, since it is more reliable and you won't get a crash if conversion fails.
  3. Use subscript instead of valueForKey method.

Here is the code:

if let antiAliasing = dict["antAliasing"] as? [NSValue] {
UIBezierPath.interpolateCGPoints(withHermite: antiAliasing, closed: true)
}

How to convert [AnyHashable: Any] to NSmutableDictionary

It is very straight forward

var d = [AnyHashable: Any]()
d["name"] = "Jay"
d[0] = "Jay"
print(d)
//[AnyHashable(0): "Jay", AnyHashable("name"): "Jay"]

let nsD = NSDictionary(dictionary: d)
print(nsD)
//{
// 0 = Jay;
// name = Jay;
//}

let nsMD = NSMutableDictionary(dictionary: d)
print(nsMD)
//{
// 0 = Jay;
// name = Jay;
//}

Bridging example:

Your swift class may look like this

@objc class Swft: NSObject {
@objc var d = [AnyHashable: Any]()

override init() {
super.init()
d["name"] = "jay"
}

@objc func method() ->[AnyHashable: Any] {
return d
}
}

And your Objective-C class may look like this, .m

#import "Objc.h"
#import "{Your_project_name}-Swift.h"

@interface Objc ()

@end

@implementation Objc

- (void)someMethod {

Swft *s = [[Swft alloc] init];
NSLog(@"1234567890 %@", s.d);
// 1234567890 {
// name = jay;
// }
NSLog(@"0987654321 %@", [s method]);
// 0987654321 {
// name = jay;
// }

}

@end

Swift 3.0 passing NSArray as Any

This code seems to be working in playgrounds and not showing any errors

func someFunc(nsarray: NSArray) {
/// some implementation
}

let array = [Any]()

someFunc(nsarray: array as NSArray)

Swift - Cannot convert value of type 'Any?' to expected argument type 'String'

If it is ok to crash

let temp = json["srvFile0"]! as! String 

But much better would be to avoid that

if let temp = json["srvFile0"], let serverFile = temp as? String {

Cannot convert value of type

In swift 3 some things have changed and one of those is that id from objective c is now Any in swift instead of AnyObject. Change your idContext to type Any.

Also you must also change the type of your dictionary and the string to an optional. So it becomes String? and [AnyHashable: Any]?.

For-in loop requires '[UserVehicles]?' to conform to 'Sequence'; did you mean to unwrap optional? Swift

You need to supply a default value for optional as a good practise instead of force unwrap

for i in vehicleList?._embedded.userVehicles ?? [] { }


Related Topics



Leave a reply



Submit