Swift 2: How can i assign a dictionary to AnyObject? - swift

I was using swift 1.2 and everything was going fine. after upgrading my Xcode to 7 . I faced some weird problems.
My code was :
let postData : AnyObject = ["username":username , "password":password] ;
I need this variable to be AnyObject, because
let jsonObject : AnyObject = postData ;
let jsonString = JSONStringify(jsonObject)
let data1 = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
let task1 = NSURLSession.sharedSession().uploadTaskWithRequest(request, fromData: data1) {
(Data, Response, Error) -> Void in
needs a Anyobject for post Data header.
The error is
Value of type '[String : String?]' does not conform to specified type 'AnyObject'
can any one help me?

The problem is your password variable is an Optional<String>. This means the conversion from Swift dictionary to AnyObject (I think it tries to convert it to an NSDictionary) will fail.
If you do
let postData : AnyObject = ["username":username , "password":password!]
It should work unless the password is nil (check that before creating the dictionary)
If you want to be able to have null passwords in the output, you can do this in your dictionary
let postData : [String : AnyObject] = ["username":username , "password":password ?? NSNull()]
The following works
let pw: String? = "pw"
let pw2: String? = nil
var foo: [String : AnyObject] = ["bar" : pw ?? NSNull(), "baz" : pw2 ?? NSNull()]
let data = try NSJSONSerialization.dataWithJSONObject(foo, options: NSJSONWritingOptions.PrettyPrinted)
let str = NSString(data: data, encoding: NSUTF8StringEncoding)!
print(str)
And prints
{
"baz" : null,
"bar" : "pw"
}

I assume you are passing parameters to a request which require key as String and value can be AnyObject. Try this:
let postData: [String: AnyObject] = ["username":username , "password":password]
Also make sure username and password are not optional, and in that case, use ! to unwrap them if you are sure values wil be there.
let postData: [String: AnyObject] = ["username":username!, "password":password!]
or you can use
let postData: [String: AnyObject] = ["username":username ?? "", "password":password ?? ""]

Related

Finding nil when reading from database

When trying to read from Firebase I get
Fatal error: Unexpectedly found nil while unwrapping an Optional value
Code for reading the database:
ref = Database.database().reference().child("userDatabases").child(userID!).child("-Lk__eup2Z7WR-iqtXkI").child("-Lk__gmhOTWfVzEPVo2t")
ref?.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children.allObjects as! [DataSnapshot] {
let dict = child.value as? [String : AnyObject] ?? [:]
self.objectProducer.append(dict["objectProducer"] as! String)
self.objectType.append(dict["objectType"] as! String)
self.objectAmount.append(dict["amount"] as! String)
self.objectMeasureUnit.append(dict["unit"] as! String)
}
})
If I try to print for example: print(dict["objectProducer"]) I get the correct result.
The FirebaseStructure I´m trying to read from looks like this:
"-Lk__eup2Z7WR-iqtXkI" : {
"-Lk__gmhOTWfVzEPVo2t" : {
"5740700998485" : {
"amount" : "330",
"objectProducer" : "Coca Cola",
"objectType" : "Zero",
"unit" : "Milliliter"
},
"createdOn" : "24-7-2019 at: 22:5:35",
"listID" : "-Lk__gmhOTWfVzEPVo2t",
"name" : "Test"
},
What is going wrong here?
in my opinion, change this line of code
let dict = child.value as? [String : AnyObject] ?? [:]
to:
guard let dict = child.value as? [String: AnyObject] else { return }
then you sould not getting error.
hop this help.
I think the crash due to self.objectAmount.append(dict["amount"] as! String).
You try execute the code: self.objectAmount.append(dict["amount"] as! Int)

swift keychain add, delete, get working, update not working

I'm troubleshooting a problem with Keychain updates. I have SecItemAdd, SecItemCopyMatching, and SecItemDelete working. But I'm stumped on SecItemUpdate. I always get a -50 fail.
I've put a public MacOS keychainTest project on Github at:
https://github.com/darrellroot/keychainTest/blob/master/README.md
FYI this almost identical question/answer should help me, but it's not:
Swift 4 Keychain SecItemUpdate Error status code -50
Here's relevant code snippets:
let keychainTest = "Keychain Test"
let serverHostname = "mail.nowhere.com"
let keychainService = "KeychainService"
AddQuery works:
let addQuery: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: keychainService,
kSecAttrAccount as String: serverHostname,
kSecValueData as String: inputTextOutlet.stringValue]
let status = SecItemAdd(addQuery as CFDictionary, nil)
GetQuery works:
let getQuery: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: keychainService,
kSecAttrAccount as String: serverHostname,
kSecMatchLimit as String: kSecMatchLimitOne,
kSecReturnData as String: true]
var rawResult: AnyObject?
let status = SecItemCopyMatching(getQuery as CFDictionary, &rawResult)
statusLabel.stringValue = status.description
guard let retrievedData = rawResult as? Data else { return }
guard let pass = String(data: retrievedData, encoding: String.Encoding.utf8) else { return }
DeleteQuery works:
let deleteQuery: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: keychainService,
kSecAttrAccount as String: serverHostname]
let status = SecItemDelete(deleteQuery as CFDictionary)
statusLabel.stringValue = status.description
But for this updateQuery I always get a -50 OSStatus message:
let updateQuery: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: keychainService,
kSecAttrAccount as String: serverHostname]
let newAttributes: [String: Any] = [kSecValueData as String: inputTextOutlet.stringValue]
let status = SecItemUpdate(updateQuery as CFDictionary, newAttributes as CFDictionary)
per osstatus.com, -50 is "One or more parameters passed to the function were not valid."

Could not cast value of type __NSCFString

I am trying out FCM messaging service. I have setup everything perfecting. When I receive message from FCM I get the following error. I am not sure what is wrong here:
AnyHashable("google.c.a.c_id"): 1586592282379086000, AnyHashable("gcm.message_id"): 0:1515418580276498%f4373656f4373656]
Could not cast value of type '__NSCFString' (0x1b4c70040) to 'NSDictionary' (0x1b4c70b80).
2018-01-08 19:06:21.198548+0530 Ozone[1067:540436] Could not cast value of type '__NSCFString' (0x1b4c70040) to 'NSDictionary' (0x1b4c70b80).
The strange part is I created a seperate Push Notification App and put the same code, it is working there. What could be wrong here?
Here is the piece code: I am getting the error in let d : [String : Any].....line
UNNotificationPresentationOptions) -> Void) {
print("Handle push from foreground\(notification.request.content.userInfo)")
let dict = notification.request.content.userInfo["aps"] as! NSDictionary
let d : [String : Any] = dict["alert"] as! [String : Any]
let body : String = d["body"] as! String
let title : String = d["title"] as! String
print("Title:\(title) + body:\(body)")
self.showAlertAppDelegate(title: title,message:body,buttonTitle:"ok",window:self.window!)
}
Can some one help me with this? I know it is very general error but not sure why this is coming as it is working fine in another app.
Thanks!
alert key can be string or dictionary (depends on your server). You can try this.
if let dict = notification.request.content.userInfo["aps"] as? [String : Any] {
if let d = dict["alert"] as? [String : Any],
let body = d["body"] as? String,
let title = d["title"] as? String {
print("Title:\(title) + body:\(body)")
} else if let body = dict["alert"] as? String {
print("body:\(body)")
}
}
And also you should avoid force casting and don't use NSDictionary in swift.

Swift 3: How to convert from [String: AnyObject] to [String: String]?

I want to convert a [String: Anyobject] dictionary to [String: String] dictionary?
How can I do this?
You cannot convert a dictionary directly from [String: AnyObject] to [String: String]: since AnyObject can hold different types of values in the same dict, each such value entry isn't necessarily convertable to String.
Instead, you need to go over each key-value pair and conditionally perform a value conversion to String, if possible. E.g.:
// (example) source dict
let dict: [String: AnyObject] = ["foo": "1" as AnyObject,
"bar": 2 as AnyObject,
"baz": "3" as AnyObject]
// target dict
var targetDict = [String: String]()
for (key, value) in dict {
if let value = value as? String { targetDict[key] = value }
} // targetDict: ["foo": "1", "baz": "3"]
Simply, you can do it this way:
if let castedDict = dictionary as? [String: String] {
print("Converted successfully: \(castedDict)")
} else {
print("Failed to cast the dictionary")
}

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

Xcode7 and swift, My code:
func loadDefaults() {
let settingBundle = NSBundle.mainBundle().pathForResource("Settings", ofType: "bundle")
if settingBundle == nil {
return
}
let root = NSDictionary(contentsOfFile: settingBundle!.stringByAppendingString("Root.plist"))
let prefrences = root?.objectForKey("PreferenceSpecifiers") as! Array<NSDictionary>
let defautlsToRegister = NSMutableDictionary(capacity: root!.count)
for prefrence in prefrences {
let key = prefrence.objectForKey("Key") as! String!
if key != nil {
defautlsToRegister.setValue(prefrence.objectForKey("DefaultVale"), forKey: key!)
}
}
NSUserDefaults.standardUserDefaults().registerDefaults(defautlsToRegister as [NSObject: AnyObject])
}
Problem code:
NSUserDefaults.standardUserDefaults().registerDefaults(defautlsToRegister as [NSObject: AnyObject])
building warnings
Cannot convert value of type '[NSObject : AnyObject]' to expected argument type '[String : AnyObject]'
change code:
NSUserDefaults.standardUserDefaults().registerDefaults(defautlsToRegister as [String: AnyObject])
building warnings
'NSMutableDictionary' is not convertible to '[String : AnyObject]'
Please teach me how to do? thanks.
Your defautlsToRegister should be in the following format [String: AnyObject]
Example: The following should work without warning
let defautlsToRegister = ["Test":10]
NSUserDefaults.standardUserDefaults().registerDefaults(defautlsToRegister as [String: AnyObject])
I've noticed a simple thing about this error. I'm not sure if this the case but casting String to NSString seems to solve the problem for me. I found an explanation that AnyObject is a type alias to represent instances of any reference type, which is for example: NSString. But String is a struct so it can't be the reference type for AnyObject.
I see two ways for this:
First:
let keyForMyKey: NSString = NSString(string: "mykey")
let result = dict.objectForKey(keyForMyKey) as? NSMutableArray
Second:
let result = dict.objectForKey(NSString(string: "myKey")) as? NSMUtableArray
More on the problem here: http://drewag.me/posts/swift-s-weird-handling-of-basic-value-types-and-anyobject
For me this is worked.
let token = fields["X-AUTH-TOKEN"]! as? [[String : AnyObject]] //{
// safe to use employees
self.bindings.setObject(NSString(format: "%#", token!) as String, forKey: "X-AUTH-TOKEN")
Format(NSString method) will work in this scenario.