JSONKit、Alamofire、AFNetworking这三个第三方库是工作中常用来解析j son数据,上传下载,获取URL地址里传过来的数据的工具,今天我来总结一下我在开发中是如何使用这三个工具进行json数据的解析。 对于cocoapods的使用和如何将第三方库加入自己的项目中,在此我不过多描述,这里我们只谈如何使用这三个第三方库进行json解析,后续的博客中我会写一个关于cocoapods的使用和如何加载第三方库的总结。 话不多说,切入正题。
对于第三方库的选择:如果公司要求支持iOS5.0以下版本,那选择JSONKit,如果要求支持iOS5.0以上版本,Swift用Alamofire,Object-C用AFNetworkin。
JSONKit
常用的方法有下面几个:
-(id)objectFromJSONString;
-(id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-(id)objectFromJSONData;
-(id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
看下列示例代码:
- (IBAction)btnPressJsonKit:(id)sender {
//如果json是“单层”的,即value都是字符串、数字,可以使用objectFromJSONString
NSString *json1 = @"{\"a\":123, \"b\":\"abc\"}";
NSLog(@"json1:%@",json1);
NSDictionary *data1 = [json1 objectFromJSONString];
NSLog(@"json1.a:%@",[data1 objectForKey:@"a"]);
NSLog(@"json1.b:%@",[data1 objectForKey:@"b"]);
//[json1 release];
//如果json有嵌套,即value里有array、object,如果再使用objectFromJSONString,程序可能会报错(测试结果表明:使用由网络或得到的php/json_encode生成的json时会报错,但使用NSString定义的json字符串时,解析成功),最好使用objectFromJSONStringWithParseOptions:
NSString *json2 = @"{\"a\":123, \"b\":\"abc\", \"c\":[456, \"hello\"], \"d\":{\"name\":\"张三\", \"age\":\"32\"}}";
NSLog(@"json2:%@", json2);
NSDictionary *data2 = [json2 objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
NSLog(@"json2.c:%@", [data2 objectForKey:@"c"]);
NSLog(@"json2.d:%@", [[data2 objectForKey:@"d"] objectForKey:@"name"]);
//[json2 release];
//NSArray *result = [_dict]
}
输出结果:
2016-10-06.。。。。。。。。。 json.c:(134,Hello)
2016-10-06。。。。。。。。。 json.d:张三
假如存在如下json数据:
{
"result":[
{
"meeting":{
"add": "203",
"creator":"张一",
"member":[
{
"name":"张二",
"age":"20"
}
{
"name":"张三",
"age":"30"
}
]
}
"meeting":{
"add": "204",
"creator":"张二",
"member":[
{
"name":"张四",
"age":"20"
}
{
"name":"张五",
"age":"30"
}
]
}
}
]
}
则json解析过程:
//json解析
//2. 解析数组型
NSArray *result = [_dict objectForKey:@"result"];
//3.
NSDictionary *dic = [result objectAtIndex:0];
//4.解析字典型
NSDictionary *meeting = [dic objectForKey:@"meeting"];
//得到add值 解析字符串型
NSString *address = [meeting objectForKey:@"add"];
//得到creator值
NSString *creator = [meeting objectForKey:@"creator"];
//得到member里面的数据,因为这个键值中有数组,所以要重复上面的2.3.4的操作
//2.
//NSArray *members = [meeting objectForKey:@"member"];
//3.
//这里用循环语句
for (NSDictionary * member in members){
//4.
NSString *name = [member objectForKey:@"name"];
NSString *age = [member objectForKey:@"age"];
}
/*
用法:
1.dictionary——>json
NSString *jsonstring = [dictionary JSONString];
2.json————>dictionary
NSDictionary *dictionary = [jsonstring objectFromJSONString];
*/
总结:
从以上可以体会到json解析的顺序
1.根据得到的字符串获取里面的键值对;
2.根据得到的键值对通过key来得到相应的值,也就是值里面的数组
3.然后获取数组中的键值对。
4.然后根据得到的键值对通过key获取里面的键值对的值。
Alamofire
下面来看一个实际开发过程中的例子:
接口: http://app.buuyou.com/api/app?type=userlogin&data=123456789@q.com,123
bejson解析:
{
"status": 1,
"recordnum": 1,
"msg": "OK",
"data": [
{
"Userid": 20039,
"GroupID": 3,
"UserRealName": "深海鱼",
"Email": "123456789@qq.com",
"BankACCount": "FISHBALL1",
"WebName": "baidu",
"WebUrl": "www.456.com",
}
]
}
准备工作:1.Alamofire导入项目;2.写一个HTTP.swift文件;3.写一个LIST.swift文件。
分析代码:
func GetDate(){
//下面两句代码是从缓存中取出用户登陆时输入的账号密码(入参)值
let Accountid = NSUserDefaults.standardUserDefaults()
let Account = Accountid.stringForKey("Account")
let Passwordid = NSUserDefaults.standardUserDefaults()
let Password = Passwordid.stringForKey("Password")
let url = apiUrl + "userlogin"//接口前缀+接口名
let param = [
"data":"\(Account!),\(Password!)"
]
Alamofire.request(.GET, url, parameters: param).response { request, response, json, error in
if(error != nil){
}
else{
print("request是")
print(request!)
print("====================")
let status = HTTP(JSONDecoder(json!))
print("状态是")
print(status.status)
if(status.status == 0){
let hud = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
hud.mode = MBProgressHUDMode.Text
hud.labelText = status.errorData
hud.margin = 10.0
hud.removeFromSuperViewOnHide = true
hud.hide(true, afterDelay: 1)
}
if(status.status == 1){
self.IndexSource = IndexList(status.data!)
self.tableSource.reloadData()
}
}
}
}
HTTP.swift文件里的内容:
import Foundation
class HttpY: JSONJoy{
var status:Int?
//数组类型的data
var data:JSONDecoder?
var errorData:String?
var uid:String?
init(){
}
required init(_ decoder:JSONDecoder){
status = decoder["status"].integer
if status == 1{
data = decoder["data"]
}else{
errorData = decoder["data"].string
}
}
}
LIST.swift文件里的内容
import Foundation
class IndexList: JSONJoy {
var objectlist: [IndexInfo]
var count: Int{
return self.objectlist.count
}
init(){
objectlist = Array<IndexInfo>()
}
required init(_ decoder: JSONDecoder) {
objectlist = Array<IndexInfo>()
for childs: JSONDecoder in decoder.array!{
objectlist.append(IndexInfo(childs))
}
}
func append(list: [IndexInfo]){
self.objectlist = list + self.objectlist
}
}
//IndexList IndexInfo
class IndexInfo: JSONJoy{
var UserRealName:String?
var WebName:Int?
init() {
}
required init(_ decoder: JSONDecoder){
UserRealName = decoder["UserRealName"].string
WebName = decoder["WebName"].integer
}
}
解析过程:
1.使用Alamofire里的request方法和response方法(Alamofire以后的版本里这里是responseJSON方法),request里的参数是:get或者post传输、url地址,这里会返回一个request对象。 response是做出响应,而这里面j son参数会返回一个json对象;
2.使用JSONDecoder来获取json对象里的键值对;其结果
"status": 1,
"recordnum": 1,
"msg": "OK",
"data": [
{}
]
3.再用HTTP.swift文件对status进行0/1判断
如果status == 1,则用decode来获取data的键值对,其结果
"data": [
{
"Userid": 20039,
"GroupID": 3,
"UserRealName": "深海鱼",
"Email": "123456789@qq.com",
"BankACCount": "FISHBALL1",
"WebName": "baidu",
"WebUrl": "www.456.com",
}
]
4.然后用LIST.swift文件里的IndexInfo,根据key名获取到值名。
"UserRealName": "深海鱼",
"WebName": "baidu",
AFNetworking
AFNetworking是对NSURLConnection和NSURLSession的封装,现在因为只有NSURLSession对http2.0支持,所以AFNetworking现在 只是一个完全基于NSURLSession 的API。 我对AFNetworking的研究和使用较少,所以现在我推荐一个比较好的讲解AFNetworking的博客地址供读者学习,http://www.jianshu.com/p/ab246881efa9。
在总结的过程中我发现我对Alamofire和AFNetworking的掌握已经落后现在当前的最新版本了(例如:Alamofire现在使用responseJSON,很少使用response;AFNetworking不再支持NSURLConnection,而转向仅支持苹果主推的NSURLSession),所以下一步有时间我会对这两个第三方库的最新版本做一个深入研究。 现在我还处在校招找工作阶段,比较忙,所以后续再做深入研究吧。 虽然现在ios找工作的行情不太好,但是机会总是留给有准备的人,不管什么行业,缺的永远是牛逼人物,不缺的永远是打酱油,虽然我也是渣渣一枚,但我从来没有听过谁因为学习而贫困潦倒,坚定+努力!