JSON 문자열을 NSDictionary로 역 직렬화하는 방법은 무엇입니까? (iOS 5 이상인 경우)


154

내 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'

내 접근 방식은 다음과 같습니다. NSDictionary * JSON = [NSJSONSerialization JSONObjectWithData : @ "{\"2 \ ": \"3 \ "}"옵션 : NSJSONReadingMutableContainers 오류 : & e]; 가져 오기 : 2011-12-22 17 : 18 : 59.300 Pi9000 [938 : 13803]-[__ NSCFConstantString 바이트] : 인식 할 수없는 선택기가 인스턴스 0x1372c로 전송 2011-12-22 17 : 18 : 59.302 Pi9000 [938 : 13803] *** 잡히지 않은 예외 'NSInvalidArgumentException'으로 인해 앱을 종료하는 이유 : '-[__ NSCFConstantString bytes] : 인식 할 수없는 선택기가 인스턴스 0x1372c로 전송 됨
Andreas

JSON 문자열을 Swift 3 및 Swift 4 용 사전으로 직렬화 해제하는 두 가지 방법을 보여주는 내 답변 을 참조하십시오 .
Imanou Petit

답변:


335

NSString매개 변수를 전달 해야하는 곳 에서 매개 변수를 전달하는 것처럼 보입니다 NSData.

NSError *jsonError;
NSData *objectData = [@"{\"2\":\"3\"}" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
                                      options:NSJSONReadingMutableContainers 
                                        error:&jsonError];

@Abizem, 여기에 어떤 오류를 사용할 수 있습니까? (op는 언급하지 않습니다)

고마워 ...이 도움이되었습니다! +1
Jayprakash Dubey

고마워요 그러나 XCode 5 nil대신 오류로 사용&e
Michael Ho Chum

3
Objective C가 마음에 듭니다. 문자열을 원시 바이트로 인코딩 한 다음 NSString 및 NSNumber로 다시 디코딩하십시오. 이것은 분명하지 않습니까?
vahotm

1
응용 프로그램의 어딘가의 외부에서 문자열로 JSON을 수신하기 위해 공통 @Abizern
Chicowitz

37
NSData *data = [strChangetoJSON dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
                                                             options:kNilOptions
                                                               error:&error];

예를 들어 strChangetoJSON NSString에는 특수 문자가 NSString있습니다. 그런 다음 위 코드를 사용하여 해당 문자열을 JSON 응답으로 변환 할 수 있습니다.


6

@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

이렇게 사용하세요

NSString *jsonString = @"{\"2\":\"3\"}";
NSLog(@"%@",[jsonString json_StringToDictionary]);

error이러한 경우에는 테스트하지 않고 반환하기 전에 반환 값이 0인지 아닌지를 테스트 하는 것이 가장 좋습니다 . 즉, return json ?: nil; 작은 nitpick이지만 언급 할 가치가 있다고 생각합니다.
Mike

@ 마이크, 값에 관계없이 "오류"를 확인하는 것이 좋다고 생각합니까? 오류가 있으면 nil바로 돌아 옵니다.
Hemang

Apple의 문서에 따르면 "참조로 전달 된 오류를 처리 할 때는 메소드의 반환 값을 테스트하여 위에 표시된대로 오류가 발생했는지 여부를 테스트하는 것이 중요합니다. 오류 포인터가 다음을 가리 키도록 설정되어 있는지 확인하지 마십시오. 오류입니다. " developer.apple.com/library/ios/documentation/Cocoa/Conceptual/… 오류가 발생하지 않고 메소드가 값을 반환하는 경우가있을 수 있지만 오류 포인터가 가리키는 메모리는 오류가 있다고 잘못 생각합니다.
Mike

"내 변수는 초기화되지 않았습니다. 즉, 해당 주소의 값이 정의되지 않았으므로 값을 변경해도 아무런 의미가 없습니다 ... 메서드가 작성되지 않을 것이라는 보장은 없습니다. 오류가 발생하지 않으면 주소에 쓰레기가 들어간다고 Apple 문서는 오류 변수의 값을 테스트하는 것이 안전하지 않다고 말합니다. " stackoverflow.com/questions/25558442/…
Mike

1
@ 마이크, 아, 좋아요! 참조 주셔서 감사합니다. 곧 업데이트하겠습니다.
Hemang

5

Swift 3 및 Swift 4 String에는이라는 메소드가 data(using:allowLossyConversion:)있습니다. data(using:allowLossyConversion:)다음과 같은 선언이 있습니다.

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

주어진 인코딩을 사용하여 인코딩 된 문자열 표현이 포함 된 데이터를 반환합니다.

스위프트 4, String'들 data(using:allowLossyConversion:)과 함께 이용 될 수 JSONDecoderdecode(_:from:)사전에 JSON 문자열을 직렬화하기 위해.

또한, 신속한 3 스위프트 4, String'들 data(using:allowLossyConversion:)도 함께 함께 이용 될 수 JSONSerializationjson​Object(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 표현에서 주어진 유형의 최상위 값을 디코딩합니다.

사용하는 방법을 보여줍니다 아래의 놀이터 코드 data(using:allowLossyConversion:)decode(_:from:)순서는 얻을 수 DictionaryJSON에서 포맷 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. 스위프트 3 및 스위프트 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

주어진 JSON 데이터에서 Foundation 객체를 반환합니다.

사용하는 방법을 보여줍니다 아래의 놀이터 코드 data(using:allowLossyConversion:)json​Object(with:​options:​)순서는 얻을 수 DictionaryJSON에서 포맷 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)
    }
}

3

신속한 2.2에 Abizern 코드 사용

let objectData = responseString!.dataUsingEncoding(NSUTF8StringEncoding)
let json = try NSJSONSerialization.JSONObjectWithData(objectData!, options: NSJSONReadingOptions.MutableContainers)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.