问题
In my iOS 5 app, I have an NSString that contains a JSON string. I would like to deserialize that JSON string representation into a native NSDictionary object.
\"{\\\"password\\\" : \\\"1234\\\", \\\"user\\\" : \\\"andreas\\\"}\"
I tried the following approach:
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:@\"{\\\"2\\\":\\\"3\\\"}\"
options:NSJSONReadingMutableContainers
error:&e];
But it throws the a runtime error. What am I doing wrong?
-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x1372c
*** Terminating app due to uncaught exception \'NSInvalidArgumentException\',
reason: \'-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x1372c\'
回答1:
It looks like you are passing an NSString parameter where you should be passing an NSData parameter:
NSError *jsonError;
NSData *objectData = [@"{\"2\":\"3\"}" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
回答2:
NSData *data = [strChangetoJSON dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
For example you have a NSString with special characters in NSString strChangetoJSON.
Then you can convert that string to JSON response using above code.
回答3:
I've made a category from @Abizern answer
@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
Use it like this,
NSString *jsonString = @"{\"2\":\"3\"}";
NSLog(@"%@",[jsonString json_StringToDictionary]);
回答4:
With Swift 3 and Swift 4, String has a method called data(using:allowLossyConversion:). data(using:allowLossyConversion:) has the following declaration:
func data(using encoding: String.Encoding, allowLossyConversion: Bool = default) -> Data?
Returns a Data containing a representation of the String encoded using a given encoding.
With Swift 4, String's data(using:allowLossyConversion:) can be used in conjunction with JSONDecoder's decode(_:from:) in order to deserialize a JSON string into a dictionary.
Furthermore, with Swift 3 and Swift 4, String's data(using:allowLossyConversion:) can also be used in conjunction with JSONSerialization's jsonObject(with:options:) in order to deserialize a JSON string into a dictionary.
#1. Swift 4 solution
With Swift 4, JSONDecoder has a method called decode(_:from:). decode(_:from:) has the following declaration:
func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable
Decodes a top-level value of the given type from the given JSON representation.
The Playground code below shows how to use data(using:allowLossyConversion:) and decode(_:from:) in order to get a Dictionary from a JSON formatted String:
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 and Swift 4 solution
With Swift 3 and Swift 4, JSONSerialization has a method called jsonObject(with:options:). jsonObject(with:options:) has the following declaration:
class func jsonObject(with data: Data, options opt: JSONSerialization.ReadingOptions = []) throws -> Any
Returns a Foundation object from given JSON data.
The Playground code below shows how to use data(using:allowLossyConversion:) and jsonObject(with:options:) in order to get a Dictionary from a JSON formatted String:
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)
}
}
回答5:
Using Abizern code for swift 2.2
let objectData = responseString!.dataUsingEncoding(NSUTF8StringEncoding)
let json = try NSJSONSerialization.JSONObjectWithData(objectData!, options: NSJSONReadingOptions.MutableContainers)
来源:https://stackoverflow.com/questions/8606444/how-do-i-deserialize-a-json-string-into-an-nsdictionary-for-ios-5