在 iOS 的 UITextView 或 UIWebView 中显示 JSON(格式正确)的最佳方式

Posted

技术标签:

【中文标题】在 iOS 的 UITextView 或 UIWebView 中显示 JSON(格式正确)的最佳方式【英文标题】:Best way to display JSON (well formatted) in UITextView or UIWebView in iOS 【发布时间】:2015-06-28 13:23:53 【问题描述】:

我需要在我的 iPhone 应用程序中显示 JSON。目前我正在获取未格式化的 JSON - 就像一个没有缩进的大字符串。

什么是最好的展示方式?

谢谢,

【问题讨论】:

【参考方案1】:

获取格式化的 JSON 字符串。

解决方案是从 JSON 字符串创建 JSON 对象,

然后使用 .PrettyPrinted 选项将 JSON 对象转换回 JSON 字符串。

代码是

let jsonString = "[\"person\": \"name\":\"Dani\",\"age\":\"24\",\"person\": \"name\":\"ray\",\"age\":\"70\"]"

var error: NSError?

//1. convert string to NSData
let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)!

//2. convert JSON data to JSON object
let jsonObject:AnyObject = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error)!

//3. convert back to JSON data by setting .PrettyPrinted option
let prettyJsonData = NSJSONSerialization.dataWithJSONObject(jsonObject, options: .PrettyPrinted, error: &error)!

//4. convert NSData back to NSString (use NSString init for convenience), later you can convert to String.
let prettyPrintedJson = NSString(data: prettyJsonData, encoding: NSUTF8StringEncoding)!

//print the result
println("\(prettyPrintedJson)")

结果将如下所示

【讨论】:

@nRewik 为什么是NSString 而不是String【参考方案2】:

Objective-C 代码

NSString *jsonString = @"[\"person\": \"name\":\"Dani\",\"age\":\"24\",\"person\": \"name\":\"ray\",\"age\":\"70\"]";
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&error];
NSData *prettyJsonData = [NSJSONSerialization dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:&error];
NSString *prettyPrintedJson = [NSString stringWithUTF8String:[prettyJsonData bytes]];

NSLog(@"%@", prettyPrintedJson);

【讨论】:

【参考方案3】:

这是 Objective-C 代码。


NSString+PrettyPrint.h

@interface NSString (PrettyPrint)

+ (NSString * _Nonnull)prettifiedJsonStringFromData:(nullable NSData *)data;
+ (NSString * _Nonnull)prettifiedStringFromDictionary:(nullable NSDictionary *)dictionary;

@end

NSString+PrettyPrint.m

#import "NSString+PrettyPrint.h"

@implementation NSString (PrettyPrint)

+ (NSString *)prettifiedStringFromDictionary:(nullable NSDictionary *)dictionary 
    
    if (dictionary == nil)  return @"nil"; 
    
    NSMutableString *returnStr = [NSMutableString stringWithString:@"[ \n"];
    
    for (NSString *key in dictionary) 
        [returnStr appendFormat:@"  %@: %@,\n", key, [dictionary valueForKey:key]];
    

    [returnStr appendFormat:@"]"];

    return returnStr;


+ (NSString *)prettifiedJsonStringFromData:(nullable NSData *)data 
    
    if (data == nil)  return @"nil"; 
    
    NSData *jsonData;
    NSError *error = nil;
    
    NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:&error];
    if (jsonObject == nil) 
        return @"nil (json object from data)";
     else 
        BOOL isValidJsonObject = [NSJSONSerialization isValidJSONObject:jsonObject];
        if (isValidJsonObject) 
            NSData *finalData = [NSJSONSerialization dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:&error];
            //TODO: error description
            NSString *prettyJson = [[NSString alloc] initWithData:finalData encoding:NSUTF8StringEncoding];
            return prettyJson;
         else 
            return [NSString stringWithFormat:@"%@\n%@", jsonStr, @" (⚠️ Invalid json object ⚠️)\n"];
        
    


@end

然后在你需要使用方法时调用它们。

ex1.为 body、response ...等打印 NSData

NSLog(@"body: %@", [NSString prettifiedJsonStringFromData:[request HTTPBody]]);

ex2.打印 NSDictionary

NSLog(@"headers: %@", [NSString prettifiedStringFromDictionary:[request allHTTPHeaderFields]]);

您可能会在日志中得到这些结果。

【讨论】:

【参考方案4】:

请记住,如果您正在处理 Encodable 对象,则可以使用 JSONEncoder 进行漂亮的打印。

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
        
guard let jsonData = try? encoder.encode(obj) else 
    return

        
let text = String(decoding: jsonData, as: UTF8.self)

【讨论】:

以上是关于在 iOS 的 UITextView 或 UIWebView 中显示 JSON(格式正确)的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

隐藏 iOS 键盘预测文本栏 - UITextView / UITextField

有没有办法让 iOS 的自动更正忽略 UITextView 中的单个单词或正则表达式?

iOS UITextView 或 UILabel 带有可点击的动作链接[重复]

iOS 7 UITextView 的原生链接不会取消触摸

在 UITextView 上以编程方式禁用 iOS8 Quicktype 键盘

iOS 8.1仅间歇性地显示UITextView