NSMutableDictionary中的可选值

时间:2016-03-02 01:28:49

标签: ios swift

我是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

    }

4 个答案:

答案 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.