在iOS中从NSDictionary生成JSON字符串


Answers:


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均适用。无需编写两个单独的文件/接口。并且在出现错误的情况下应该返回nil。
阿卜杜拉·乌默尔2014年

您为什么认为这NSUTF8StringEncoding是正确的编码?
Heath Borders

5
没关系,文档说“结果数据以UTF-8编码”。
Heath Borders'Apr

@AbdullahUmer这也是我所做的,因为我想它也可以在,和上工作NSNumber,一两分钟后就会发现!NSStringNSNull
约翰

756

苹果在iOS 5.0和Mac OS X 10.7中添加了JSON解析器和序列化器。请参阅NSJSONSerialization

要从NSDictionary或NSArray生成JSON字符串,您不再需要导入任何第三方框架。

这是操作方法:

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对象的绝佳解决方案。伟大的工作.. :)
女士。

1
+1将此作为类别添加到中NSArrayNSDictionary并使重用变得更加简单。
devios1

如何将json转换回字典?
OMGPOP'3

5
@OMGPOP - [NSJSONSerialization JSONObjectWithData:options:error:]从给定的JSON数据回报基金objec
卢卡斯“Severiaan”格雷拉

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 2011年

克隆git仓库后,@ ChandraSekhar应该足以将Classes /文件夹添加到您的项目中。
Nick Weaver

1
我只是写了stackoverflow.com/questions/11765037/…来充分说明这一点。包括错误检查和一些建议。
Pascal 2012年

25

您还可以通过在调试器中输入以下内容即时执行此操作

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

4
硬编码常量有点吓人。为什么不使用NSUTF8StringEncoding等?
伊恩·纽森

5
目前在LLDB中不起作用:error: use of undeclared identifier 'NSUTF8StringEncoding'
Andy

2
非常适合那些您想快速使用外部json编辑器检查字典的时刻!
弗洛里安2014年

15

您可以传递数组或字典。在这里,我正在学习NSMutableDictionary。

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

要从NSDictionary或NSArray生成JSON字符串,您不需要导入任何第三方框架。只需使用以下代码:

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
法新社

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

这是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会保留间距。
肖恩·林特纳

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打印样式

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.