How do I deserialize a JSON string into an NSDictionary? (For iOS 5+)

IosJsonIos5NsstringNsdictionary

Ios Problem Overview


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'

Ios Solutions


Solution 1 - Ios

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];

Solution 2 - Ios

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.

Solution 3 - Ios

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]);

Solution 4 - Ios

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 json​Object(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 json​Object(with:​options:​). json​Object(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 json​Object(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)
	}
}

Solution 5 - Ios

Using Abizern code for swift 2.2

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndreasView Question on Stackoverflow
Solution 1 - IosAbizernView Answer on Stackoverflow
Solution 2 - IosDesert RoseView Answer on Stackoverflow
Solution 3 - IosHemangView Answer on Stackoverflow
Solution 4 - IosImanou PetitView Answer on Stackoverflow
Solution 5 - IosIOS SinghView Answer on Stackoverflow