我是Swift的新手,在Objective-C方面非常有经验。
在我的应用程序中,我从服务器接收数据并将其映射到NSMutableDictionary。我使用NSMutableDictionary的原因是来自服务器的值不一致,它是字符串和数字的混合。而这似乎打破了一个只期望一种价值的Swift词典。
有时服务器没有发送NSMutableDictionary期望的值,它会使应用程序崩溃。
在我的研究中,似乎在将其设置为NSMutableDictionary之前,我必须检查每个对象以查看Swift中是否存在该值。
这是我目前的代码:
let userDictionary:NSMutableDictionary = [
"name": data.objectForKey("name") as! String,
... // many more values
如果服务器的响应中没有“name”值,则会崩溃。
似乎解决方案是:
if let nameValue = data.objectForKey("name") as! String {
//not sure what to do in here since the var is assigned as I need
}
// ... check many more values
let userDictionary:NSMutableDictionary = [
"name": nameValue,
// ... assign many more values that I checked above
这似乎是很多额外的代码来检查服务器中的每个值。有更简单的解决方案吗?
感谢您的时间。
@Matt下面。下面是详细的代码(为简洁起见,在userDictionary中取出了一些值)。我从Facebook获取数据,添加其他信息并将其保存到Firebase:
//check all of the values
var birthdayValue:String? = "";
if let value:String? = data.objectForKey("birthday") as? String {
birthdayValue = value;
}
let userDictionary:NSMutableDictionary = [
"name": data.objectForKey("name") as! String,
"birthday": birthdayValue!,
"email": data.objectForKey("email") as! String,
"firstName": data.objectForKey("first_name") as! String,
"lastName": data.objectForKey("last_name") as! String,
"description": "",
"distance": 50,
"facebookID": data.objectForKey("id") as! String,
"location":[ 37.12314, -122.49182 ], //TODO: Get location
"points" : 0,
"rating" : 1,
"school" : "",
]
//we need to convert the FB profile pic to a base 64 string and add it here
let imagePath:String = "https://graph.facebook.com/\(data.objectForKey("id") as! String)/picture?width=375&height=667"
self.getDataFromUrl(NSURL(string: imagePath)!) { (imageData, response, error) -> Void in
//convert the data to base 64
let imgString:String = self.convertDataToBase64(imageData);
let images:Array<String> = [imgString];
userDictionary.setValue(images, forKey: "profilePics")
//save the user to Firebase
userRef.childByAppendingPath(data.objectForKey("id") as! String).setValue(userDictionary)
self.currentUserID = (data.objectForKey("id")) as! String
}
答案 0 :(得分:0)
在我的应用中,我从服务器接收数据并将其映射到NSMutableDictionary
根本不需要这样做。数据将作为字典出现在中(至少我认为它是;如果不是,那么你很难调用objectForKey
,在我看来)。所以现在继续使用它。没有什么可以“映射”。
例如,假设data
是在原始NSData JSONObjectWithData:options:
上调用NSJSONSerialization的d
的结果。并且假设你期望这个序列化的是字典。所以在你说完之后
var data = try! NSJSONSerialization.JSONObjectWithData(
d, options:[]) as! [NSObject:AnyObject]
...你已经完成了:这是一个可变的字典,你可以参加比赛了。
答案 1 :(得分:0)
如果您的数据是字符串和数字的混合,您可以尝试将其作为AnyObject
存储在字典中,例如[String: AnyObject]
然后您可以尝试保存这样的数据:
var userDictionary: [String: AnyObject] = [:]
userDictionary["name"] = data.objectForKey("name")
当您需要访问它时:
if let name = userDictionary["name"] as? String {
// Do something with name
}
如果您不想将其保存为AnyObject
,我建议您改为创建结构。
答案 2 :(得分:-1)
as!
是一个强制转发,如果无法进行此转发,则会导致异常(如果值为nil
,则显然是这种情况)。另一方面,as?
只在可能的情况下向下倾斜,否则会导致nil
(这听起来像你想要的那样)。
let userDictionary:NSMutableDictionary = [
"name": data.objectForKey("name") as? String,
... // many more values
]
这应该有用。
编辑:没关系,这只有在您使用原生Swift词典时才有效。尽管如此,了解as?
和as!
之间的区别仍然很有用。
答案 3 :(得分:-1)
Swift实际上支持字典中的多个类型。以下是合法的。
let arr: [NSObject: AnyObject] = [1: "hello", "a": 19, 2: "Swift"]
您可以在字典中存储可选对象:
let arr: [NSObject: AnyObject?] = [1: "hello", "a": 19, 2: nil]
是的,如果您关心它,您可能需要检查值的存在。我会使用if
代替guard
,以确保您以后可以使用该变量。
guard let nameValue = data.objectForKey("name") as? String else {
return
}
// Now you can safely use nameValue.