1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//#import "SBJSON.h"
//#import "NSObject+SBJSON.h"
//#import "NSString+SBJSON.h"
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
]
;
NSString
*
filePath
=
[
[
NSBundle
mainBundle
]
pathForResource
:
@"CITY"
ofType
:
@"json"
]
;
NSLog
(
@"filePath=%@"
,
filePath
)
;
NSString
*
jsonData
=
[
NSString
stringWithContentsOfFile
:
filePath
encoding
:
NSUTF8StringEncoding
error
:
nil
]
;
NSMutableDictionary
*
dic
=
[
jsonData
JSONValue
]
;
NSLog
(
@"dic = %@"
,
dic
)
;
}
//通过JSONValue就可以将数据解析为我们数值的数组或者字典形式了!
|
@H_755_301@
@H_301_307@
SBJson是一个开源的json库,结构如下:
结构主要分为:主头文件SBJson.h,一个对象类别扩展NSObject+SBJson.h,一个json解析包Parser,一个json编写包Writer
任何使用SBJson库的地方都要导入SBJson.h头文件
1.JSON转Objective-C,方法如下:
null -> NSNull
string -> NSString
array -> NSMutableArray
object -> NSMutableDictionary
true -> NSNumber's -numberWithBool:YES
false -> NSNumber's -numberWithBool:NO
integer up to 19 digits -> NSNumber's -numberWithLongLong:
all other numbers -> NSDecimalNumber
true或false转为 [NSNumber numberWithBool:YES]或[NSNumber numberWithBool:NO]
integer整数长度19位,表现为LongLong类型,[NSNumber numberWithLongLong:]
json允许大的离谱的数字,为避免任何精度损失,将其他复杂数变成NSDecimalNumber实例
2.Objective-C转JSON,方法如下:
NSNull -> null
NSString -> string
NSArray -> array
NSDictionary -> object
NSNumber's -initWithBool:YES -> true
NSNumber's -initWithBool:NO -> false
NSNumber -> number
注意:JSON中对象的键key必须是字符串
NSDictionary中的键key,可能不是字符串,所以当拥有非字符串的键的NSDictionary转为json时会抛出异常
主要两个接口:
[NSObjectJSONRepresentation]
[NSStringJSONValue]
@H_301_307@
一.NSObject+SBJson.h
1.把objc对象编码成json字符串
通过类别,为NSObject添加新方法:[NSObjectJSONRepresentation]
@H_826_502@1 @interface NSObject (NSObject_SBJsonWriting)
@H_826_502@2 /**@H_826_502@ @H_826_502@3 虽然定义成NSObject的类别,但仅对NSArray和NSDictionary有效
@H_826_502@4 返回:已编码的json对象,或nil
@H_826_502@5 */
@H_826_502@6 - (NSString *)JSONRepresentation;
@H_826_502@7 @end
2.把json对象解析为objc对象
通过类别,为NSString添加新方法:[NSStringJSONValue]
@H_826_502@1 @interface NSString (NSString_SBJsonParsing)
@H_826_502@2 /**
@H_826_502@3 返回:NSDictionary或NSArray对象,或nil
@H_826_502@4 */
@H_826_502@5 - (id)JSONValue;
@H_826_502@6 @end
二.NSObject+SBJson.m
导入头文件
@H_826_502@1 #import "NSObject+SBJson.h"
@H_826_502@2 #import "SBJsonWriter.h"
@H_826_502@3 #import "SBJsonParser.h"
1.通过json编写器SBJsonWriter,的stringWithObject: 方法,实现[NSObjectJSONRepresentation]编码逻辑
@H_826_502@ 1 @implementation NSObject (NSObject_SBJsonWriting)
@H_826_502@ 2
@H_826_502@ 3 //objc2json
@H_826_502@ 4 - (NSString *)JSONRepresentation {
@H_826_502@ 5 SBJsonWriter *writer = [[SBJsonWriter alloc] init];
@H_826_502@ 6 NSString *json = [writer stringWithObject:self];
@H_826_502@ 7 if (!json)
@H_826_502@ 8 NSLog(@"-JSONRepresentation Failed. Error is: %@",writer.error);
@H_826_502@ 9 return json;
@H_826_502@10 }
@H_826_502@11
@H_826_502@12 @end
2.通过json解析器SBJsonParser,的objectWithString: 方法,实现[NSStringJSONValue]解析逻辑
@H_826_502@ 1 @implementation NSString (NSString_SBJsonParsing)
@H_826_502@ 2
@H_826_502@ 3 //json2objc
@H_826_502@ 4 - (id)JSONValue {
@H_826_502@ 5 SBJsonParser *parser = [[SBJsonParser alloc] init];
@H_826_502@ 6 id repr = [parser objectWithString:self];
@H_826_502@ 7 if (!repr)
@H_826_502@ 8 NSLog(@"-JSONValue Failed. Error is: %@",parser.error);
@H_826_502@ 9 return repr;
@H_826_502@10 }
@H_826_502@11
@H_826_502@12 @end
SBJsonWriter:json编写器类
内部使用了json流编写器:SBJsonStreamWriter类,和json流编写累加器:SBJsonStreamWriterAccumulator类
主要有4个属性:
@H_826_502@ 1 /**
@H_826_502@ 2 @最大递归深度,默认为32
@H_826_502@ 3 如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
@H_826_502@ 4 可以通过设置maxDepth为0,来取消此安全功能
@H_826_502@ 5 */
@H_826_502@ 6 @property NSUInteger maxDepth;
@H_826_502@ 7
@H_826_502@ 8 /**
@H_826_502@ 9 @返回一个出错信息,如果没错误,返回为nil
@H_826_502@10 */
@H_826_502@11 @property (readonly,copy) NSString *error;
@H_826_502@12
@H_826_502@13 /**
@H_826_502@14 @是否为人类可读的json
@H_826_502@15 默认为NO,产生的json没有任何空白
@H_826_502@16 如果设为YES,换行后,每个数组值和字典键/值对缩进两个空格
@H_826_502@17 */
@H_826_502@18 @property BOOL humanReadable;
@H_826_502@19
@H_826_502@20 /**
@H_826_502@21 @输出时字典键是否排序
@H_826_502@22 默认为NO,如果设为YES,排序json输出的字典键
@H_826_502@23 如果你需要比较两个结构时候很有用
@H_826_502@24 */
@H_826_502@25 @property BOOL sortKeys;
注意:上面的error属性为只读的(readonly)
属性实现在SBJsonWriter.m文件中:
@H_826_502@1 @synthesize sortKeys;
@H_826_502@2 @synthesize humanReadable;
@H_826_502@3 @synthesize error;
@H_826_502@4 @synthesize maxDepth;
其中error通过类别声明为私有可写,如下:
@H_826_502@1 @interface SBJsonWriter ()
@H_826_502@2 @property (copy) NSString *error;
@H_826_502@3 @end
此类有3个转json表述的方法:
@H_826_502@ 1 /**
@H_826_502@ 2 @objc转成NSString
@H_826_502@ 3 返回给定objc对象的json表示
@H_826_502@ 4 返回一个字符串,或nil
@H_826_502@ 5 如果返回nil,则SBJsonWriter的error属性不为空,可以通过error的信息知道出错原因
@H_826_502@ 6 其中的参数value,是任何可以用json表述的对象
@H_826_502@ 7 */
@H_826_502@ 8 - (NSString*)stringWithObject:(id)value;
@H_826_502@ 9
@H_826_502@10 /**
@H_826_502@11 @objc转成NSData
@H_826_502@12 返回给定objc对象的json表示,用UTF8编码
@H_826_502@13 返回一个NSData对象,或nil
@H_826_502@14 */
@H_826_502@15 - (NSData*)dataWithObject:(id)value;
@H_826_502@16
@H_826_502@17 /**
@H_826_502@18 @返回给定objc对象的json表示(或片段)
@H_826_502@19 返回字符串,或nil
@H_826_502@20 */
@H_826_502@21 - (NSString*)stringWithObject:(id)value
@H_826_502@22 error:(NSError**)error;
三个方法的具体实现在SBJsonWriter.m文件中
@H_826_502@ 1 //把objc转成NSData,再通过UTF8编码把NSData转成字符串
@H_826_502@ 2 - (NSString*)stringWithObject:(id)value {
@H_826_502@ 3 NSData *data = [self dataWithObject:value];
@H_826_502@ 4 if (data)
@H_826_502@ 5 return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
@H_826_502@ 6 return nil;
@H_826_502@ 7 }
@H_826_502@ 8
@H_826_502@ 9 - (NSString*)stringWithObject:(id)value error:(NSError**)error_ {
@H_826_502@10 NSString *tmp = [self stringWithObject:value];
@H_826_502@11 if (tmp)
@H_826_502@12 return tmp;
@H_826_502@13
@H_826_502@14 if (error_) {
@H_826_502@15 NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error,NSLocalizedDescriptionKey,nil];
@H_826_502@16 *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonWriter.ErrorDomain" code:0 userInfo:ui];
@H_826_502@17 }
@H_826_502@18
@H_826_502@19 return nil;
@H_826_502@20 }
@H_826_502@21
@H_826_502@22 /**
@H_826_502@23 初始化一个json流编写器,设置参数
@H_826_502@24 初始化一个json流编写叠加器,把它设为SBJsonStreamWriter的代理(delegate)
@H_826_502@25 把ojbc对象转变为NSData,通过调用SBJsonStreamWriter的writeObject:方法,或writeArray:方法,
@H_826_502@26 或递归调用dataWithObject:方法,参数为[object proxyForJson]返回的代理对象
@H_826_502@27 其中SBJsonStreamWriter的各种write方法,是把基本数据写成二进制bytes
@H_826_502@28 然后通过叠加器SBJsonStreamWriterAccumulator,把二进制bytes拼装成NSData对象
@H_826_502@29 返回叠加器的data属性变量
@H_826_502@30 */
@H_826_502@31 - (NSData*)dataWithObject:(id)object {
@H_826_502@32 self.error = nil;
@H_826_502@33
@H_826_502@34 SBJsonStreamWriterAccumulator *accumulator = [[SBJsonStreamWriterAccumulator alloc] init];
@H_826_502@35
@H_826_502@36 SBJsonStreamWriter *streamWriter = [[SBJsonStreamWriter alloc] init];
@H_826_502@37 streamWriter.sortKeys = self.sortKeys;
@H_826_502@38 streamWriter.maxDepth = self.maxDepth;
@H_826_502@39 streamWriter.humanReadable = self.humanReadable;
@H_826_502@40 streamWriter.delegate = accumulator;
@H_826_502@41
@H_826_502@42 BOOL ok = NO;
@H_826_502@43 if ([object isKindOfClass:[NSDictionary class]])
@H_826_502@44 ok = [streamWriter writeObject:object];
@H_826_502@45
@H_826_502@46 else if ([object isKindOfClass:[NSArray class]])
@H_826_502@47 ok = [streamWriter writeArray:object];
@H_826_502@48
@H_826_502@49 else if ([object respondsToSelector:@selector(proxyForJson)])
@H_826_502@50 return [self dataWithObject:[object proxyForJson]];
@H_826_502@51 else {
@H_826_502@52 self.error = @"Not valid type for JSON";
@H_826_502@53 return nil;
@H_826_502@54 }
@H_826_502@55
@H_826_502@56 if (ok)
@H_826_502@57 return accumulator.data;
@H_826_502@58
@H_826_502@59 self.error = streamWriter.error;
@H_826_502@60 return nil;
@H_826_502@61 }
json流编写器
允许传入一个消息流对象,把它写入到SBJsonStreamWriterAccumulator的data里.
1.里面含有个新的NSObject类别,把objc对象转成json允许的对象类型
@H_826_502@ 1 @interface NSObject (SBProxyForJson)
@H_826_502@ 2
@H_826_502@ 3 /**
@H_826_502@ 4 json只支持NSArray和NSDictionary等类型
@H_826_502@ 5 所以转换之前先把特定objc对象转成这两种类型的形式
@H_826_502@ 6 如果你有一个自定义类,要把它转成json,需要实现该方法
@H_826_502@ 7 例子如下:
@H_826_502@ 8 @code
@H_826_502@ 9 - (id)proxyForJson {
@H_826_502@10 return [NSDictionary dictionaryWithObjectsAndKeys:
@H_826_502@11 name,@"name",@H_826_502@12 phone,@"phone",@H_826_502@13 email,@"email",@H_826_502@14 nil];
@H_826_502@15 }
@H_826_502@16 @endcode
@H_826_502@17 */
@H_826_502@18
@H_826_502@19 - (id)proxyForJson;
@H_826_502@20
@H_826_502@21 @end
2.里面定义了个json流编写器代理协议:
@H_826_502@1 //在json流编写叠加器SBJsonStreamWriterAccumulator里实现
@H_826_502@2 @protocol SBJsonStreamWriterDelegate
@H_826_502@3
@H_826_502@4 - (void)writer:(SBJsonStreamWriter*)writer appendBytes:(const void *)bytes length:(NSUInteger)length;
@H_826_502@5
@H_826_502@6 @end
3.定义了一个私有属性:
NSMutableDictionary *cache;
4.定义了7个公有属性:
@H_826_502@ 1 @property (nonatomic,unsafe_unretained) SBJsonStreamWriterState *state; // Internal
@H_826_502@ 2 @property (nonatomic,readonly,strong) NSMutableArray *stateStack; // Internal
@H_826_502@ 3
@H_826_502@ 4 //json输出流的代理
@H_826_502@ 5 @property (unsafe_unretained) id<SBJsonStreamWriterDelegate> delegate;
@H_826_502@ 6
@H_826_502@ 7 /**
@H_826_502@ 8 @最大递归深度,默认为512.
@H_826_502@ 9 如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
@H_826_502@10 可以通过设置maxDepth为0,来取消此安全功能
@H_826_502@11 */
@H_826_502@12 @property NSUInteger maxDepth;
@H_826_502@13
@H_826_502@14 /**
@H_826_502@15 @是否为人类可读的json
@H_826_502@16 默认为NO,产生的json没有任何空白
@H_826_502@17 如果设为YES,换行后,每个数组值和字典键/值对缩进两个空格
@H_826_502@18 */
@H_826_502@19 @property BOOL humanReadable;
@H_826_502@20
@H_826_502@21 /**
@H_826_502@22 @输出时字典键是否排序
@H_826_502@23 默认为NO,如果设为YES,排序json输出的字典键
@H_826_502@24 如果你需要比较两个结构时候很有用
@H_826_502@25 */
@H_826_502@26 @property BOOL sortKeys;
@H_826_502@27
@H_826_502@28 /**
@H_826_502@29 @返回一个出错信息,如果没错误,返回为nil
@H_826_502@30 */
@H_826_502@31 @property (copy) NSString *error;
5.定义了10个公有方法:
@H_826_502@ 1 /**
@H_826_502@ 2 把NSDictionary对象写到JSON输出流
@H_826_502@ 3 返回YES,表示成功
@H_826_502@ 4 */
@H_826_502@ 5 - (BOOL)writeObject:(NSDictionary*)dict;
@H_826_502@ 6
@H_826_502@ 7 /**
@H_826_502@ 8 把NSArray对象写入JSON输出流
@H_826_502@ 9 返回YES,表示成功
@H_826_502@10 */
@H_826_502@11 - (BOOL)writeArray:(NSArray *)array;
@H_826_502@12
@H_826_502@13 /**
@H_826_502@14 开始写一个obj对象到JSON输出流
@H_826_502@15 返回YES,表示成功
@H_826_502@16 */
@H_826_502@17 - (BOOL)writeObjectOpen;
@H_826_502@18
@H_826_502@19 /**
@H_826_502@20 结束写obj对象到JSON输出流
@H_826_502@21 返回YES,表示成功
@H_826_502@22 */
@H_826_502@23 - (BOOL)writeObjectClose;
@H_826_502@24
@H_826_502@25 /**
@H_826_502@26 开始写一个Array对象到JSON输出流
@H_826_502@27 返回YES,表示成功
@H_826_502@28 */
@H_826_502@29 - (BOOL)writeArrayOpen;
@H_826_502@30
@H_826_502@31 /**
@H_826_502@32 结束写Array对象到JSON输出流
@H_826_502@33 返回YES,表示成功
@H_826_502@34 */
@H_826_502@35 - (BOOL)writeArrayClose;
@H_826_502@36
@H_826_502@37 /**
@H_826_502@38 把null对象写入JSON输出流
@H_826_502@39 返回YES,表示成功
@H_826_502@40 */
@H_826_502@41 - (BOOL)writeNull;
@H_826_502@42
@H_826_502@43 /**
@H_826_502@44 把boolean对象写入JSON输出流
@H_826_502@45 返回YES,表示成功
@H_826_502@46 */
@H_826_502@47 - (BOOL)writeBool:(BOOL)x;
@H_826_502@48
@H_826_502@49 /**
@H_826_502@50 把Number对象写入JSON输出流
@H_826_502@51 返回YES,表示成功
@H_826_502@52 */
@H_826_502@53 - (BOOL)writeNumber:(NSNumber*)n;
@H_826_502@54
@H_826_502@55 /**
@H_826_502@56 把String对象写入JSON输出流
@H_826_502@57 返回YES,表示成功
@H_826_502@58 */
@H_826_502@59 - (BOOL)writeString:(NSString*)s;
6.有个类别,定义了两个私有方法:
@H_826_502@1 @interface SBJsonStreamWriter (Private)
@H_826_502@2 - (BOOL)writeValue:(id)v;
@H_826_502@3 - (void)appendBytes:(const void *)bytes length:(NSUInteger)length;
@H_826_502@4 @end
json流编写叠加器,拥有个可变data对象
@H_826_502@1 @interface SBJsonStreamWriterAccumulator : NSObject <SBJsonStreamWriterDelegate>
@H_826_502@2
@H_826_502@3 @property (readonly,copy) NSMutableData* data;
@H_826_502@4
@H_826_502@5 @end
具体实现:
@H_826_502@ 1 @implementation SBJsonStreamWriterAccumulator
@H_826_502@ 2
@H_826_502@ 3 @synthesize data;
@H_826_502@ 4
@H_826_502@ 5 - (id)init {
@H_826_502@ 6 self = [super init];
@H_826_502@ 7 if (self) {
@H_826_502@ 8 data = [[NSMutableData alloc] initWithCapacity:8096u];
@H_826_502@ 9 }
@H_826_502@10 return self;
@H_826_502@11 }
@H_826_502@12
@H_826_502@13
@H_826_502@14 #pragma mark SBJsonStreamWriterDelegate
@H_826_502@15
@H_826_502@16 //实现SBJsonStreamWriterDelegate协议,把二进制数据添加到data
@H_826_502@17
@H_826_502@18 - (void)writer:(SBJsonStreamWriter *)writer appendBytes:(const void *)bytes length:(NSUInteger)length {
@H_826_502@19 [data appendBytes:bytes length:length];
@H_826_502@20 }
@H_826_502@21
@H_826_502@22 @end
json解析器
@H_826_502@ 1 /**
@H_826_502@ 2 json转objc
@H_826_502@ 3 解析json字符串和NSData对象
@H_826_502@ 4 内部使用了SBJsonStreamParser类
@H_826_502@ 5 */
@H_826_502@ 6
@H_826_502@ 7 @interface SBJsonParser : NSObject
@H_826_502@ 8
@H_826_502@ 9 /**
@H_826_502@10 @最大递归深度,默认为32
@H_826_502@11 如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
@H_826_502@12 可以通过设置maxDepth为0,来取消此安全功能
@H_826_502@13 */
@H_826_502@14 @property NSUInteger maxDepth;
@H_826_502@15
@H_826_502@16 /**
@H_826_502@17 @返回一个出错信息,如果没错误,返回为nil
@H_826_502@18 */
@H_826_502@19 @property(copy) NSString *error;
@H_826_502@20
@H_826_502@21 /**
@H_826_502@22 json转objc
@H_826_502@23 @返回给定的NSData所代表的对象
@H_826_502@24 参数data必须为UTF8编码
@H_826_502@25 返回NSArray或NSDictionary对象,如果返回nil,表示出现错误
@H_826_502@26 */
@H_826_502@27 - (id)objectWithData:(NSData*)data;
@H_826_502@28
@H_826_502@29 /**
@H_826_502@30 json转objc
@H_826_502@31 @返回给定字符串所代表的对象
@H_826_502@32 此方法内部实现是:把参数用UTF8编码成NSData,然后调用objectWithData:方法,转成NSArray或NSDictionary,或nil
@H_826_502@33 */
@H_826_502@34 - (id)objectWithString:(NSString *)repr;
@H_826_502@35
@H_826_502@36 /**
@H_826_502@37 json转objc
@H_826_502@38 @返回给定字符串所代表的对象
@H_826_502@39 */
@H_826_502@40
@H_826_502@41 - (id)objectWithString:(NSString*)jsonText
@H_826_502@42 error:(NSError**)error;
@H_826_502@43
@H_826_502@44 @end
实现在SBJsonParser.m文件中:
@H_826_502@ 1 #import "SBJsonParser.h"
@H_826_502@ 2 #import "SBJsonStreamParser.h"
@H_826_502@ 3 #import "SBJsonStreamParserAdapter.h"
@H_826_502@ 4 #import "SBJsonStreamParserAccumulator.h"
@H_826_502@ 5
@H_826_502@ 6 @implementation SBJsonParser
@H_826_502@ 7
@H_826_502@ 8 @synthesize maxDepth;
@H_826_502@ 9 @synthesize error;
@H_826_502@10
@H_826_502@11 - (id)init {
@H_826_502@12 self = [super init];
@H_826_502@13 if (self)
@H_826_502@14 self.maxDepth = 32u;
@H_826_502@15 return self;
@H_826_502@16 }
@H_826_502@17
@H_826_502@18 #pragma mark Methods
@H_826_502@19
@H_826_502@20 /**
@H_826_502@21 调用流解析器SBJsonStreamParser的parse:方法,把NSData转成NSArray或NSDictionary对象
@H_826_502@22 */
@H_826_502@23 - (id)objectWithData:(NSData *)data {
@H_826_502@24
@H_826_502@25 if (!data) {
@H_826_502@26 self.error = @"Input was 'nil'";
@H_826_502@27 return nil;
@H_826_502@28 }
@H_826_502@29
@H_826_502@30 //初始化一个json流解析叠加器
@H_826_502@31 SBJsonStreamParserAccumulator *accumulator = [[SBJsonStreamParserAccumulator alloc] init];
@H_826_502@32
@H_826_502@33 //初始化一个json流解析配置器
@H_826_502@34 SBJsonStreamParserAdapter *adapter = [[SBJsonStreamParserAdapter alloc] init];
@H_826_502@35 //把叠加器设为配置器的代理(delegate)
@H_826_502@36 adapter.delegate = accumulator;
@H_826_502@37
@H_826_502@38 //初始化一个json流解析器,设置参数
@H_826_502@39 SBJsonStreamParser *parser = [[SBJsonStreamParser alloc] init];
@H_826_502@40 parser.maxDepth = self.maxDepth;
@H_826_502@41 //把配置器设为解析器的代理(delegate)
@H_826_502@42 parser.delegate = adapter;
@H_826_502@43
@H_826_502@44 switch ([parser parse:data]) {
@H_826_502@45 case SBJsonStreamParserComplete:
@H_826_502@46 return accumulator.value;
@H_826_502@47 break;
@H_826_502@48
@H_826_502@49 case SBJsonStreamParserWaitingForData:
@H_826_502@50 self.error = @"Unexpected end of input";
@H_826_502@51 break;
@H_826_502@52
@H_826_502@53 case SBJsonStreamParserError:
@H_826_502@54 self.error = parser.error;
@H_826_502@55 break;
@H_826_502@56 }
@H_826_502@57
@H_826_502@58 return nil;
@H_826_502@59 }
@H_826_502@60
@H_826_502@61 //NSString用UTF8编码成NSData,再把NSData转成NSArray或NSDictionary对象
@H_826_502@62 - (id)objectWithString:(NSString *)repr {
@H_826_502@63 return [self objectWithData:[repr dataUsingEncoding:NSUTF8StringEncoding]];
@H_826_502@64 }
@H_826_502@65
@H_826_502@66 - (id)objectWithString:(NSString*)repr error:(NSError**)error_ {
@H_826_502@67 id tmp = [self objectWithString:repr];
@H_826_502@68 if (tmp)
@H_826_502@69 return tmp;
@H_826_502@70
@H_826_502@71 if (error_) {
@H_826_502@72 NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error,nil];
@H_826_502@73 *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonParser.ErrorDomain" code:0 userInfo:ui];
@H_826_502@74 }
@H_826_502@75
@H_826_502@76 return nil;
@H_826_502@77 }
@H_826_502@78
@H_826_502@79 @end
json数据流解析器
1.定义了一个枚举值表示解析状态:
@H_826_502@1 typedef enum {
@H_826_502@2 SBJsonStreamParserComplete,@H_826_502@3 SBJsonStreamParserWaitingForData,@H_826_502@4 SBJsonStreamParserError,@H_826_502@5 } SBJsonStreamParserStatus;
2.定义了一个json流解析代理协议:
@H_826_502@ 1 /**
@H_826_502@ 2 由SBJsonStreamParserAdapter类实现
@H_826_502@ 3 */
@H_826_502@ 4 @protocol SBJsonStreamParserDelegate
@H_826_502@ 5
@H_826_502@ 6 //当找到obj时调用
@H_826_502@ 7 - (void)parserFoundObjectStart:(SBJsonStreamParser*)parser;
@H_826_502@ 8
@H_826_502@ 9 //当找到obj对象key时调用
@H_826_502@10 - (void)parser:(SBJsonStreamParser*)parser foundObjectKey:(NSString*)key;
@H_826_502@11
@H_826_502@12 //当obj结束时调用
@H_826_502@13 - (void)parserFoundObjectEnd:(SBJsonStreamParser*)parser;
@H_826_502@14
@H_826_502@15 //当找到array对象时调用
@H_826_502@16 - (void)parserFoundArrayStart:(SBJsonStreamParser*)parser;
@H_826_502@17
@H_826_502@18 //当array对象结束时调用
@H_826_502@19 - (void)parserFoundArrayEnd:(SBJsonStreamParser*)parser;
@H_826_502@20
@H_826_502@21 //当找到boolean值时调用
@H_826_502@22 - (void)parser:(SBJsonStreamParser*)parser foundBoolean:(BOOL)x;
@H_826_502@23
@H_826_502@24 //当找到null时调用
@H_826_502@25 - (void)parserFoundNull:(SBJsonStreamParser*)parser;
@H_826_502@26
@H_826_502@27 //当找到number时调用
@H_826_502@28 - (void)parser:(SBJsonStreamParser*)parser foundNumber:(NSNumber*)num;
@H_826_502@29
@H_826_502@30 //当找到字符串对象时调用
@H_826_502@31 - (void)parser:(SBJsonStreamParser*)parser foundString:(NSString*)string;
@H_826_502@32
@H_826_502@33 @end
3.属性和声明的方法:
@H_826_502@ 1 /**
@H_826_502@ 2 @json数据流解析器
@H_826_502@ 3 把json数据流解析成NSArray或NSDictionary对象
@H_826_502@ 4 使用这个类,可以边下载边解析(在整个文件被全部下载之前进行解析)
@H_826_502@ 5 用这个类对磁盘上的大文件解析也有好处,不用全部加载到内存
@H_826_502@ 6 具体实现可查看SBJsonStreamParserAdapter类
@H_826_502@ 7 */
@H_826_502@ 8 @interface SBJsonStreamParser : NSObject {
@H_826_502@ 9 @private
@H_826_502@10 SBJsonTokeniser *tokeniser;
@H_826_502@11 }
@H_826_502@12
@H_826_502@13 @property (nonatomic,unsafe_unretained) SBJsonStreamParserState *state; // Private
@H_826_502@14 @property (nonatomic,strong) NSMutableArray *stateStack; // Private
@H_826_502@15
@H_826_502@16 /**
@H_826_502@17 是否用空格隔开多个文件
@H_826_502@18 当设置为YES,解析器就不会返回SBJsonStreamParserComplete
@H_826_502@19 默认为NO,一但返回SBJsonStreamParserComplete,解析器不会解析更多数据
@H_826_502@20 */
@H_826_502@21 @property BOOL supportMultipleDocuments;
@H_826_502@22
@H_826_502@23 /**
@H_826_502@24 @流解析代理对象
@H_826_502@25 通常是指SBJsonStreamParserAdapter
@H_826_502@26 也可以是实现了SBJsonStreamParserDelegate解析代理协议的任何对象
@H_826_502@27 */
@H_826_502@28 @property (unsafe_unretained) id<SBJsonStreamParserDelegate> delegate;
@H_826_502@29
@H_826_502@30 /**
@H_826_502@31 @最大递归深度,默认为32
@H_826_502@32 如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
@H_826_502@33 */
@H_826_502@34 @property NSUInteger maxDepth;
@H_826_502@35
@H_826_502@36 //保存BJsonStreamParserError后返回的错误信息
@H_826_502@37 @property (copy) NSString *error;
@H_826_502@38
@H_826_502@39 /**
@H_826_502@40 解析json数据
@H_826_502@41 参数是UTF8编码的json数据(NSData)
@H_826_502@42 返回一个枚举值,流解析状态:
@H_826_502@43 SBJsonStreamParserComplete表示:解析了全部数据
@H_826_502@44 SBJsonStreamParserWaitingForData表示:等待获得更多数据
@H_826_502@45 SBJsonStreamParserError表示:解析出错
@H_826_502@46 */
@H_826_502@47 - (SBJsonStreamParserStatus)parse:(NSData*)data;
@H_826_502@48
@H_826_502@49 @end
json流解析配置器
1.定义了一个枚举配置器类型:
@H_826_502@1 typedef enum {
@H_826_502@2 SBJsonStreamParserAdapterNone,@H_826_502@3 SBJsonStreamParserAdapterArray,@H_826_502@4 SBJsonStreamParserAdapterObject,@H_826_502@5 } SBJsonStreamParserAdapterType;
2.定义了一个json流解析配置器代理协议:
@H_826_502@ 1 /**
@H_826_502@ 2 @json流解析配置器代理协议
@H_826_502@ 3 从流解析配置器获得obj或array对象的代理
@H_826_502@ 4 由流解析叠加器SBJsonStreamParserAccumulator实现
@H_826_502@ 5 */
@H_826_502@ 6 @protocol SBJsonStreamParserAdapterDelegate
@H_826_502@ 7
@H_826_502@ 8 /**
@H_826_502@ 9 如果发现一个json数组,则调用此方法
@H_826_502@10 */
@H_826_502@11 - (void)parser:(SBJsonStreamParser*)parser foundArray:(NSArray*)array;
@H_826_502@12
@H_826_502@13 /**
@H_826_502@14 如果发现一个json对象,则调用此方法
@H_826_502@15 */
@H_826_502@16 - (void)parser:(SBJsonStreamParser*)parser foundObject:(NSDictionary*)dict;
@H_826_502@17
@H_826_502@18 @end
3.类定义和属性:
@H_826_502@ 1 @interface SBJsonStreamParserAdapter : NSObject <SBJsonStreamParserDelegate> {
@H_826_502@ 2 @private
@H_826_502@ 3 NSUInteger depth;
@H_826_502@ 4 NSMutableArray *array;
@H_826_502@ 5 NSMutableDictionary *dict;
@H_826_502@ 6 NSMutableArray *keyStack;
@H_826_502@ 7 NSMutableArray *stack;
@H_826_502@ 8
@H_826_502@ 9 SBJsonStreamParserAdapterType currentType;
@H_826_502@10 }
@H_826_502@11
@H_826_502@12 /**
@H_826_502@13 如何跳过多个层级
@H_826_502@14 当文件太大了或链接缓慢,此方法相当有用
@H_826_502@15 如果设置此为N,它会跳过外面的N层,为每个内层对象,直接调用-parser:foundArray:或-parser:foundObject:方法
@H_826_502@16 */
@H_826_502@17 @property NSUInteger levelsToSkip;
@H_826_502@18
@H_826_502@19 /**
@H_826_502@20 实现SBJsonStreamParserAdapterDelegate代理协议的对象
@H_826_502@21 */
@H_826_502@22 @property (unsafe_unretained) id<SBJsonStreamParserAdapterDelegate> delegate;
@H_826_502@23
@H_826_502@24 @end
/**
默认的委托,当一个文件完全解析,只会调用一个-parser:foundArray:方法或-parser:foundObject:的方法
如果设置SBJsonStreamParser的supportMultipleDocuments属性为YES,
就可以支持多个json顶级对象的解析
例子如下:
@code
SBJsonStreamParserAdapter *adapter = [[[SBJsonStreamParserAdapter alloc] init] autorelease];
adapter.delegate = self;
SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease];
parser.delegate = adapter;
parser.supportMultipleDocuments = YES;
// 注意:此输入包含多个顶级json对象
NSData *json = [@"[]{}[]{}" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data];
@endcode
self调用它的顺序如下:
@li -parser:foundArray:
@li -parser:foundObject:
@li -parser:foundArray:
@li -parser:foundObject:
下面是跳过第一个或多个封装对象:
@code
SBJsonStreamParserAdapter *adapter = [[[SBJsonStreamParserAdapter alloc] init] autorelease];
adapter.delegate = self;
adapter.levelsToSkip = 1;
SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease];
parser.delegate = adapter;
// 注意:此输入包含一个单一的顶级json对象
NSData *json = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data];
@endcode
*/
json流解析叠加器
@H_826_502@1 //实现了流解析配置代理协议
@H_826_502@2 @interface SBJsonStreamParserAccumulator : NSObject <SBJsonStreamParserAdapterDelegate>
@H_826_502@3
@H_826_502@4 //声明的value对象,表示解析完成后的objc对象
@H_826_502@5 @property (copy) id value;
@H_826_502@6
@H_826_502@7 @end
json流解析叠加器
@H_826_502@1 //实现了流解析配置代理协议
@H_826_502@2 @interface SBJsonStreamParserAccumulator : NSObject <SBJsonStreamParserAdapterDelegate>
@H_826_502@3
@H_826_502@4 //声明的value对象,表示解析完成后的objc对象
@H_826_502@5 @property (copy) id value;
@H_826_502@6
@H_826_502@7 @end
实现了配置代理协议SBJsonStreamParserAdapterDelegate的两个方法:
@H_826_502@ 1 /**
@H_826_502@ 2 返回NSArray或NSDictionary对象
@H_826_502@ 3 */
@H_826_502@ 4 - (void)parser:(SBJsonStreamParser*)parser foundArray:(NSArray *)array {
@H_826_502@ 5 value = array;
@H_826_502@ 6 }
@H_826_502@ 7
@H_826_502@ 8 - (void)parser:(SBJsonStreamParser*)parser foundObject:(NSDictionary *)dict {
@H_826_502@ 9 value = dict;
@H_826_502@10 }
来自:http://www.cnblogs.com/xiaodao/archive/2012/02/17/2355893.html 原文链接:https://www.f2er.com/json/290505.html