Tạo chuỗi JSON từ NSDipedia trong iOS


338

Tôi có một dictionarytôi cần phải tạo JSON stringbằng cách sử dụng dictionary. Có thể chuyển đổi nó? Các bạn có thể vui lòng giúp đỡ về điều này?


3
@RicardoRivaldo là thế này
QED

18
Bất cứ ai đến đây từ tìm kiếm google, vui lòng đọc qua câu trả lời dưới đây của @Guillaume
Mahendra Liya

Câu trả lời:


233

Dưới đây là các danh mục cho NSArray và NSDipedia để thực hiện việc này siêu dễ dàng. Tôi đã thêm một tùy chọn cho bản in đẹp (dòng mới và tab để dễ đọc hơn).

@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
nếu chúng ta tạo một thể loại NSObject và đặt cùng một phương thức, nó sẽ hoạt động cho cả NSArray và NSDipedia. Không cần phải viết hai tập tin / giao diện riêng biệt. Và nó sẽ trả về con số không trong trường hợp có lỗi.
Abdullah Umer

Tại sao bạn cho rằng đó NSUTF8StringEncodinglà mã hóa chính xác?
Heath

5
Không bao giờ, tài liệu nói "Dữ liệu kết quả được mã hóa theo UTF-8."
Heath

@AbdullahUmer Đó là những gì tôi đã thực hiện quá như tôi đoán nó cũng sẽ làm việc trên NSNumber, NSStringNSNull- sẽ tìm ra trong một hoặc hai phút!
Stewohn

756

Apple đã thêm trình phân tích cú pháp và trình tuần tự hóa JSON trong iOS 5.0 và Mac OS X 10.7. Xem NSJSONSerialization .

Để tạo chuỗi JSON từ NSDadata hoặc NSArray, bạn không cần phải nhập bất kỳ khung bên thứ ba nào nữa.

Đây là cách làm:

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
Đây là lời khuyên tốt ... thật khó chịu khi các dự án có rất nhiều thư viện của bên thứ ba.
zakdances

3
Giải pháp tuyệt vời để chuyển đổi sang đối tượng JSON. Công việc tuyệt vời .. :)
MS.

1
+1 Thêm mục này dưới dạng danh mục vào NSArrayNSDictionarysẽ giúp việc sử dụng lại đơn giản hơn nhiều.
devios1

Làm thế nào để chuyển đổi json trở lại từ điển?
OMGPOP

5
@OMGPOP - [NSJSONSerialization JSONObjectWithData:options:error:]trả về objec Foundation từ dữ liệu JSON đã cho
Lukasz 'Severiaan' Grela

61

Để chuyển đổi một NSDipedia thành NSString:

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

34

LƯU Ý: Câu trả lời này đã được đưa ra trước khi iOS 5 được phát hành.

Lấy json-framework và làm điều này:

#import "SBJsonWriter.h"

...

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

NSString *jsonString = [jsonWriter stringWithObject:myDictionary];  

[jsonWriter release];

myDictionary sẽ là từ điển của bạn.


Cám ơn phản hồi của bạn. Bạn có thể vui lòng gợi ý cho tôi cách thêm khung vào ứng dụng của mình không, có vẻ như có rất nhiều thư mục trong stig-json-framework-36b738f
ChandraSekhar

@ChandraSekhar sau khi nhân bản kho lưu trữ git, nên thêm thư mục Classes / vào dự án của bạn.
Nick Weaver

1
Tôi vừa viết stackoverflow.com/questions/11765037/ trên để minh họa đầy đủ điều này. Bao gồm kiểm tra lỗi và một số lời khuyên.
Pascal

25

Bạn cũng có thể thực hiện việc này một cách nhanh chóng bằng cách nhập thông tin sau vào trình gỡ lỗi

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

4
Hằng số mã hóa cứng là một chút đáng sợ. Tại sao không sử dụng NSUTF8StringEncoding, v.v.?
Ian Newson

5
Điều đó hiện không hoạt động trong LLDB:error: use of undeclared identifier 'NSUTF8StringEncoding'
Andy

2
Hoàn hảo cho những khoảnh khắc mà bạn nhanh chóng muốn kiểm tra từ điển với trình soạn thảo json bên ngoài!
Florian

15

Bạn có thể vượt qua mảng hoặc từ điển. Ở đây, tôi đang dùng NSMutableDixi.

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

Để tạo chuỗi JSON từ NSDipedia hoặc NSArray, Bạn không cần nhập bất kỳ khung bên thứ ba nào. Chỉ cần sử dụng mã sau đây: -

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

Khi tôi chuyển yêu cầu này đến POST như một tham số, tôi nhận được +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'lỗi. Sử dụng XCode 9.0
Daya Kevin

7

Trong Swift (phiên bản 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

Bây giờ không cần lớp bên thứ ba ios 5 đã giới thiệu 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);

mã này có thể hữu ích để có được jsondata.


Tôi nghĩ đó là NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers.
afp

1

Trong Swift, tôi đã tạo chức năng trợ giúp sau:

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

Đây là phiên bản 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
    }
}

}

Ví dụ sử dụng

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

Hoặc nếu bạn chắc chắn đó là từ điển hợp lệ thì bạn có thể sử dụng

let jsonString = try? dic.toString()

Điều này sẽ không thực hiện như câu hỏi được yêu cầu, beautifulPrint giữ lại khoảng cách khi cố gắng nén thành một chuỗi.
Sean Litern 7/12/18

1

Điều này sẽ hoạt động trong swift4 và 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)
        }
    }
}

Cái này khá gần với kiểu in Objective-C ban đầu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.