Generieren Sie eine JSON-Zeichenfolge aus NSDictionary in iOS


338

Ich habe eine, die dictionaryich JSON stringmithilfe von generieren muss dictionary. Ist es möglich, es zu konvertieren? Könnt ihr bitte dabei helfen?


3
@ RicardoRivaldo das ist das
QED

18
Wenn jemand von der Google-Suche hierher kommt, lesen Sie bitte die Antwort unten von @Guillaume
Mahendra Liya

Antworten:


233

Hier sind Kategorien für NSArray und NSDictionary, um dies ganz einfach zu machen. Ich habe eine Option für hübsches Drucken hinzugefügt (Zeilenumbrüche und Registerkarten, um das Lesen zu erleichtern).

@interface NSDictionary (BVJSONString)
-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint;
@end

.

@implementation NSDictionary (BVJSONString)

  -(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint {
     NSError *error;
     NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
                                                   options:(NSJSONWritingOptions)    (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
                                                     error:&error];

     if (! jsonData) {
        NSLog(@"%s: error: %@", __func__, error.localizedDescription);
        return @"{}";
     } else {
        return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
     } 
 }
@end

.

@interface NSArray (BVJSONString)
- (NSString *)bv_jsonStringWithPrettyPrint:(BOOL)prettyPrint;
@end

.

@implementation NSArray (BVJSONString)
-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint {
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
                                                       options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
                                                         error:&error];

    if (! jsonData) {
        NSLog(@"%s: error: %@", __func__, error.localizedDescription);
        return @"[]";
    } else {
        return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
}
@end

8
Wenn wir eine Kategorie von NSObject erstellen und dieselbe Methode verwenden, funktioniert dies sowohl für NSArray als auch für NSDictionary. Es müssen keine zwei separaten Dateien / Schnittstellen geschrieben werden. Und es sollte im Fehlerfall null zurückgeben.
Abdullah Umer

Warum nehmen Sie an, dass dies NSUTF8StringEncodingdie richtige Codierung ist?
Heath Borders

5
In der Dokumentation heißt es jedoch: "Die resultierenden Daten sind in UTF-8 codiert."
Heath Borders

@AbdullahUmer Das habe ich auch getan, da ich davon ausgehe, dass es auch funktionieren NSNumberwird NSString, und NSNull- werde es in ein oder zwei Minuten herausfinden!
Benjohn

756

Apple hat einen JSON-Parser und Serializer in iOS 5.0 und Mac OS X 10.7 hinzugefügt. Siehe NSJSONSerialization .

Um eine JSON-Zeichenfolge aus einem NSDictionary oder NSArray zu generieren, müssen Sie kein Framework eines Drittanbieters mehr importieren.

So geht's:

NSError *error; 
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionaryOrArrayToOutput 
                                                   options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                     error:&error];

if (! jsonData) {
    NSLog(@"Got an error: %@", error);
} else {
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}

88
Dies ist ein guter Rat ... es ist wirklich ärgerlich, wenn Projekte eine Menge Bibliotheken von Drittanbietern haben.
Zakdances

3
Hervorragende Lösung für die Konvertierung in JSON Object. Tolle Arbeit .. :)
MS.

1
+1 Das Hinzufügen als Kategorie zu NSArrayund NSDictionarywürde die Wiederverwendung viel einfacher machen.
Devios1

Wie konvertiere ich den JSON zurück in ein Wörterbuch?
OMGPOP

5
@OMGPOP - [NSJSONSerialization JSONObjectWithData:options:error:]gibt ein Foundation-Objekt aus den angegebenen JSON-Daten zurück
Lukasz 'Severiaan' Grela

61

So konvertieren Sie ein NSDictionary in einen NSString:

NSError * err;
NSData * jsonData = [NSJSONSerialization dataWithJSONObject:myDictionary options:0 error:&err]; 
NSString * myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

34

HINWEIS: Diese Antwort wurde gegeben, bevor iOS 5 veröffentlicht wurde.

Holen Sie sich das JSON-Framework und machen Sie dies:

#import "SBJsonWriter.h"

...

SBJsonWriter *jsonWriter = [[SBJsonWriter alloc] init];

NSString *jsonString = [jsonWriter stringWithObject:myDictionary];  

[jsonWriter release];

myDictionary wird dein Wörterbuch sein.


Vielen Dank für Ihre Antwort. Können Sie mir bitte vorschlagen, wie ich das Framework zu meiner Anwendung hinzufügen soll? Es sieht so aus, als ob sich so viele Ordner im stig-json-framework-36b738f befinden
ChandraSekhar

@ChandraSekhar Nach dem Klonen des Git-Repositorys sollte es ausreichen, den Ordner Classes / zu Ihrem Projekt hinzuzufügen.
Nick Weaver

1
Ich habe gerade geschrieben stackoverflow.com/questions/11765037/… geschrieben , um dies vollständig zu veranschaulichen. Fügen Sie eine Fehlerprüfung und einige Ratschläge hinzu.
Pascal

25

Sie können dies auch im laufenden Betrieb tun, indem Sie Folgendes in den Debugger eingeben

po [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:yourDictionary options:1 error:nil] encoding:4];

4
Hartcodierte Konstanten sind etwas beängstigend. Warum nicht NSUTF8StringEncoding usw. verwenden?
Ian Newson

5
Das funktioniert derzeit nicht in LLDB:error: use of undeclared identifier 'NSUTF8StringEncoding'
Andy

2
Perfekt für Momente, in denen Sie schnell ein Wörterbuch mit einem externen JSON-Editor überprüfen möchten!
Florian

15

Sie können ein Array oder ein Wörterbuch übergeben. Hier nehme ich NSMutableDictionary.

NSMutableDictionary *contentDictionary = [[NSMutableDictionary alloc]init];
[contentDictionary setValue:@"a" forKey:@"b"];
[contentDictionary setValue:@"c" forKey:@"d"];

Um eine JSON-Zeichenfolge aus einem NSDictionary oder NSArray zu generieren, müssen Sie kein Framework eines Drittanbieters importieren. Verwenden Sie einfach folgenden Code: -

NSError *error; 
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:contentDictionary // Here you can pass array or dictionary
                    options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                    error:&error];
NSString *jsonString;
if (jsonData) {
    jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    //This is your JSON String
    //NSUTF8StringEncoding encodes special characters using an escaping scheme
} else {
    NSLog(@"Got an error: %@", error);
    jsonString = @"";
}
NSLog(@"Your JSON String is %@", jsonString);

12
NSMutableDictionary *contentDictionary = [[NSMutableDictionary alloc]init];
        [contentDictionary setValue:@"a" forKey:@"b"];
        [contentDictionary setValue:@"c" forKey:@"d"];
        NSData *data = [NSJSONSerialization dataWithJSONObject:contentDictionary options:NSJSONWritingPrettyPrinted error:nil];
        NSString *jsonStr = [[NSString alloc] initWithData:data
                                                  encoding:NSUTF8StringEncoding];

Wenn ich dies als Parameter an die POST-Anforderung übergebe, erhalte ich einen +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'Fehler. Verwenden von XCode 9.0
Daya Kevin

7

In Swift (Version 2.0) :

class func jsonStringWithJSONObject(jsonObject: AnyObject) throws -> String? {
    let data: NSData? = try? NSJSONSerialization.dataWithJSONObject(jsonObject, options: NSJSONWritingOptions.PrettyPrinted)

    var jsonStr: String?
    if data != nil {
        jsonStr = String(data: data!, encoding: NSUTF8StringEncoding)
    }

    return jsonStr
}

3

Jetzt brauchen keine Drittanbieter-Klassen ios 5 die Nsjsonserialisierung eingeführt

NSString *urlString=@"Your url";
NSString *urlUTF8 = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[[NSURL alloc]initWithString:urlUTF8];
NSURLRequest *request=[NSURLRequest requestWithURL:url];

NSURLResponse *response;

NSData *GETReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];

NSError *myError = nil;

NSDictionary *res = [NSJSONSerialization JSONObjectWithData:GETReply options:NSJSONReadingMutableLeaves|| NSJSONReadingMutableContainers error:&myError];

Nslog(@"%@",res);

Dieser Code kann nützlich sein, um jsondata abzurufen.


Ich denke es ist NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers.
Afp

1

In Swift habe ich die folgende Hilfsfunktion erstellt:

class func nsobjectToJSON(swiftObject: NSObject) {
    var jsonCreationError: NSError?
    let jsonData: NSData = NSJSONSerialization.dataWithJSONObject(swiftObject, options: NSJSONWritingOptions.PrettyPrinted, error: &jsonCreationError)!

    if jsonCreationError != nil {
        println("Errors: \(jsonCreationError)")
    }
    else {
        // everything is fine and we have our json stored as an NSData object. We can convert into NSString
        let strJSON : NSString =  NSString(data: jsonData, encoding: NSUTF8StringEncoding)!
        println("\(strJSON)")
    }
}


1

Hier ist die Swift 4 Version

extension NSDictionary{

func toString() throws -> String? {
    do {
        let data = try JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
        return String(data: data, encoding: .utf8)
    }
    catch (let error){
        throw error
    }
}

}}

Anwendungsbeispiel

do{
    let jsonString = try dic.toString()
    }
    catch( let error){
        print(error.localizedDescription)
    }

Oder wenn Sie sicher sind, dass es sich um ein gültiges Wörterbuch handelt, können Sie es verwenden

let jsonString = try? dic.toString()

Dies funktioniert nicht wie die angeforderte Frage. PrettyPrint behält den Abstand bei, wenn versucht wird, in eine Zeichenfolge zu quetschen.
Sean Lintern

1

Dies funktioniert in swift4 und swift5.

let dataDict = "the dictionary you want to convert in jsonString" 

let jsonData = try! JSONSerialization.data(withJSONObject: dataDict, options: JSONSerialization.WritingOptions.prettyPrinted)

let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String

print(jsonString)

-1
public func jsonPrint(_ o: NSObject, spacing: String = "", after: String = "", before: String = "") {
    let newSpacing = spacing + "    "
    if o.isArray() {
        print(before + "[")
        if let a = o as? Array<NSObject> {
            for object in a {
                jsonPrint(object, spacing: newSpacing, after: object == a.last! ? "" : ",", before: newSpacing)
            }
        }
        print(spacing + "]" + after)
    } else {
        if o.isDictionary() {
            print(before + "{")
            if let a = o as? Dictionary<NSObject, NSObject> {
                for (key, val) in a {
                    jsonPrint(val, spacing: newSpacing, after: ",", before: newSpacing + key.description + " = ")
                }
            }
            print(spacing + "}" + after)
        } else {
            print(before + o.description + after)
        }
    }
}

Dieser ist dem ursprünglichen Objective-C-Druckstil ziemlich nahe

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.