สร้างสตริง JSON จาก NSDictionary ใน iOS


338

ฉันมีdictionaryผมจำเป็นที่จะต้องสร้างโดยใช้JSON string dictionaryมันเป็นไปได้ที่จะแปลงหรือไม่ พวกคุณช่วยได้ไหม


3
@RicardoRivaldo นั่นคือสิ่งนี้
QED

18
ใครมาที่นี่จากการค้นหาของ Google โปรดอ่านคำตอบด้านล่างโดย @Guillaume
Mahendra Liya

คำตอบ:


233

นี่คือหมวดหมู่สำหรับ NSArray และ NSDictionary เพื่อทำให้ง่ายสุด ๆ ฉันได้เพิ่มตัวเลือกสำหรับการพิมพ์ที่สวยงาม (บรรทัดใหม่และแท็บเพื่อให้อ่านง่ายขึ้น)

@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
ถ้าเราสร้างหมวดหมู่ของ NSObject และใส่เมธอดเดียวกันมันก็ใช้ได้กับทั้ง NSArray และ NSDictionary ไม่จำเป็นต้องเขียนไฟล์ / อินเตอร์เฟสแยกกันสองไฟล์ และควรกลับศูนย์ในกรณีที่มีข้อผิดพลาด
Abdullah Umer

ทำไมคุณคิดว่าNSUTF8StringEncodingการเข้ารหัสนั้นถูกต้อง?
Heath Borders

5
ไม่เป็นไรเอกสารอธิบายว่า "ข้อมูลที่ได้นั้นได้รับการเข้ารหัสใน UTF-8"
Heath Borders

@AbdullahUmer นั่นคือสิ่งที่ผมได้ทำเกินไปในขณะที่ผมเข้าใจก็ยังจะทำงานบนNSNumber, NSStringและNSNull- จะพบในหนึ่งหรือสองนาที!
Benjohn

756

Apple เพิ่ม JSON parser และ serializer ใน iOS 5.0 และ Mac OS X 10.7 ดูNSJSONSerialization

เพื่อสร้างสตริง JSON จาก NSDictionary หรือ NSArray คุณไม่จำเป็นต้องนำเข้าเฟรมเวิร์กของบุคคลที่สามอีกต่อไป

นี่คือวิธีที่จะทำ:

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
นี่เป็นคำแนะนำที่ดี ... มันน่ารำคาญจริงๆที่มีโปรเจ็กต์ที่มีห้องสมุดบุคคลที่สามมากมาย
zakdances

3
ทางออกที่ยอดเยี่ยมสำหรับการแปลงเป็นวัตถุ JSON เยี่ยมมาก .. :)
MS

1
+1 การเพิ่มสิ่งนี้เป็นหมวดหมู่NSArrayและNSDictionaryจะทำให้การนำกลับมาใช้ง่ายขึ้นมาก
devios1

วิธีการแปลง json กลับไปเป็นพจนานุกรม?
OMGPOP

5
@OMGPOP - [NSJSONSerialization JSONObjectWithData:options:error:]ส่งคืนค่า objec ของมูลนิธิจากข้อมูล JSON ที่กำหนด
Lukasz 'Severiaan' Grela

61

ในการแปลง NSDictionary เป็น NSString:

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

34

หมายเหตุ: คำตอบนี้ได้รับก่อนที่จะปล่อย iOS 5

รับjson-frameworkและทำสิ่งนี้:

#import "SBJsonWriter.h"

...

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

NSString *jsonString = [jsonWriter stringWithObject:myDictionary];  

[jsonWriter release];

myDictionary จะเป็นพจนานุกรมของคุณ


ขอบคุณสำหรับคำตอบของคุณ คุณช่วยแนะนำฉันเกี่ยวกับวิธีเพิ่มเฟรมเวิร์กให้กับแอปพลิเคชันของฉันได้อย่างไรดูเหมือนว่ามีโฟลเดอร์จำนวนมากใน stig-json-framework-36b738f
ChandraSekhar

@ChandraSekhar หลังจากทำการโคลนที่เก็บ git แล้วมันก็เพียงพอที่จะเพิ่ม Classes / folder ในโปรเจคของคุณ
Nick Weaver

1
ฉันเพิ่งเขียนstackoverflow.com/questions/11765037/…เพื่ออธิบายสิ่งนี้อย่างเต็มที่ รวมถึงการตรวจสอบข้อผิดพลาดและให้คำแนะนำบางอย่าง
ปาสกาล

25

นอกจากนี้คุณยังสามารถทำสิ่งนี้ได้ทันทีโดยป้อนข้อมูลต่อไปนี้ลงในดีบักเกอร์

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

4
ค่าคงที่รหัสตายยากน่ากลัวเล็กน้อย ทำไมไม่ใช้ NSUTF8StringEncoding เป็นต้น?
Ian Newson

5
ขณะนี้ไม่สามารถใช้งานใน LLDB:error: use of undeclared identifier 'NSUTF8StringEncoding'
Andy

2
สมบูรณ์แบบสำหรับช่วงเวลาที่คุณต้องการตรวจสอบพจนานุกรมอย่างรวดเร็วด้วยเครื่องมือแก้ไข json ภายนอก!
Florian

15

คุณสามารถผ่านอาร์เรย์หรือพจนานุกรม ที่นี่ฉันกำลังใช้พจนานุกรม NSMutable

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

ในการสร้างสตริง JSON จาก NSDictionary หรือ NSArray คุณไม่จำเป็นต้องนำเข้าเฟรมเวิร์กของบุคคลที่สาม เพียงใช้รหัสต่อไปนี้: -

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];

เมื่อฉันผ่านสิ่งนี้ไปยังคำขอ POST เป็นพารามิเตอร์ฉันได้รับ+[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'ข้อผิดพลาด ใช้ XCode 9.0
Daya Kevin

7

ในSwift (เวอร์ชั่น 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

ตอนนี้ไม่จำเป็นต้องเรียนบุคคลที่สาม iOS 5 แนะนำ Nsjsonserialization

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);

รหัสนี้มีประโยชน์สำหรับการรับ jsondata


NSJSONReadingMutableLeaves | NSJSONReadingMutableContainersฉันคิดว่ามัน
afp

1

ใน Swift ฉันได้สร้างฟังก์ชั่นตัวช่วยดังต่อไปนี้:

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

ในฐานะของ ISO7 อย่างน้อยคุณสามารถทำเช่นนี้กับNSJSONSerialization


มีให้บริการใน iOS 5.0 ไม่ใช่ 7.0 ตามลิงก์
manroe

1

นี่คือเวอร์ชั่นSwift 4

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
    }
}

}

ตัวอย่างการใช้งาน

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

หรือถ้าคุณแน่ใจว่ามันเป็นพจนานุกรมที่ถูกต้องแล้วคุณสามารถใช้

let jsonString = try? dic.toString()

สิ่งนี้จะไม่เหมือนกับคำถามที่ร้องขอ prettyPrint จะรักษาระยะห่างเมื่อพยายามสควอชเป็นสตริง
Sean Lintern

1

สิ่งนี้จะทำงานใน swift4 และ 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)
        }
    }
}

อันนี้ค่อนข้างใกล้เคียงกับสไตล์การพิมพ์ดั้งเดิมของ Objective-C

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.