Как десериализовать строку JSON в NSDictionary?(Для iOS 5+) - PullRequest
150 голосов
/ 22 декабря 2011

В моем приложении для iOS 5 NSString содержит строку JSON.Я хотел бы десериализовать это строковое представление 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'

Ответы [ 5 ]

322 голосов
/ 22 декабря 2011

Похоже, вы передаете параметр NSString, где вы должны передать параметр NSData:

NSError *jsonError;
NSData *objectData = [@"{\"2\":\"3\"}" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
                                      options:NSJSONReadingMutableContainers 
                                        error:&jsonError];
36 голосов
/ 16 ноября 2012
NSData *data = [strChangetoJSON dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
                                                             options:kNilOptions
                                                               error:&error];

Например, у вас есть NSString со специальными символами в NSString strChangetoJSON.Затем вы можете преобразовать эту строку в ответ JSON, используя приведенный выше код.

5 голосов
/ 20 марта 2015

Я сделал категорию из ответа @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]);
4 голосов
/ 03 июня 2017

В Swift 3 и Swift 4 String имеет метод, называемый data(using:allowLossyConversion:). data(using:allowLossyConversion:) имеет следующую декларацию:

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

Возвращает данные, содержащие представление строки, закодированной с использованием заданной кодировки.

В Swift 4 String data(using:allowLossyConversion:) может использоваться вместе с JSONDecoder decode(_:from:) для десериализации строки JSON в словарь.

Кроме того, в Swift 3 и Swift 4 String data(using:allowLossyConversion:) также можно использовать вместе с JSONSerialization json​Object(with:​options:​) для десериализации строки JSON в словарь.


# 1. Решение Swift 4

В Swift 4 JSONDecoder имеет метод с именем decode(_:from:). decode(_:from:) имеет следующую декларацию:

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

Декодирует значение верхнего уровня данного типа из заданного представления JSON.

Приведенный ниже код игровой площадки показывает, как использовать data(using:allowLossyConversion:) и decode(_:from:) для получения Dictionary из формата JSON 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 и 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

Возвращает объект Foundation из данных JSON.

Код Playground ниже показывает, как использовать data(using:allowLossyConversion:) и json​Object(with:​options:​), чтобы получить Dictionary из формата JSON 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)
    }
}
2 голосов
/ 17 февраля 2017

Использование Abizern код для быстрого 2,2

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