SBJson库

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript的一个子集。 JSON采用完全独立于语言的文本格式,数据交换容易。容易阅读和编写,同时也易于机器解析和生成。

Json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组2种结构,通过这两种结构可以表示各种复杂的结构   

1、对象:对象在js中表示为“{}”扩起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理 解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。   

2、数组:数组在js中是中括号“[]”扩起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。

在ISO开发中有很多第三方类库支持Json解析,这里介绍一下SBJson解析Json数据。SBJson文件来自GitHub,点击下载。将Classes 文件复制到工程中,任意添加一个Json数据即可。代码如下所示:


SBJson是一个开源的json库,结构如下:

结构主要分为:主头文件SBJson.h,一个对象类别扩展NSObject+SBJson.h,一个json解析包Parser,一个json编写包Writer

任何使用SBJson库的地方都要导入SBJson.h头文件

#import "SBJson.h" 

1.JSONObjective-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

truefalse转为 [NSNumber numberWithBool:YES][NSNumber numberWithBool:NO]

integer整数长度19位,表现为LongLong类型,[NSNumber numberWithLongLong:]

json允许大的离谱的数字,为避免任何精度损失,将其他复杂数变成NSDecimalNumber实例

2.Objective-CJSON,方法如下:

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]

一.NSObject+SBJson.h

1.把objc对象编码成json字符串

通过类别,为NSObject添加新方法:[NSObjectJSONRepresentation]

1 @interface NSObject (NSObject_SBJsonWriting)
2 /** 3  虽然定义成NSObject的类别,但仅对NSArray和NSDictionary有效
4  返回:已编码的json对象,或nil
5  */
6 - (NSString *)JSONRepresentation;
7 @end

2.json对象解析为objc对象

通过类别,为NSString添加新方法:[NSStringJSONValue]

1 @interface NSString (NSString_SBJsonParsing)
2 /**
3  返回:NSDictionary或NSArray对象,或nil
4  */
5 - (id)JSONValue;
6 @end

二.NSObject+SBJson.m

导入头文件

1 #import "NSObject+SBJson.h"
2 #import "SBJsonWriter.h"
3 #import "SBJsonParser.h"

1.通过json编写器SBJsonWriter,的stringWithObject: 方法,实现[NSObjectJSONRepresentation]编码逻辑

 1 @implementation NSObject (NSObject_SBJsonWriting)
 2 
 3 //objc2json
 4 - (NSString *)JSONRepresentation {
 5     SBJsonWriter *writer = [[SBJsonWriter alloc] init];    
 6     NSString *json = [writer stringWithObject:self];
 7     if (!json)
 8         NSLog(@"-JSONRepresentation failed. Error is: %@",writer.error);
 9     return json;
10 }
11 
12 @end

2.通过json解析器SBJsonParser,的objectWithString: 方法,实现[NSStringJSONValue]解析逻辑

 1 @implementation NSString (NSString_SBJsonParsing)
 2 
 3 //json2objc
 4 - (id)JSONValue {
 5     SBJsonParser *parser = [[SBJsonParser alloc] init];
 6     id repr = [parser objectWithString:self];
 7     if (!repr)
 8         NSLog(@"-JSONValue failed. Error is: %@",parser.error);
 9     return repr;
10 }
11 
12 @end

SBJsonWriter:json编写器类

内部使用了json流编写器:SBJsonStreamWriter类,和json流编写累加器:SBJsonStreamWriterAccumulator类

主要有4个属性:

 1 /**
 2  @最大递归深度,默认为32
 3  如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
 4  可以通过设置maxDepth为0,来取消此安全功能
 5  */
 6 @property NSUInteger maxDepth;
 7 
 8 /**
 9  @返回一个出错信息,如果没错误,返回为nil
10  */
11 @property (readonly,copy) NSString *error;
12 
13 /**
14  @是否为人类可读的json
15  默认为NO,产生的json没有任何空白
16  如果设为YES,换行后,每个数组值和字典键/值对缩进两个空格
17  */
18 @property BOOL humanReadable;
19 
20 /**
21  @输出时字典键是否排序
22  默认为NO,如果设为YES,排序json输出的字典键
23  如果你需要比较两个结构时候很有用
24  */
25 @property BOOL sortKeys;

注意:上面的error属性为只读的(readonly)

属性实现在SBJsonWriter.m文件中:

1 @synthesize sortKeys;
2 @synthesize humanReadable;
3 @synthesize error;
4 @synthesize maxDepth;

其中error通过类别声明为私有可写,如下:

1 @interface SBJsonWriter ()
2 @property (copy) NSString *error;
3 @end

此类有3个转json表述的方法:

 1 /**
 2  @objc转成NSString
 3  返回给定objc对象的json表示
 4  返回一个字符串,或nil
 5  如果返回nil,则SBJsonWriter的error属性不为空,可以通过error的信息知道出错原因
 6  其中的参数value,是任何可以用json表述的对象
 7  */
 8 - (NSString*)stringWithObject:(id)value;
 9 
10 /**
11  @objc转成NSData
12  返回给定objc对象的json表示,用UTF8编码
13  返回一个NSData对象,或nil
14  */
15 - (NSData*)dataWithObject:(id)value;
16 
17 /**
18  @返回给定objc对象的json表示(或片段)
19  返回字符串,或nil
20  */
21 - (NSString*)stringWithObject:(id)value
22                            error:(NSError**)error;


三个方法的具体实现在SBJsonWriter.m文件中

 1 //把objc转成NSData,再通过UTF8编码把NSData转成字符串
 2 - (NSString*)stringWithObject:(id)value {
 3     NSData *data = [self dataWithObject:value];
 4     if (data)
 5         return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
 6     return nil;
 7 }    
 8 
 9 - (NSString*)stringWithObject:(id)value error:(NSError**)error_ {
10     NSString *tmp = [self stringWithObject:value];
11     if (tmp)
12         return tmp;
13     
14     if (error_) {
15         NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error,NSLocalizedDescriptionKey,nil];
16         *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonWriter.ErrorDomain" code:0 userInfo:ui];
17     }
18     
19     return nil;
20 }
21 
22 /**
23  初始化一个json流编写器,设置参数
24  初始化一个json流编写叠加器,把它设为SBJsonStreamWriter的代理(delegate)
25  把ojbc对象转变为NSData,通过调用SBJsonStreamWriter的writeObject:方法,或writeArray:方法,
26  或递归调用dataWithObject:方法,参数为[object proxyForJson]返回的代理对象
27  其中SBJsonStreamWriter的各种write方法,是把基本数据写成二进制bytes
28  然后通过叠加器SBJsonStreamWriterAccumulator,把二进制bytes拼装成NSData对象
29  返回叠加器的data属性变量
30  */
31 - (NSData*)dataWithObject:(id)object {    
32     self.error = nil;
33 
34     SBJsonStreamWriterAccumulator *accumulator = [[SBJsonStreamWriterAccumulator alloc] init];
35     
36     SBJsonStreamWriter *streamWriter = [[SBJsonStreamWriter alloc] init];
37     streamWriter.sortKeys = self.sortKeys;
38     streamWriter.maxDepth = self.maxDepth;
39     streamWriter.humanReadable = self.humanReadable;
40     streamWriter.delegate = accumulator;
41     
42     BOOL ok = NO;
43     if ([object isKindOfClass:[NSDictionary class]])
44         ok = [streamWriter writeObject:object];
45     
46     else if ([object isKindOfClass:[NSArray class]])
47         ok = [streamWriter writeArray:object];
48         
49     else if ([object respondsToSelector:@selector(proxyForJson)])
50         return [self dataWithObject:[object proxyForJson]];
51     else {
52         self.error = @"Not valid type for JSON";
53         return nil;
54     }
55     
56     if (ok)
57         return accumulator.data;
58     
59     self.error = streamWriter.error;
60     return nil;    
61 }


json流编写器

允许传入一个消息流对象,把它写入到SBJsonStreamWriterAccumulatordata.

1.里面含有个新的NSObject类别,把objc对象转成json允许的对象类型

 1 @interface NSObject (SBProxyForJson)
 2 
 3 /**
 4  json只支持NSArray和NSDictionary等类型
 5  所以转换之前先把特定objc对象转成这两种类型的形式
 6  如果你有一个自定义类,要把它转成json,需要实现该方法
 7  例子如下:
 8  @code
 9  - (id)proxyForJson {
10  return [NSDictionary dictionaryWithObjectsAndKeys:
11  name,@"name",12  phone,@"phone",13  email,@"email",14  nil];
15  }
16  @endcode
17  */
18 
19 - (id)proxyForJson;
20 
21 @end

2.里面定义了个json流编写器代理协议:

1 //在json流编写叠加器SBJsonStreamWriterAccumulator里实现
2 @protocol SBJsonStreamWriterDelegate
3 
4 - (void)writer:(SBJsonStreamWriter*)writer appendBytes:(const void *)bytes length:(NSUInteger)length;
5 
6 @end

3.定义了一个私有属性:

NSMutableDictionary *cache;

4.定义了7个公有属性:

 1 @property (nonatomic,unsafe_unretained) SBJsonStreamWriterState *state; // Internal
 2 @property (nonatomic,readonly,strong) NSMutableArray *stateStack; // Internal 
 3 
 4 //json输出流的代理
 5 @property (unsafe_unretained) id<SBJsonStreamWriterDelegate> delegate;
 6 
 7 /**
 8  @最大递归深度,默认为512.
 9  如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
10  可以通过设置maxDepth为0,来取消此安全功能
11  */
12 @property NSUInteger maxDepth;
13 
14 /**
15  @是否为人类可读的json
16  默认为NO,产生的json没有任何空白
17  如果设为YES,换行后,每个数组值和字典键/值对缩进两个空格
18  */
19 @property BOOL humanReadable;
20 
21 /**
22  @输出时字典键是否排序
23  默认为NO,如果设为YES,排序json输出的字典键
24  如果你需要比较两个结构时候很有用
25  */
26 @property BOOL sortKeys;
27 
28 /**
29  @返回一个出错信息,如果没错误,返回为nil
30  */
31 @property (copy) NSString *error;

5.定义了10个公有方法:

 1 /**
 2  把NSDictionary对象写到JSON输出流
 3  返回YES,表示成功
 4  */
 5 - (BOOL)writeObject:(NSDictionary*)dict;
 6 
 7 /**
 8  把NSArray对象写入JSON输出流
 9  返回YES,表示成功
10  */
11 - (BOOL)writeArray:(NSArray *)array;
12 
13 /**
14  开始写一个obj对象到JSON输出流
15  返回YES,表示成功
16  */
17 - (BOOL)writeObjectOpen;
18 
19 /**
20  结束写obj对象到JSON输出流
21  返回YES,表示成功
22 */
23 - (BOOL)writeObjectClose;
24 
25 /**
26  开始写一个Array对象到JSON输出流
27  返回YES,表示成功
28  */
29 - (BOOL)writeArrayOpen;
30 
31 /**
32  结束写Array对象到JSON输出流
33  返回YES,表示成功
34  */
35 - (BOOL)writeArrayClose;
36 
37 /**
38  把null对象写入JSON输出流
39  返回YES,表示成功
40  */
41 - (BOOL)writeNull;
42 
43 /**
44  把boolean对象写入JSON输出流
45  返回YES,表示成功
46  */
47 - (BOOL)writeBool:(BOOL)x;
48 
49 /**
50  把Number对象写入JSON输出流
51  返回YES,表示成功
52  */
53 - (BOOL)writeNumber:(NSNumber*)n;
54 
55 /**
56  把String对象写入JSON输出流
57  返回YES,表示成功
58  */
59 - (BOOL)writeString:(NSString*)s;

6.有个类别,定义了两个私有方法:

1 @interface SBJsonStreamWriter (Private)
2 - (BOOL)writeValue:(id)v;
3 - (void)appendBytes:(const void *)bytes length:(NSUInteger)length;
4 @end


json流编写叠加器,拥有个可变data对象

1 @interface SBJsonStreamWriterAccumulator : NSObject <SBJsonStreamWriterDelegate>
2 
3 @property (readonly,copy) NSMutableData* data;
4 
5 @end

具体实现:

 1 @implementation SBJsonStreamWriterAccumulator
 2 
 3 @synthesize data;
 4 
 5 - (id)init {
 6     self = [super init];
 7     if (self) {
 8         data = [[NSMutableData alloc] initWithCapacity:8096u];
 9     }
10     return self;
11 }
12 
13 
14 #pragma mark SBJsonStreamWriterDelegate
15 
16 //实现SBJsonStreamWriterDelegate协议,把二进制数据添加到data
17 
18 - (void)writer:(SBJsonStreamWriter *)writer appendBytes:(const void *)bytes length:(NSUInteger)length {
19     [data appendBytes:bytes length:length];
20 }
21 
22 @end

json解析器

 1 /**
 2  json转objc
 3  解析json字符串和NSData对象
 4  内部使用了SBJsonStreamParser类
 5  */
 6 
 7 @interface SBJsonParser : NSObject
 8 
 9 /**
10  @最大递归深度,默认为32
11  如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
12  可以通过设置maxDepth为0,来取消此安全功能
13  */
14 @property NSUInteger maxDepth;
15 
16 /**
17  @返回一个出错信息,如果没错误,返回为nil
18  */
19 @property(copy) NSString *error;
20 
21 /**
22  json转objc
23  @返回给定的NSData所代表的对象
24  参数data必须为UTF8编码
25  返回NSArray或NSDictionary对象,如果返回nil,表示出现错误
26  */
27 - (id)objectWithData:(NSData*)data;
28 
29 /**
30  json转objc
31  @返回给定字符串所代表的对象
32  此方法内部实现是:把参数用UTF8编码成NSData,然后调用objectWithData:方法,转成NSArray或NSDictionary,或nil
33  */
34 - (id)objectWithString:(NSString *)repr;
35 
36 /**
37  json转objc
38  @返回给定字符串所代表的对象
39  */
40 
41 - (id)objectWithString:(NSString*)jsonText
42                  error:(NSError**)error;
43 
44 @end

实现在SBJsonParser.m文件中:

 1 #import "SBJsonParser.h"
 2 #import "SBJsonStreamParser.h"
 3 #import "SBJsonStreamParserAdapter.h"
 4 #import "SBJsonStreamParserAccumulator.h"
 5 
 6 @implementation SBJsonParser
 7 
 8 @synthesize maxDepth;
 9 @synthesize error;
10 
11 - (id)init {
12     self = [super init];
13     if (self)
14         self.maxDepth = 32u;
15     return self;
16 }
17 
18 #pragma mark Methods
19 
20 /**
21  调用流解析器SBJsonStreamParser的parse:方法,把NSData转成NSArray或NSDictionary对象
22  */
23 - (id)objectWithData:(NSData *)data {
24 
25     if (!data) {
26         self.error = @"Input was 'nil'";
27         return nil;
28     }
29 
30     //初始化一个json流解析叠加器
31     SBJsonStreamParserAccumulator *accumulator = [[SBJsonStreamParserAccumulator alloc] init];
32     
33     //初始化一个json流解析配置器
34     SBJsonStreamParserAdapter *adapter = [[SBJsonStreamParserAdapter alloc] init];
35     //把叠加器设为配置器的代理(delegate)
36     adapter.delegate = accumulator;
37     
38     //初始化一个json流解析器,设置参数
39     SBJsonStreamParser *parser = [[SBJsonStreamParser alloc] init];
40     parser.maxDepth = self.maxDepth;
41     //把配置器设为解析器的代理(delegate)
42     parser.delegate = adapter;
43     
44     switch ([parser parse:data]) {
45         case SBJsonStreamParserComplete:
46             return accumulator.value;
47             break;
48             
49         case SBJsonStreamParserWaitingForData:
50             self.error = @"Unexpected end of input";
51             break;
52 
53         case SBJsonStreamParserError:
54             self.error = parser.error;
55             break;
56     }
57     
58     return nil;
59 }
60 
61 //NSString用UTF8编码成NSData,再把NSData转成NSArray或NSDictionary对象
62 - (id)objectWithString:(NSString *)repr {
63     return [self objectWithData:[repr dataUsingEncoding:NSUTF8StringEncoding]];
64 }
65 
66 - (id)objectWithString:(NSString*)repr error:(NSError**)error_ {
67     id tmp = [self objectWithString:repr];
68     if (tmp)
69         return tmp;
70     
71     if (error_) {
72         NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error,nil];
73         *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonParser.ErrorDomain" code:0 userInfo:ui];
74     }
75     
76     return nil;
77 }
78 
79 @end


json数据流解析器

1.定义了一个枚举值表示解析状态:

1 typedef enum {
2     SBJsonStreamParserComplete,3     SBJsonStreamParserWaitingForData,4     SBJsonStreamParserError,5 } SBJsonStreamParserStatus;

2.定义了一个json流解析代理协议:

 1 /**
 2  由SBJsonStreamParserAdapter类实现
 3  */
 4 @protocol SBJsonStreamParserDelegate
 5 
 6 //当找到obj时调用
 7 - (void)parserFoundObjectStart:(SBJsonStreamParser*)parser;
 8 
 9 //当找到obj对象key时调用
10 - (void)parser:(SBJsonStreamParser*)parser foundObjectKey:(NSString*)key;
11 
12 //当obj结束时调用
13 - (void)parserFoundObjectEnd:(SBJsonStreamParser*)parser;
14 
15 //当找到array对象时调用
16 - (void)parserFoundArrayStart:(SBJsonStreamParser*)parser;
17 
18 //当array对象结束时调用
19 - (void)parserFoundArrayEnd:(SBJsonStreamParser*)parser;
20 
21 //当找到boolean值时调用
22 - (void)parser:(SBJsonStreamParser*)parser foundBoolean:(BOOL)x;
23 
24 //当找到null时调用
25 - (void)parserFoundNull:(SBJsonStreamParser*)parser;
26 
27 //当找到number时调用
28 - (void)parser:(SBJsonStreamParser*)parser foundNumber:(NSNumber*)num;
29 
30 //当找到字符串对象时调用
31 - (void)parser:(SBJsonStreamParser*)parser foundString:(NSString*)string;
32 
33 @end

3.属性和声明的方法:

 1 /**
 2  @json数据流解析器
 3  把json数据流解析成NSArray或NSDictionary对象
 4  使用这个类,可以边下载边解析(在整个文件被全部下载之前进行解析)
 5  用这个类对磁盘上的大文件解析也有好处,不用全部加载到内存
 6  具体实现可查看SBJsonStreamParserAdapter类
 7  */
 8 @interface SBJsonStreamParser : NSObject {
 9 @private
10     SBJsonTokeniser *tokeniser;
11 }
12 
13 @property (nonatomic,unsafe_unretained) SBJsonStreamParserState *state; // Private
14 @property (nonatomic,strong) NSMutableArray *stateStack; // Private
15 
16 /**
17  是否用空格隔开多个文件
18  当设置为YES,解析器就不会返回SBJsonStreamParserComplete
19  默认为NO,一但返回SBJsonStreamParserComplete,解析器不会解析更多数据
20  */
21 @property BOOL supportMultipleDocuments;
22 
23 /**
24  @流解析代理对象
25  通常是指SBJsonStreamParserAdapter
26  也可以是实现了SBJsonStreamParserDelegate解析代理协议的任何对象
27  */
28 @property (unsafe_unretained) id<SBJsonStreamParserDelegate> delegate;
29 
30 /**
31  @最大递归深度,默认为32
32  如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
33  */
34 @property NSUInteger maxDepth;
35 
36 //保存BJsonStreamParserError后返回的错误信息
37 @property (copy) NSString *error;
38 
39 /**
40  解析json数据
41  参数是UTF8编码的json数据(NSData)
42  返回一个枚举值,流解析状态:
43  SBJsonStreamParserComplete表示:解析了全部数据
44  SBJsonStreamParserWaitingForData表示:等待获得更多数据
45  SBJsonStreamParserError表示:解析出错
46  */
47 - (SBJsonStreamParserStatus)parse:(NSData*)data;
48 
49 @end

json流解析配置器

1.定义了一个枚举配置器类型:

1 typedef enum {
2     SBJsonStreamParserAdapterNone,3     SBJsonStreamParserAdapterArray,4     SBJsonStreamParserAdapterObject,5 } SBJsonStreamParserAdapterType;

2.定义了一个json流解析配置器代理协议:

 1 /**
 2  @json流解析配置器代理协议
 3  从流解析配置器获得obj或array对象的代理
 4  由流解析叠加器SBJsonStreamParserAccumulator实现
 5  */
 6 @protocol SBJsonStreamParserAdapterDelegate
 7 
 8 /**
 9  如果发现一个json数组,则调用此方法
10  */
11 - (void)parser:(SBJsonStreamParser*)parser foundArray:(NSArray*)array;
12 
13 /**
14  如果发现一个json对象,则调用此方法
15  */
16 - (void)parser:(SBJsonStreamParser*)parser foundObject:(NSDictionary*)dict;
17 
18 @end

3.类定义和属性:

 1 @interface SBJsonStreamParserAdapter : NSObject <SBJsonStreamParserDelegate> {
 2 @private
 3     NSUInteger depth;
 4     NSMutableArray *array;
 5     NSMutableDictionary *dict;
 6     NSMutableArray *keyStack;
 7     NSMutableArray *stack;
 8     
 9     SBJsonStreamParserAdapterType currentType;
10 }
11 
12 /**
13  如何跳过多个层级
14  当文件太大了或链接缓慢,此方法相当有用
15  如果设置此为N,它会跳过外面的N层,为每个内层对象,直接调用-parser:foundArray:或-parser:foundObject:方法
16  */
17 @property NSUInteger levelsToSkip;
18 
19 /**
20  实现SBJsonStreamParserAdapterDelegate代理协议的对象
21  */
22 @property (unsafe_unretained) id<SBJsonStreamParserAdapterDelegate> delegate;
23 
24 @end

/**

默认的委托,当一个文件完全解析,只会调用一个-parser:foundArray:方法或-parser:foundObject:的方法

如果设置SBJsonStreamParsersupportMultipleDocuments属性为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流解析叠加器

1 //实现了流解析配置代理协议
2 @interface SBJsonStreamParserAccumulator : NSObject <SBJsonStreamParserAdapterDelegate>
3 
4 //声明的value对象,表示解析完成后的objc对象
5 @property (copy) id value;
6 
7 @end

json流解析叠加器

1 //实现了流解析配置代理协议
2 @interface SBJsonStreamParserAccumulator : NSObject <SBJsonStreamParserAdapterDelegate>
3 
4 //声明的value对象,表示解析完成后的objc对象
5 @property (copy) id value;
6 
7 @end

实现了配置代理协议SBJsonStreamParserAdapterDelegate的两个方法:

 1 /**
 2  返回NSArray或NSDictionary对象
 3  */
 4 - (void)parser:(SBJsonStreamParser*)parser foundArray:(NSArray *)array {
 5     value = array;
 6 }
 7 
 8 - (void)parser:(SBJsonStreamParser*)parser foundObject:(NSDictionary *)dict {
 9     value = dict;
10 }
来自:http://www.cnblogs.com/xiaodao/archive/2012/02/17/2355893.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读2.4k次。最近要优化cesium里的热力图效果,浏览了网络上的各种方法,发现大多是贴在影像上的。这么做好是好,但是会被自生添加的模型或者其他数据给遮盖。其次是网上的方法大多数是截取成一个矩形。不能自定义的截取自己所需要的。经过尝试,决定修改下cesium heatmap,让他达到我们需要的要求。首先先下载 cesium heatmap包。其中我们可以看到也是通过叠加entity达到添加canvas的方法绘制到地图上。我们先把这一段代码注释} else {} };
文章浏览阅读1.2w次,点赞3次,收藏19次。在 Python中读取 json文件也可以使用 sort ()函数,在这里我介绍一个简单的示例程序: (4)如果我们想将字符串转换为列表形式,只需要添加一个变量来存储需要转换的字符串即可。在上面的代码中,我们创建了一个名为` read`的对象,然后在文件的开头使用`./`关键字来命名该对象,并在文件中定义了一个名为` json`的变量,并在其中定义了一个名为` json`的字段。比如,我们可以使用 read方法读取 json文件中的内容,然后使用 send方法将其发送到 json文件中。_python怎么读取json文件
文章浏览阅读1.4k次。首字母缩略词 API 代表应用程序编程接口,它是一种设备,例如用于使用编程代码发送和检索数据的服务器。最常见的是,该技术用于从源检索数据并将其显示给软件应用程序及其用户。当您访问网页时,API 的工作方式与浏览器相同,信息请求会发送到服务器,如何在 Windows PC 中手动创建系统还原点服务器会做出响应。唯一的区别是服务器响应的数据类型,对于 API,数据是 JSON 类型。JSON 代表 JavaScript Object Notation,它是大多数软件语言中 API 的标准数据表示法。_api是什么 python
文章浏览阅读802次,点赞10次,收藏10次。解决一个JSON反序列化问题-空字符串变为空集合_cannot coerce empty string ("") to element of `java.util.arraylist
文章浏览阅读882次。Unity Json和Xml的序列化和反序列化_unity json反序列化存储换行
文章浏览阅读796次。reader.readAsText(data.file)中data.file的数据格式为。使用FileReader对象读取文件内容,最后将文件内容进行处理使用。_a-upload 同时支持文件和文件夹
文章浏览阅读775次,点赞19次,收藏10次。fastjson是由国内的阿里推出的一种json处理器,由java语言编写,无依赖,不需要引用额外的jar包,能直接运行在jdk环境中,它的解析速度是非常之快的,目前超过了所有json库。提示:以下是引用fastjson的方法,数据未涉及到私密信息。_解析器用fastjson还是jackson
文章浏览阅读940次。【Qt之JSON文件】QJsonDocument、QJsonObject、QJsonArray等类介绍及使用_使用什么方法检查qjsondocument是否为空
文章浏览阅读957次,点赞34次,收藏22次。主要内容原生 ajax重点重点JSON熟悉章节目标掌握原生 ajax掌握jQuery ajax掌握JSON第一节 ajax1. 什么是ajaxAJAX 全称为,表示异步的Java脚本和Xml文件,是一种异步刷新技术。2. 为什么要使用ajaxServlet进行网页的变更往往是通过请求转发或者是重定向来完成,这样的操作更新的是整个网页,如果我们只需要更新网页的局部内容,就需要使用到AJAX来处理了。因为只是更新局部内容,因此,Servlet。
文章浏览阅读1.4k次,点赞45次,收藏13次。主要介绍了JsonFormat与@DateTimeFormat注解实例解析,文中通过示例代码介绍的非常详细,对大家的学习 或者工作具有一定的参考学习价值,需要的朋友可以参考下 这篇文章主要介绍了从数据库获取时间传到前端进行展示的时候,我们有时候可能无法得到一个满意的时间格式的时间日期,在数据库中显 示的是正确的时间格式,获取出来却变成了时间戳,@JsonFormat注解很好的解决了这个问题,我们通过使用 @JsonFormat可以很好的解决:后台到前台时间格式保持一致的问题,
文章浏览阅读1k次。JsonDeserialize:json反序列化注解,作用于setter()方法,将json数据反序列化为java对象。可以理解为用在处理接收的数据上。_jsondeserialize
文章浏览阅读2.7k次。labelme标注的json文件是在数据标注时产生,不能直接应用于模型训练。各大目标检测训练平台或项目框架均有自己的数据格式要求,通常为voc、coco或yolo格式。由于yolov8项目比较火热,故此本博文详细介绍将json格式标注转化为yolo格式的过程及其代码。_labelme json 转 yolo
文章浏览阅读790次,点赞26次,收藏6次。GROUP_CONCAT_UNORDERED(): 与GROUP_CONCAT类似,但不保证结果的顺序。COUNT_DISTINCT_AND_ORDERED(): 计算指定列的不同值的数量,并保持结果的顺序。COUNT_ALL_DISTINCT(): 计算指定列的所有不同值的数量(包括NULL)。AVG_RANGE(): 计算指定列的最大值和最小值之间的差异的平均值。JSON_OBJECT(): 将结果集中的行转换为JSON对象。COUNT_DISTINCT(): 计算指定列的不同值的数量。_mysql json 聚合
文章浏览阅读1.2k次。ajax同步与异步,json-serve的安装与使用,node.js的下载_json-serve 与node版本
文章浏览阅读1.7k次。`.net core`提供了Json处理模块,在命名空间`System.Text.Json`中,下面通过顶级语句,对C#的Json功能进行讲解。_c# json
文章浏览阅读2.8k次。主要介绍了python对于json文件的读写操作内容_python读取json文件
文章浏览阅读770次。然而,有时候在处理包含中文字符的Json数据时会出现乱码的情况。本文将介绍一种解决Json中文乱码问题的常见方法,并提供相应的源代码和描述。而某些情况下,中文字符可能会被错误地编码或解码,导致乱码的出现。通过适当地控制编码和解码过程,我们可以有效地处理包含中文字符的Json数据,避免乱码的发生。通过控制编码和解码过程,我们可以确保Json数据中的中文字符能够正确地传输和解析。为了解决这个问题,我们可以使用C#的System.Text.Encoding类提供的方法进行编码和解码的控制。_c# json 中文编码
文章浏览阅读997次。【代码】【工具】XML和JSON互相转换。_xml 转json
文章浏览阅读1.1k次。json path 提取数据_jsonpath数组取值
文章浏览阅读3w次,点赞35次,收藏36次。本文主要介绍了pandas read_json时ValueError: Expected object or value的解决方案,希望能对学习python的同学们有所帮助。文章目录1. 问题描述2. 解决方案_valueerror: expected object or value