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?

ChandraSekhar
quelle
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
Ben Clayton
quelle
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];
}
Guillaume
quelle
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];
jobima
quelle
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.

Nick Weaver
quelle
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];
Andy
quelle
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);
Treffen Sie Doshi
quelle
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];
user2885077
quelle
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
}
König-Zauberer
quelle
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.

Mahesh Chowdary
quelle
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)")
    }
}
James Laurenstin
quelle
1

Zumindest ab ISO7 können Sie dies problemlos mit NSJSONSerialization tun .

Jeef
quelle
Dies ist laut Link tatsächlich ab iOS 5.0 verfügbar, nicht ab 7.0.
Manroe
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()
levin varghese
quelle
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)
azeem usmani
quelle
-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

markov
quelle