在Swift中将NSDictionary转换为NSData和将NSData转换为NSDictionary

59

我不确定我是在错误地使用字典还是数据对象,或者两者都有误。我正在尝试适应切换到Swift,但我遇到了一些小麻烦。

var dictionaryExample : [String:AnyObject] =
    ["user":"UserName",
     "pass":"password",
    "token":"0123456789",
    "image":0] // image should be either NSData or empty

let dataExample : NSData = dictionaryExample as NSData

我需要将NSDictionary编码为一个NSData对象,同时还需将该NSData对象解码为NSDictionary

非常感谢任何帮助。


你实际上想要实现什么?如果你不指定NSData的格式,那么说“将NSDictionary转换为NSData”是没有意义的。 - gnasher729
6个回答

114

您可以使用NSKeyedArchiverNSKeyedUnarchiver

Swift 2.0+示例:

var dictionaryExample : [String:AnyObject] = ["user":"UserName", "pass":"password", "token":"0123456789", "image":0]
let dataExample : NSData = NSKeyedArchiver.archivedDataWithRootObject(dictionaryExample)
let dictionary:NSDictionary? = NSKeyedUnarchiver.unarchiveObjectWithData(dataExample)! as? NSDictionary

Swift3.0

let dataExample: Data = NSKeyedArchiver.archivedData(withRootObject: dictionaryExample)
let dictionary: Dictionary? = NSKeyedUnarchiver.unarchiveObject(with: dataExample) as! [String : Any]

Playground 的屏幕截图

输入图片说明


你回答了我在标题中指定的问题。我认为 AnyObject 是错误的。我想让用户/密码/令牌成为字符串,而图像则是 NSData 对象。我能做到吗?还是应该将它们全部编码为 NSData 对象,然后再解码它们? - IanTimmis
这是来自Xcode文档的内容:class func unarchiveObjectWithData(data: NSData) -> AnyObject? - Leo
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - IanTimmis
这个不行。它产生了错误 'AnyObject' 无法转换为 'NSDictionary'; - c.dunlap
@c.dunlap 我更新了代码。我回答时是针对Swift 1.2的,所以对于Swift 2.0来说,可能会有一些语法问题。 - Leo
这个不起作用是因为函数unarchiveObject(with:)需要一个Data类型的变量,而函数unarchiveTopLevelObjectWithData()需要一个NSData类型的变量。请参考我的答案。 - Ujjwal-Nadhani

11

Swift 5

正如 @yuyeqingshan 所说,PropertyListSerialization 是一个不错的选择。

       // Swift Dictionary To Data.
        do {
            let data = try PropertyListSerialization.data(fromPropertyList: [:], format: PropertyListSerialization.PropertyListFormat.binary, options: 0)
            // do sth
        } catch{
            print(error)
        }


        // Data to Swift Dictionary
        do {
            let dicFromData = try PropertyListSerialization.propertyList(from: data, options: PropertyListSerialization.ReadOptions.mutableContainers, format: nil)
            if let dict = dicFromData as? [String: Any]{
                // do sth
            }
        } catch{
            print(error)
        }

9

NSPropertyListSerialization可能是另一个解决方案。

// Swift Dictionary To Data.
var data = try NSPropertyListSerialization.dataWithPropertyList(dictionaryExample, format: NSPropertyListFormat.BinaryFormat_v1_0, options: 0)

// Data to Swift Dictionary
var dicFromData = (try NSPropertyListSerialization.propertyListWithData(data, options: NSPropertyListReadOptions.Immutable, format: nil)) as! Dictionary<String, AnyObject>

3

针对Swift3:

let data = try PropertyListSerialization.data(fromPropertyList: authResponse, format: PropertyListSerialization.PropertyListFormat.binary, options: 0)

3

Leo的回答给我带来了构建时间错误,因为NSDataData不同。函数unarchiveObject(with:)需要一个类型为Data的变量,而函数unarchiveTopLevelObjectWithData()需要一个类型为NSData的变量。

以下是可用的Swift 3答案:

var names : NSDictionary = ["name":["John Smith"], "age": 35]
let namesData : NSData = NSKeyedArchiver.archivedData(withRootObject: names) as NSData
do{
    let backToNames = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(namesData) as! NSDictionary
    print(backToNames)
}catch{
    print("Unable to successfully convert NSData to NSDictionary")
}

-3

对于Swift 4 -

let dictionaryExample : [String:AnyObject] = ["user":"UserName" as AnyObject, "pass":"password" as AnyObject, "token":"0123456789" as AnyObject, "image":0 as AnyObject]
    let dataExample : NSData = NSKeyedArchiver.archivedData(withRootObject: dictionaryExample) as NSData
    let dictionary:NSDictionary? = NSKeyedUnarchiver.unarchiveObject(with: dataExample as Data)! as? NSDictionary

4
糟糕的例子。虽然你说了“Swift 4”,但实际上你却将NSData强制转换为Data,而没有直接使用Data;你还在使用AnyObject而不是Any,并且你对可选项(optional)的使用远未达到最佳状态... - Eric Aya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接