iOS开发使用JSON解析网络数据
程序员文章站
2023-11-22 08:36:16
前言:对服务器请求之后,返回给客户端的数据,一般都是json格式或者xml格式(文件下载除外)
本篇随便先讲解json解析。
正文:
关于json:
j...
前言:对服务器请求之后,返回给客户端的数据,一般都是json格式或者xml格式(文件下载除外)
本篇随便先讲解json解析。
正文:
关于json:
json是一种轻量级的数据格式,一般用于数据交互json的格式很像objective-c中的字典和数组:{"name":"jack","age":10}
补充:
标准的json格式的注意点:key必须用双引号。(但是在java中是单引号)
json-oc的转换对照表
其中:null--返回oc里的nsnull类型
使用:
在json解析方案有很多种,但是(苹果原生的)nsjsonserialization性能最好
反序列化(json --> oc对象),下面示例解析成字典对象
序列化(oc对象 --> json),注意字典的值不能传nil,但是可以传[nsnull null]
并不是所有的类型都是可以转为json的
以下是苹果官方规定:
我们再来看个实例:
#import "mainviewcontroller.h" #import "video.h" #define kbaseurl @"http://192.168.3.252/~apple" @interface mainviewcontroller () @property (strong, nonatomic) nsarray *datalist; @property (weak, nonatomic) uitableview *tableview; @end @implementation mainviewcontroller class="p1"> "412158" snippet_file_name="blog_20140630_1_3481337" name="code" class="objc"> #pragma mark 实例化视图 - (void)loadview { self.view = [[uiview alloc]initwithframe:[uiscreen mainscreen].applicationframe]; //1 tableview cgrect frame = self.view.bounds; uitableview *tableview = [[uitableview alloc]initwithframe:cgrectmake(0, 0, frame.size.width, frame.size.height - 44) style:uitableviewstyleplain]; //1)数据源 [tableview setdatasource:self]; //2)代理 [tableview setdelegate:self]; //)设置表格高度 [tableview setrowheight:80]; [self.view addsubview:tableview]; self.tableview = tableview; //toolbar uitoolbar *toolbar = [[uitoolbar alloc]initwithframe:cgrectmake(0, tableview.bounds.size.height, 320, 44)]; [self.view addsubview:toolbar]; //添加toolbar按钮 uibarbuttonitem *item1 = [[uibarbuttonitem alloc]initwithtitle:@"load json" style:uibarbuttonitemstyledone target:self action:@selector(loadjson)]; uibarbuttonitem *item2 = [[uibarbuttonitem alloc]initwithtitle:@"load xml" style:uibarbuttonitemstyledone target:self action:@selector(loadxml)]; uibarbuttonitem *item3 = [[uibarbuttonitem alloc]initwithbarbuttonsystemitem:uibarbuttonsystemitemflexiblespace target:nil action:nil]; [toolbar setitems:@[item3, item1, item3, item2, item3]]; } #pragma mark -uitableview数据源方法 对于uitableview下面这两个方法是必须实现的。 - (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section { return self.datalist.count; } //每填充一行都调用一次这个方法。知道界面上的所有行都填充完毕。, - (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { //使用可充用标示符查询可重用单元格 static nsstring *id = @"mycell"; uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:id]; if (cell == nil) { cell = [[uitableviewcell alloc]initwithstyle:uitableviewcellstylesubtitle reuseidentifier:id]; } //设置单元格内容 video *v = self.datalist[indexpath.row]; cell.textlabel.text = v.name; cell.detailtextlabel.text = v.teacher; //加载图片 //1)同步加载网络图片,同步方法以为这这些指令在完成之前,后续指令都无法执行。 //注意:在开发网络应用时,不要使用同步方法加载图片,否则会严重影响用户体验 // nsstring *imagepath = [nsstring stringwithformat:@"%@%@", kbaseurl, v.imageurl]; // nsurl *imageurl = [nsurl urlwithstring:imagepath]; // nsdata *imagedata = [nsdata datawithcontentsofurl:imageurl]; // uiimage *image = [uiimage imagewithdata:imagedata]; // // //2)异步加载网络图片 // //网络连接本身就有异步命令 sendasync // [cell.imageview setimage:image]; //如果缓存图像不存在 if (v.cacheimage == nil) { //使用默认图像占位,即能够保证有图像,又能够保证有地方。 uiimage *image = [uiimage imagenamed:@"user_default.png"]; [cell.imageview setimage:image]; //使用默认图像占位 //开启异步连接,加载图像,因为加载完成之后,需要刷新对应的表格航 [self loadimageasyncwithindexpath:indexpath]; }else { [cell.imageview setimage:v.cacheimage]; } //[self loadimageasyncwithurl:imageurl imageview:cell.imageview]; return cell; } #pragma mark 异步加载网络图片 //由于uitableview是可重用的,为了避免用户快速频繁刷新表格,造成数据冲突,不能直接将uiimageview传入异步方法 //正确的解决方法是:将表格行的indexpath传入异步方法,加载完成图像以后,直接刷新指定的行。 - (void)loadimageasyncwithindexpath:(nsindexpath *)indexpath { video *v = self.datalist[indexpath.row]; //取出当前要填充的行 nsstring *imagepath = [nsstring stringwithformat:@"%@%@", kbaseurl, v.imageurl]; nsurl *imageurl = [nsurl urlwithstring:imagepath]; //nslog(@"%@ %@", url, imageview); //1 request nsurlrequest *request = [nsurlrequest requestwithurl:imageurl]; //2 connection sendasync异步请求 [nsurlconnection sendasynchronousrequest:request queue:[nsoperationqueue mainqueue] completionhandler:^(nsurlresponse *response, nsdata *data, nserror *error) { //uiimage *image = [uiimage imagewithdata:data]; //[imageview setimage:image]; //将网络数据保存至缓存图像。 v.cacheimage = [uiimage imagewithdata:data]; //刷新表格 [self.tableview reloadrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationleft]; }]; } #pragma mark 处理json数据 - (void)handlerjsondata:(nsdata *)data { //json文件中的[]表示一个数据。 //反序列化json数据 //第二个参数是解析方式,一般用nsjsonreadingallowfragments nsarray *array = [nsjsonserialization jsonobjectwithdata:data options:nsjsonreadingallowfragments error:nil]; nslog(@"%@", array); //json解析以后是nsarray格式的数据。 //提示:如果开发网络应用,可以将反序列化出来的对象,保存至沙箱,以便后续开发使用。 nsarray *docs = nssearchpathfordirectoriesindomains(nsdocumentdirectory, nsuserdomainmask, yes); nsstring *path = [docs[0]stringbyappendingpathcomponent:@"json.plist"]; [array writetofile:path atomically:yes]; //把array里面的数据写入沙箱中的jspn.plist中。 //给数据列表赋值 nsmutablearray *arraym = [nsmutablearray array]; for (nsdictionary *dict in array) { video *video = [[video alloc]init]; //给video赋值 [video setvaluesforkeyswithdictionary:dict]; [arraym addobject:video]; } self.datalist = arraym; //刷新表格 [self.tableview reloaddata]; nslog(@"%@", arraym); //这句话将调用video里面的description和nsarray+log里面的descriptionwithlocale } #pragma mark 加载json - (void)loadjson { nslog(@"load json"); //从web服务器加载数据 nsstring *str = @"http://www.baidu.com?format=json"; //这里是乱写的 //提示:nsdata本身具有同步方法,但是在实际开发中,不要使用次方法 //在使用nsdata的同步方法时,无法指定超时时间,如果服务器连接不正常,会影响用户体验。 //nsdata *data = [nsdata datawithcontentsofurl:[nsurl urlwithstring:str]]; //简历nsurl nsurl *url = [nsurl urlwithstring:str]; //建立nsurlrequest nsurlrequest *request = [nsurlrequest requestwithurl:url cachepolicy:nsurlrequestuseprotocolcachepolicy timeoutinterval:2.0f]; //建立nsurlconnect的同步方法加载数据 nsurlresponse *response = nil; nserror *error = nil; //同步加载数据 nsdata *data = [nsurlconnection sendsynchronousrequest:request returningresponse:&response error:&error]; //错误处理 if (data != nil) { //下面这两句话本身没有什么意义,仅用于跟踪调试。 nsstring *result = [[nsstring alloc]initwithdata:data encoding:nsutf8stringencoding]; nslog(@"%@", result); //在处理网络数据的时候,不要将nsdata转换成nsstring。 [self handlerjsondata:data]; }else if (data == nil && error == nil){ nslog(@"空数据"); }else { nslog(@"%@", error.localizeddescription); } } #pragma mark 加载xml - (void)loadxml { nslog(@"load xml"); } //- (void)viewdidload //{ // [super viewdidload]; //} @end