iOS的JSON转化其他常见类型,使用分类封装

iOS中对JSON的操作通常的使用场景是string与object相互转化,NSJSONSerialization类就是用于这个场景的,只不过是data与object相互转化,我们可以更进一步做data和string相互转化。

首先JSON Ojbect的标准是什么?先看看NSJSONSerialization里
+ (BOOL)isValidJSONObject:(id)obj的使用说明:

/* Returns YES if the given object can be converted to JSON data, 
 NO otherwise. The object must have the following properties:
    - Top level object is an NSArray or NSDictionary
    - All objects are NSString, NSNumber, NSArray, NSDictionary, or NSNull
    - All dictionary keys are NSStrings
    - NSNumbers are not NaN or infinity
 Other rules may apply. Calling this method or attempting a conversion 
 are the definitive ways to tell 
 if a given object can be converted to JSON data.
 */
+ (BOOL)isValidJSONObject:(id)obj;

因此我们可以很放心的使用这个方法判断是否是JSON object了

JSON data与JSON object互转,通常只用这两个方法:
+ (nullable NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;

+ (nullable id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;

先看看JSON string -> JSON object (dictionary 或 array)

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];

id jsonObj = [NSJSONSerialization JSONObjectWithData:jsonData 
                     options:NSJSONReadingAllowFragments 
                     error:nil];

然后是JSON object -> JSON string

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self 
                      options:NSJSONWritingPrettyPrinted 
                      error:nil];

NSString *jsonStr = [[NSString alloc] initWithData:stringData 
                      encoding:NSUTF8StringEncoding];

以上代码可以看出,中间都是经过NSData的(base64也是这样)。这样写并没有安全保护,而且不方便使用。所以需要封装一下。

首先创建一个NSObject的分类

#import 

@interface NSObject (ZZJSONExt)

- (NSString *)JSONString;
- (id)JSONObject;

@end

@implementation NSObject (ZZJSONExt)

- (NSString *)JSONString {
    // 请先判断自己是不是合法的JSON类型,不是就不能玩
    if ([NSJSONSerialization isValidJSONObject:self]) {
        NSData *stringData = [NSJSONSerialization dataWithJSONObject:self 
                               options:NSJSONWritingPrettyPrinted 
                               error:nil];
        return [[NSString alloc] initWithData:stringData 
                 encoding:NSUTF8StringEncoding];
    } else if ([self isKindOfClass:[NSString class]]) {
        // 这情况很坑,自己是string但又不知道是不是jsonString
        return [[self JSONObject] JSONString];
    }
    return nil;
}

- (id)JSONObject {
    // 请先判断自己是不是合法的JSON类型,是就别凑热闹了
    if ([NSJSONSerialization isValidJSONObject:self]) {
        return self;
    }
    id myself = self;
    NSData *jsonData = nil; // 万物基于data
    
    if ([self isKindOfClass:[NSData class]]) {
        // 自己是data的话直接转JSON
        jsonData = myself;
    } else if ([self isKindOfClass:[NSString class]]) { 
        // 是string的话先转dat再转JSON
        jsonData = [myself dataUsingEncoding:NSUTF8StringEncoding];
    }
    if (jsonData) {
        return [NSJSONSerialization JSONObjectWithData:jsonData 
                 options:NSJSONReadingAllowFragments 
                 error:nil];
    }
    return nil;
}

@end

然后可以随便转来转去啦

/* 任何object都可以用,是json就有结果 */
[xxx JSONString];
[yyy JSONObject];
/* 完 */

你可能感兴趣的:(iOS的JSON转化其他常见类型,使用分类封装)