【问题标题】:Storing and Reading NSKeyedArchived NSData to/from database在数据库中存储和读取 NSKeyedArchived NSData
【发布时间】:2013-03-07 03:16:23
【问题描述】:
我有一个包含大量变量的对象,这些变量需要保存在本地以及数据库中。该对象将使用 NSKeyedArchiver(与来自https://github.com/nicklockwood/CryptoCoding 的 CryptoCoder 一起)进行序列化和本地存储。
现在我正在尝试将数据存储在数据库 (cloudant.com) 中。我可以使用 NSData 直接发送数据,将(例如,)存储在数据库中,但是读回来我不知道如何将其转换回 NSData。将 NSString 与编码一起使用会产生空结果。
因为序列化的数据写在一个遵循 plist 格式的文件中,我尝试使用 NSPropertyListSerialization 将其转换为 NSDictionary 并将其发送出去,但转换不准确。
需要建议。
【问题讨论】:
标签:
database
nsdictionary
nsdata
nskeyedarchiver
data-serialization
【解决方案1】:
NSData(例如,)是十六进制格式。我相信您正在调用 [NSData description] 方法来获得该结果。它不应该用于序列化,尽管序列化并非不可能。 (只需要编写一个自定义的十六进制数据转换器)
有很多方法可以通过网络传输数据。我假设您使用 HTTP 作为传输层。我列出了两种可以做到这一点的方法
JSON 方式(也适用于 plist,虽然它支持更多数据类型)
编写自定义序列化器和反序列化器,将要序列化的对象转换成NSJSONSerializer可以成功序列化成JSON的对象。
可以转换为 JSON 的对象必须具有以下属性:
- 顶级对象是 NSArray 或 NSDictionary。
- 所有对象都是 NSString、NSNumber、NSArray、NSDictionary 或 NSNull 的实例。
- 所有字典键都是 NSString 的实例。
- 数字不是 NaN 或无穷大。
参考:
通过 HTTP 的原始 NSData
通过 HTTP 上传原始 NSData(来自 NSCoding)通常使用 application/octet-stream 或 multipart/form-data 的 HTTP POST 完成。
如果您想使用 application/x-www-form-urlencoded 等其他方法进行 POST,则需要将其序列化为 web 友好编码,如 base64 或十六进制。我推荐使用 Base64。 iOS 不附带 Base64 编码器和解码器,但我编写了一个(基于 Mattt Thompson 的 AFNetworking 实现)。我知道其他人写过类似的方法,我查看过这些方法,发现 Mattt Thompson(以及随后我派生的 base64 解码器代码)干净、易读且逻辑尽可能少。
Base64 Encoding and Decoding implementation in Objective-C
确保当您从服务器取回数据时,如果它是(base64 或十六进制)编码的,请先解码。将解码后的数据序列化为 JSON、Property List 或 NSCoding,具体取决于您的实现。
基本上,反转您的序列化步骤。