Sbjson教程

So the previouspost focussed on retrieving data from awebservice – namely Google’s Local Search.

This post will focus on parsing the JSON returned from thewebservice.

My personal choice for parsing JSON isthe SBJON library.There are others out there such as TouchJSON and YAJL socheck them put and decide for yourself.

Let’s start with a quick recap on what JSON is and how it can beused.

Wikipedia says:

JSON (an acronym forJavaScript Object Notation) is a lightweight text-based openstandard designed for human-readable data interchange. It isderived from the JavaScript programming language for representingsimple data structures and associative arrays, called objects.Despite its relationship to JavaScript, it is language-independent,with parsers available for virtually every programminglanguage.

JSON presents its data as key-value pairs. Each value is referencedby a key name, which is a string. If you were to represent a personin JSON, their name would be referenced by the key “name” like so:“name” : “James”.

So, JSON represents data in a way that can be passed betweenapplications easily. Perfect.

So when parsing data from a webservice, the first thing you shoulddo is figure out your model. Look at an example of the webservice’sresponse and figure out which bits represent objects, arrays ofobjects, fields that belong to an object, etc.

But what kinds of data can JSON represent?

Objects are everythingbetween the braces ( { } ).
Strings are enclosed in quotes.
Numbers aren’t enclosed by anything and just appear as numbers,e.g. 12345.
Arrays are enclosed in square brackets ( [ ] ).
Booleans take the form of the words ‘true’ or ‘false’ (withoutquotes).
Null values are represented as ‘null’ (without quotes).

So an example of JSON using all these data types:

{
     "firstName": "John",
     "lastName": "Smith",
     "age": 25,
     "address": 
     {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": "10021"
     },
     "phoneNumber": 
     [
         {
           "type": "home",
           "number": "212 555-1234"
         },
         {
           "type": "fax",
           "number": "646 555-4567"
         }
     ]
 }

And it’s representation in Objective-C:

#import 
 
@interface Person : NSObject
{
    NSString *firstName;
    NSString *lastName;
 
    NSInteger age;
 
    NSDictionary *address;
 
    NSArray *phoneNumbers;
}
 
@end

You may think we’ve missed out some information, such as thedetails of the address, and phone numbers. It’s you decision howyou model your objects. I’ve chosen to store the address details ina dictionary, each value being referenced by a key name, just as itis in JSON. The phone numbers also stored in dictionaries, but thenthose dictionaries put into an array.

If you wanted to, you could create another Class named Address anduse it to store the address details. This may be a moreobject-oriented approach and useful if addresses are used in otherplaces throughout your application without needing to be tied to aPerson.

So now that you have your object model, you need to get the dataout of the JSON and create instances of your model.

SBJSON has a useful SBJsonParser class that can parse an entireJSON object in one line:

SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
NSError *error = nil;
NSArray *jsonObjects = [jsonParser objectWithString:jsonString error:&error];
[jsonParser release], jsonParser = nil;

SBJSON treats JSON objects as dictionaries in Objective-C.Depending on the webservice you may get a JSON object as the toplevel object or you may get an array. For this reason,objectWithString:error: has id asit’s return type. You can use Objective-C’s dynamism to determinewhich type of data store the parser as returned, like this:

id jsonObject = [jsonParser objectWithString:jsonString error:&error];
 
if ([jsonObject isKindOfClass:[NSDictionary class]])
    // treat as a dictionary, or reassign to a dictionary ivar
else if ([jsonObject isKindOfClass:[NSArray class]])
    // treat as an array or reassign to an array ivar.

If the webservice only ever returns one of the two representationsas it’s top level then you can go ahead and assume it will beeither an Array or Dictionary, and not have to worry aboutchecking.

Now you have your JSON data in a format that you can manage viaObjective-C. All you need to do now is iterate over the contents ofthe dictionary/array and create instances of Person to representthem.

One thing that’s important to remember is that literal numbers suchas the age value in our Person example will be wrapped in NSNumberobjects, so we’ll need to call ‘intValue’ on them to get thenumber.

NSMutableArrary *people = [NSMutableArray array];
 
for (NSDictionary *dict in jsonObjects)
{
    Person *newPerson = [[[Person alloc] init] autorelease];
    [newPerson setFirstName:[dict objectForKey:@"firstName"]];
    [newPerson setLastName:[dict objectForKey:@"lastName"]];
    [newPerson setAge:[[dict objectForKey:@"age"] intValue]];
    [newPerson setAddress:[dict objectForKey:@"address"]];
    [newPerson setPhoneNumbers:[dict objectForKey:@"phoneNumber"]];
 
    [people addObject:newPerson];
}

And there we have it.

One final thing to take note of. You’ll notice that I used literalstrings as key names while creating the Person objects. It might bebetter for you to determine each key name that you’ll be using andcreate a string constant for them. That way, when you’re parsingyour data, if you misspell firstName, the compiler can throw anerror (because it won’t match the name of the constant you created)and save you a lot of time debugging when, for some damn reason,you’re not getting any value for @”firtName”!


附:

 

From JSON String to Objects:

SBJsonParser *parser = [[SBJsonParser alloc] init];

// gives array as output

id objectArray = [parser objectWithString:@"[1,2,3]"]; 

// gives dictionary as output

id objectDictionary = [parser objectWithString:@"{\"name\":\"xyz\",\"email\":\"xyz@email.com\"}"]; 

From Objects to JSON String:

SBJsonWriter *writer = [[SBJsonWriter alloc] init];

id *objectArray = [NSArray arrayWithObjects:@"Hello",@"World", nil];

// Pass an Array or Dictionary object.

id *jsonString = [writer stringWithObject:objectArray]; 


注:SBjson要求开启arc,方法:
targets-->build phased->Compile Sources ->双击输入-fobjc-arc
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值