如何将 JSON 字符串反序列化为 NSDictionary? (针对 iOS5 +)

在我的 iOS5应用程序中,我有一个包含 JSON 字符串的 NSString。我想将该 JSON 字符串表示反序列化为一个本地 NSDictionary对象。

 "{\"password\" : \"1234\",  \"user\" : \"andreas\"}"

我尝试了以下方法:

NSDictionary *json = [NSJSONSerialization JSONObjectWithData:@"{\"2\":\"3\"}"
options:NSJSONReadingMutableContainers
error:&e];

但是它抛出了一个运行时错误。我做错了什么?

-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x1372c
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x1372c'
155223 次浏览

这看起来像是在传递一个 NSString参数,其中应该传递一个 NSData参数:

NSError *jsonError;
NSData *objectData = [@"{\"2\":\"3\"}" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
NSData *data = [strChangetoJSON dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];

例如,在 NSString strChangetoJSON 中有一个带有特殊字符的 NSString。 然后可以使用上面的代码将该字符串转换为 JSON 响应。

我从@Abizern 答案中列出了一个类别

@implementation NSString (Extensions)
- (NSDictionary *) json_StringToDictionary {
NSError *error;
NSData *objectData = [self dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData options:NSJSONReadingMutableContainers error:&error];
return (!json ? nil : json);
}
@end

像这样使用它,

NSString *jsonString = @"{\"2\":\"3\"}";
NSLog(@"%@",[jsonString json_StringToDictionary]);

在 Swift 2.2中使用 阿比让代码

let objectData = responseString!.dataUsingEncoding(NSUTF8StringEncoding)
let json = try NSJSONSerialization.JSONObjectWithData(objectData!, options: NSJSONReadingOptions.MutableContainers)

对于 Swift 3和 Swift 4,String有一个名为 data(using:allowLossyConversion:)的方法。 data(using:allowLossyConversion:)有以下声明:

func data(using encoding: String.Encoding, allowLossyConversion: Bool = default) -> Data?

返回一个 Data,其中包含使用给定编码编码的 String 的表示形式。

在 Swift 4中,Stringdata(using:allowLossyConversion:)可以与 JSONDecoderdecode(_:from:)一起使用,以便将 JSON 字符串反序列化为字典。

此外,对于 Swift 3和 Swift 4,Stringdata(using:allowLossyConversion:)也可以与 JSONSerializationjson​Object(with:​options:​)一起使用,以便将 JSON 字符串反序列化为字典。


第一,迅捷4解决方案

对于 Swift 4,JSONDecoder有一个名为 decode(_:from:)的方法。 decode(_:from:)有以下声明:

func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable

从给定的 JSON 表示解码给定类型的顶级值。

下面的 Playground 代码展示了如何使用 data(using:allowLossyConversion:)decode(_:from:)从 JSON 格式的 String中获得 Dictionary:

let jsonString = """
{"password" : "1234",  "user" : "andreas"}
"""


if let data = jsonString.data(using: String.Encoding.utf8) {
do {
let decoder = JSONDecoder()
let jsonDictionary = try decoder.decode(Dictionary<String, String>.self, from: data)
print(jsonDictionary) // prints: ["user": "andreas", "password": "1234"]
} catch {
// Handle error
print(error)
}
}

2. Swift 3和 Swift 4的解决方案

对于 Swift 3和 Swift 4,JSONSerialization有一个名为 json​Object(with:​options:​)的方法。 json​Object(with:​options:​)有以下声明:

class func jsonObject(with data: Data, options opt: JSONSerialization.ReadingOptions = []) throws -> Any

从给定的 JSON 数据返回 Foundation 对象。

下面的 Playground 代码展示了如何使用 data(using:allowLossyConversion:)json​Object(with:​options:​)从 JSON 格式的 String中获得 Dictionary:

import Foundation


let jsonString = "{\"password\" : \"1234\",  \"user\" : \"andreas\"}"


if let data = jsonString.data(using: String.Encoding.utf8) {
do {
let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: []) as? [String : String]
print(String(describing: jsonDictionary)) // prints: Optional(["user": "andreas", "password": "1234"])
} catch {
// Handle error
print(error)
}
}