欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS开发使用JSON解析网络数据

程序员文章站 2023-11-22 08:36:16
前言:对服务器请求之后,返回给客户端的数据,一般都是json格式或者xml格式(文件下载除外) 本篇随便先讲解json解析。 正文: 关于json: j...

前言:对服务器请求之后,返回给客户端的数据,一般都是json格式或者xml格式(文件下载除外)

iOS开发使用JSON解析网络数据

iOS开发使用JSON解析网络数据

本篇随便先讲解json解析。

正文:

关于json:

json是一种轻量级的数据格式,一般用于数据交互json的格式很像objective-c中的字典和数组:{"name":"jack","age":10}

补充:

  标准的json格式的注意点:key必须用双引号。(但是在java中是单引号)

  json-oc的转换对照表

   iOS开发使用JSON解析网络数据

   其中:null--返回oc里的nsnull类型

使用:

  在json解析方案有很多种,但是(苹果原生的)nsjsonserialization性能最好

  反序列化(json --> oc对象),下面示例解析成字典对象

  iOS开发使用JSON解析网络数据

  序列化(oc对象 --> json),注意字典的值不能传nil,但是可以传[nsnull null]

  iOS开发使用JSON解析网络数据

  并不是所有的类型都是可以转为json的

  以下是苹果官方规定:

  iOS开发使用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