在一个互联的时代,网络交互是基础功能。这里面涉及的功能有两大块:
- 互联协议,主流就是HTTP协议了。
- 交换的数据格式,主流就是JSON。
在iOS系统中,如何用http协议传输json呢?其中涉及到的技术有:
- 异步加载;
- 网络交互;
- JSON解析
关键技术1:异步加载
因为网络比较耗时,不能直接在UI线程处理,所以需要另外开启新的线程,等数据加载完成,再讲数据传输给UI线程处理,执行UI刷新操作。iOS中有四种方式开启新线程
- Pthreads
- NSThread
- GCD(Grand Central Dispatch)
- NSOperation
其中,Pthreads是基于C语言的,在类Unix操作系统中通用,不是面向对象的,操作复杂;NSThread是经过苹果封装后的,完全面向对象的,但它的生命周期还是需要我们手动管理;GCD是苹果为多核的并行运算提出的解决方案,所以会自动合理地利用更多的CPU内核(比如双核、四核),会自动管理线程的生命周期(创建线程、调度任务、销毁线程),完全不需要我们管理,我们只需要告诉干什么就行,因此成为最常用的异步加载方案;NSOperation 是苹果公司对 GCD 的封装,完全面向对象,所以使用起来更好理解。它们具体的使用方式和区别 参考关于iOS多线程,你看我就够了、NSOprationQueue 与 GCD 的区别与选用
关键技术2:网络交互
在iOS中,常见的发送网络交互的解决方案有
- iOS原生接口
- NSURLConnection:用法简单,最古老最经典最直接的一种方案
- NSURLSession:iOS 7新出的技术,功能比NSURLConnection更加强大
- CFNetwork:NSURL*的底层,纯C语言
- 第三方框架
- ASIHttpRequest:外号“HTTP终结者”,功能极其强大,可惜早已停止更新
- AFNetworking:简单易用,提供了基本够用的常用功能。目前比较常用,可以用CocoaPods集成(具体方法参考:构建iOS开发工作流)。
AFNetworking是一个讨人喜欢的网络库,适用于iOS以及Mac OS X。
它构建于在NSURLConnection, NSOperation, 以及其他熟悉的Foundation技术之上。拥有良好的架构,丰富的api,以及模块化构建方式,使得使用起来非常轻松。示例代码:
NSURL *url = [NSURL URLWithString:@"https://gowalla.com/users/mattt.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"Name: %@ %@", [JSON valueForKeyPath:@"first_name"], [JSON valueForKeyPath:@"last_name"]);
} failure:nil];
[operation start];
关键技术3:JSON解析
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。JSON采用完全独立于程序语言的文本格式。
- iOS原生接口:NSJSONSerialization
- 第三方框架:在github搜索json,object-c下star前三的如下
其中,JSONKit 是用 Objective-C 实现的一个高性能的 JSON 解析和生成库,支持iOS。解析(Parsing)和序列化(Serializing)性能比较如下:
简单实例
NetViewController用原生的GCD、NSURLConnection、NSJSONSerialization模拟了 异步加载、 网络交互、JSON解析等功能。
NetViewController.h代码如下:
//
// NetViewController.h
// PandaiOSDemo
//
// Created by shitianci on 16/7/1.
// Copyright © 2016年 Panda. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface NetViewController : UIViewController
@property (strong, nonatomic) UILabel *infoLabel;
@end
NetViewController.m代码如下:
//
// NetViewController.m
// PandaiOSDemo
//
// Created by shitianci on 16/7/1.
// Copyright © 2016年 Panda. All rights reserved.
//
#import "NetViewController.h"
@interface NetViewController ()
@end
@implementation NetViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.infoLabel = [[UILabel alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.infoLabel.text = @"网络加载中...";
// self.infoLabel.backgroundColor = [UIColor greenColor];
/**
* 创建异步任务
*/
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
//code here
NSLog(@"这是异步任务", [NSThread currentThread]);
/**
* 访问网络,输出错误日志
*/
{
NSURL *url = [[NSURL alloc] initWithString:@"http://www.xxx.xxx"];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
if (data == nil) {
NSLog(@"send request failed: %@", error);
}
}
/**
* 此处模拟json串,进行解析
*/
NSString *jsonString = @"{\"jsonKey\": \"这是网络数据中,jsonKey对应的数据\"}";
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSString *result;
{
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
if (json == nil) {
NSLog(@"json parse failed \r\n");
}
result = [json objectForKey:@"jsonKey"];
}
sleep(2);
dispatch_async(dispatch_get_main_queue(), ^{
/**
* 通知主线程刷新
*/
self.infoLabel.text = result;
});
});
[self.view addSubview:self.infoLabel];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
参考:
Panda
2016-07-01