在我的iOS 5应用程序中,我有一个包含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'
看起来您正在传递一个 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
NSString
strChangetoJSON 中包含特殊字符。然后,您可以使用上面的代码将该字符串转换为 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]);
3 和 Swift 4,String
有一个名为 data(using:allowLossyConversion:)
的方法。 data(using:allowLossyConversion:)
具有以下声明:
func data(using encoding: String.Encoding, allowLossyConversion: Bool = default) -> Data?
返回一个 Data,其中包含使用给定编码编码的字符串的表示形式。
在 Swift 4 中,String
的data(using:allowLossyConversion:)
可以与 JSONDecoder
的decode(_:from:)
结合使用,以便将 JSON 字符串反序列化为字典。
此外,在 Swift 3 和 Swift 4 中,String
的data(using:allowLossyConversion:)
也可以与 JSONSerialization
的jsonObject(with:options:)
结合使用,以便将 JSON 字符串反序列化为字典。
#1.迅捷 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
有一个名为 jsonObject(with:options:)
的方法。 jsonObject(with:options:)
具有以下声明:
class func jsonObject(with data: Data, options opt: JSONSerialization.ReadingOptions = []) throws -> Any
从给定的 JSON 数据返回基础对象。
下面的 Playground 代码显示了如何使用 data(using:allowLossyConversion:)
和 jsonObject(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)
}
}
在 swift 2.2 中使用 Abizern 代码
let objectData = responseString!.dataUsingEncoding(NSUTF8StringEncoding)
let json = try NSJSONSerialization.JSONObjectWithData(objectData!, options: NSJSONReadingOptions.MutableContainers)