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];
/* 完 */