Bir JSON dizesinin bir NSDictionary içine serisini nasıl kaldırabilirim? (İOS 5+ için)


154

İOS 5 uygulamamda NSStringJSON dizesi içeren bir tane var. Bu JSON dize temsilini yerel bir NSDictionarynesneye serileştirmek istiyorum .

 "{\"password\" : \"1234\",  \"user\" : \"andreas\"}"

Aşağıdaki yaklaşımı denedim:

NSDictionary *json = [NSJSONSerialization JSONObjectWithData:@"{\"2\":\"3\"}"
                                options:NSJSONReadingMutableContainers
                                  error:&e];  

Ancak bir çalışma zamanı hatası atar. Neyi yanlış yapıyorum?

-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x1372c 
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x1372c'

Benim yaklaşımım buydu: NSDictionary * JSON = [NSJSONSerialization JSONObjectWithData: @ "{\" 2 \ ": \" 3 \ "}" seçenekler: NSJSONReadingMutableContainers hatası: & e]; i: 2011-12-22 17: 18: 59.300 Pi9000 [938: 13803] - [__ NSCFConstantString bayt]: tanınmayan seçici 0x1372c 2011-12-22 17: 18: 59.302 Pi9000 [938: 13803] *** gönderildi *** Yakalanmayan istisna 'NSInvalidArgumentException' nedeniyle uygulamayı sonlandırma, nedeni: '- [__ NSCFConstantString bytes]: tanınmayan seçici 0x1372c örneğine gönderildi'
Andreas

Swift 3 ve Swift 4 için bir JSON dizesini
diziselleştirmenin

Yanıtlar:


335

Bir NSStringparametreyi geçirmeniz gereken bir parametre geçiriyorsunuz gibi görünüyor NSData:

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

@Abizem, burada hangi hatayı kullanabilirim? (op bundan bahsetmiyor)

Teşekkürler ... bu yardımcı oldu! ve +1
Jayprakash Dubey

Teşekkürler, işe yaradı. Ancak, XCode 5 nilyerine hata olarak kullanma&e
Michael Ho Chum

3
Amaç C'yi seviyorum. Dizenizi ham baytlara kodlayın ve sonra bunları NSStrings ve NSNumbers'a geri çözün. Bu açık, değil mi?
vahotm

1
@Abizern, JSON'u uygulamanızın dışındaki bir yerden dize olarak almak için yaygın
Chicowitz

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

Örneğin strChangetoJSON'da NSStringözel karakterlere sahip bir NSStringa'nız var. Daha sonra bu kodu yukarıdaki kodu kullanarak JSON yanıtına dönüştürebilirsiniz.


6

@Abizern yanıtından bir kategori yaptım

@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

Bu şekilde kullanın,

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

Bu errordurumlarda test etmemenin , ancak dönüşten önce dönüş değerinin sıfır olup olmadığını test etmenin en iyi uygulama olduğunu anlıyorum . yani return json ?: nil; küçük nitpick, ama bahsetmeye değer, sanırım.
Mike

@Mike, değeri ne olursa olsun "hata" kontrol etmek için Tamam olduğunu düşünüyorum? Çünkü bir hata olursa hemen geri dönüyoruz nil.
Hemang

Apple'ın dokümanlarına göre "Referansla geçen hatalarla uğraşırken, yukarıda gösterildiği gibi bir hatanın oluşup oluşmadığını görmek için yöntemin dönüş değerini test etmek önemlidir. Yalnızca hata işaretçisinin işaret edecek şekilde ayarlanıp ayarlanmadığını test etmeyin bir hata." developer.apple.com/library/ios/documentation/Cocoa/Conceptual/… Bunun bir hatanın meydana gelmediği ve yöntemin bir değer döndürdüğü durumlar olabileceği, ancak hata işaretçisinin işaret ettiği bellek olabileceğine inanıyorum. yazılır, böylece yanlış bir hata olduğunu düşünürsünüz.
Mike

Daha önceki bir soruda okudum: "Değişken başlatılmadı. Bu, bu adresteki değerin tanımsız olduğu anlamına gelir, bu nedenle değeri değiştirmek hiçbir şey ifade etmeyecektir ... Metodun yazmayacağının garantisi olmadığından hata oluşmazsa, Apple'ın dokümanları hata değişkeninin değerini test etmenin güvenli olmadığını söylüyor. " stackoverflow.com/questions/25558442/…
Mike

1
@Mike, oh harika, bilmek güzel! Referanslar için teşekkürler. Bunu yakında güncelleyeceğim.
Hemang

5

Swift 3 ve Swift 4 ile Stringdenilen bir yöntem var data(using:allowLossyConversion:). data(using:allowLossyConversion:)aşağıdaki beyanı içerir:

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

Belirli bir kodlama kullanılarak kodlanan Dizenin bir temsilini içeren bir Veri döndürür.

Swift 4 ile, String'ler bir JSON dizesini sözlükte serileştirmek için ' s data(using:allowLossyConversion:)ile birlikte kullanılabilir .JSONDecoderdecode(_:from:)

Ayrıca, Swift 3 ve Swift 4, String'in data(using:allowLossyConversion:)birlikte de kullanılabilir JSONSerializationS' json​Object(with:​options:​)bir sözlüğe JSON dize serisini amacıyla.


# 1. Swift 4 çözümü

Swift 4 ile JSONDecoderdenilen bir yöntem var decode(_:from:). decode(_:from:)aşağıdaki beyanı içerir:

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

Belirli bir JSON gösteriminden, belirtilen türde bir üst düzey değerin kodunu çözer.

Nasıl kullanımına gösterileri altında Bahçesi kodu data(using:allowLossyConversion:)ve decode(_:from:)sırayla bir olsun Dictionarybir JSON'dan biçimlendirilmiş 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 ve Swift 4 çözümü

Swift 3 ve Swift 4 ile JSONSerializationdenilen bir yöntem var json​Object(with:​options:​). json​Object(with:​options:​)aşağıdaki beyanı içerir:

class func jsonObject(with data: Data, options opt: JSONSerialization.ReadingOptions = []) throws -> Any

Verilen JSON verilerinden bir Foundation nesnesi döndürür.

Nasıl kullanımına gösterileri altında Bahçesi kodu data(using:allowLossyConversion:)ve json​Object(with:​options:​)sırayla bir olsun Dictionarybir JSON'dan biçimlendirilmiş 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

Hızlı 2.2 için Abizern kodunu kullanma

let objectData = responseString!.dataUsingEncoding(NSUTF8StringEncoding)
let json = try NSJSONSerialization.JSONObjectWithData(objectData!, options: NSJSONReadingOptions.MutableContainers)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.