Как десериализовать строку JSON в NSDictionary? (Для iOS 5+)
В моем приложении 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'
Ответы
Ответ 1
Похоже, вы передаете параметр NSString
, где вы должны передавать параметр NSData
:
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];
Например, у вас есть NSString
со специальными символами в NSString
strChangetoJSON.
Затем вы можете преобразовать эту строку в ответ JSON, используя вышеуказанный код.
Ответ 3
Я сделал категорию из ответа @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
С 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
jsonObject(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
имеет метод jsonObject(with:options:)
. jsonObject(with:options:)
имеет следующее объявление:
class func jsonObject(with data: Data, options opt: JSONSerialization.ReadingOptions = []) throws -> Any
Возвращает объект Foundation из данных JSON.
Ниже приведен пример кода игры, где показано, как использовать data(using:allowLossyConversion:)
и jsonObject(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)
}
}
Ответ 5
Использование Abizern для быстрого 2.2
let objectData = responseString!.dataUsingEncoding(NSUTF8StringEncoding)
let json = try NSJSONSerialization.JSONObjectWithData(objectData!, options: NSJSONReadingOptions.MutableContainers)