初步异步下载
url定义:在WWW上,每一信息资源都有统一的且在网上唯一的地址,该地址就叫URL(UniformResourceLocator,统一资源定位符),它是WWW的统一资源定位标志,就是指网络地址。
/* http://(客户端与服务端进行数据交互,遵循的协议,超文本传输协议)
* 10.0.8.8/(服务器的地址(基地址),可以是ip地址也可以是域名)
* /my/user_list.php (服务器上特定资源(用户公开列表)的后续地址/接口名称)
* http://10.0.8.8/sns/my/user_list.php(组成了请求公开用户列表的地址)
* 请求地址与参数之间用?隔开,参数作为请求资源的限定条件;参数之间用&连接 (参数格式:参数名称=参数类型对应的值)
*/
1,【同步下载,工作中从来不直接使用!!】
NSString *str = [NSString stringWithFormat:@"http://10.0.8.8/sns/my/user_list.php?page=%d&number=%d",page,number];
//对字符串封装成网址类
NSURL *url = [NSURL URLWithString:str];
//字符串的类方法,会自动根据url向服务器发起同步请求,并将请求结果返回。
//应用程序在启动之初,会自动开辟一个主线程,负责数据的初始化,视图的初始化以及视图的展示等,同步请求数据也在主线程中进行,如果耗时较长,会对主线程造成阻塞,用户体验极差
NSString *result = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData *data = [result dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary/NSArray(根据数据结构选择最外层容器) *myResult = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
把结果放到tableView中(uid/username)
2,系统自带异步下载流程
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//状态栏的旋转小菊花
NSString *str = [NSString stringWithFormat:@"http://10.0.8.8/sns/my/user_list.php?page=%d&number=%d",page,number];
NSURL *url = [NSURL URLWithString:str];
//根据url,生成一个请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//[NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20];
//利用请求对象,创建一个NSURLConnection 对象,connection对象会在客户端与服务端之间建立一个连接,并将request由客户端发到服务端
//遵循http协议,发起的是异步的请求
//异步:主线程负责数据的初始化,视图的初始化和界面的展示等,NSURLConnection进行数据请求的时候,会在主线程之外,单独开辟一个线程进行与服务器的交互,和接收服务器数据等耗时的操作,当数据接收完毕后,会通过代理方法自动回到主线程。我们可以在主线程进行后续的数据解析和视图刷新的操作
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
+ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;
//2种方法开始连接 +方法/-方法
<NSURLConnectionDataDelegate> 代理方法
//常用的4个:1,开始响应。2,传输数据。3,成功。4,失败
//客户端收到服务端对request的响应时,调用此方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//开始下载前清空里面的旧数据
[_downloadData setLength:0];
}
//当客户端收到服务端根据request传递过来的数据时(接收数据的过程 ),调用此方法
//可能被调用多次
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_downloadData appendData:data];
}
//客户端接收数据完毕后,调用此方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//将_downloadData转化成数据源然后刷新tableView
[_myTableView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"联网失败,或者数据传输超时");
}
中途取消下载的方法
- (void)cancel;//取消连网
3,【SDWebImage】
一个非常牛b的第三方图片下载库,实现了图片的异步,并发下载,并且有缓存功能
封装的是一个category
#import "UIImageView+WebCache.h"
//2个最常用的方法:加载一个网络图片,且自动缓存
//一个有默认图片,一个没有
- (void)setImageWithURL:(NSURL *)url;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
4,【ASIHTTPRequest】以前非常流行的下载类,现在已经不更新了,逐渐被淘汰中
一个三方连网下载类,遵循http协议,支持get、post请求,支持数据的同步和异步下载。支持多任务下载和获取下载进度,支持资源的断点续传
NSString *str = @"http://10.0.8.8/sns/my/user_list.php?page=1&number=5";
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:str]];
//设置代理
request.delegate = self;
//不同的request对象,可以通过不同的tag值来标记
request.tag = 100;
//向服务器发起异步数据请求
[request startAsynchronous];
需要+4个framework
代理方法<ASIHTTPRequestDelegate>,2个一个成功,一个失败
//当数据获取完毕后,调用此方法
- (void)requestFinished:(ASIHTTPRequest *)request
{
//不同的request对象通过tag值来区分,进而进行不同的后续处理
if (request.tag == 100) {
//请求下来的数据都存在responseData属性中
if (request.responseData) {
//可以直接获得字符串,但实际开发中,一般都用data然后json解析
NSString *result = request.responseString;
NSLog(@"结果:%@",result);
}
}
}
//获取数据失败时,或者网络不可以时,调用此方法
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSLog(@"错误:%@",[request.error description]);
}
#import "ViewController.h"
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
{
NSMutableArray *_dataArr;
UITableView *_myTableView;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *urlStr = @"http://10.0.8.8/sns/my/user_list.php";
NSLog(@"1111");
//从网络获取数据(同步的,工作中严禁使用)
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlStr]];
NSLog(@"222");
//将符合json格式的数据转化成字典(或数组,根据数据的最外层)
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
_dataArr = [dic objectForKey:@"users"];
_myTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
_myTableView.delegate = self;
_myTableView.dataSource = self;
[self.view addSubview:_myTableView];
}
#pragma mark - tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _dataArr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
NSDictionary *dic = [_dataArr objectAtIndex:indexPath.row];
cell.textLabel.text = [dic objectForKey:@"uid"];
cell.detailTextLabel.text = [dic objectForKey:@"username"];
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
#import "ViewController.h"
#import "UIImageView+WebCache.h"
@interface ViewController () <NSURLConnectionDataDelegate, UITableViewDataSource, UITableViewDelegate>
{
NSMutableData *_downloadData;
NSMutableArray *_dataArr;
UITableView *_myTableView;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//网址的字符串
NSString *urlStr = @"http://10.0.8.8/sns/my/user_list.php?page=7&number=100";
//转成NSURL网址类的对象
NSURL *url = [NSURL URLWithString:urlStr];
//使用网址创建网络请求,中间参数是缓存策略,一般直接写0,最后一个参数超时时间
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:15];
NSLog(@"111");
//用来接收下载的数据
_downloadData = [[NSMutableData alloc] init];
_dataArr = [[NSMutableArray alloc] init];
//开始网络请求
[NSURLConnection connectionWithRequest:request delegate:self];
NSLog(@"222");
_myTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
_myTableView.dataSource = self;
_myTableView.delegate = self;
_myTableView.separatorColor = [UIColor redColor];
[self.view addSubview:_myTableView];
}
#pragma mark - connection
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"服务器开始响应");
//每次开始响应的时候清空数据
_downloadData.length = 0;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"接收数据,可能会被调用多次");
//下载一点放一点
[_downloadData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"网络请求已完成");
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:_downloadData options:0 error:nil];
_dataArr.array = [dic objectForKey:@"users"];
//数据下载完成以后,需要刷新tv
[_myTableView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"网络请求失败:%@",error);
}
#pragma mark - tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _dataArr.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"qqq"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"qqq"];
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(200, 10, 60, 60)];
iv.tag = 1;
[cell.contentView addSubview:iv];
}
NSDictionary *dic = [_dataArr objectAtIndex:indexPath.row];
cell.textLabel.text = [dic objectForKey:@"uid"];
cell.detailTextLabel.text = [dic objectForKey:@"username"];
UIImageView *iv = (UIImageView *)[cell.contentView viewWithTag:1];
//头像的网址
NSString *imageUrlStr = [NSString stringWithFormat:@"http://10.0.8.8/sns%@",[dic objectForKey:@"headimage"]];
//为一个iv加载网络图片,自带缓存
[iv setImageWithURL:[NSURL URLWithString:imageUrlStr]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(@"uid = %@",[[_dataArr objectAtIndex:indexPath.row] objectForKey:@"uid"]);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
ASI----------------------------------------------------------------
#import "ViewController.h"
#import "ASIHTTPRequest.h"
@interface ViewController () <ASIHTTPRequestDelegate>
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *str = @"http://10.0.8.8/sns/my/user_list.php?page=5&number=60";
//创建asi的网络请求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:str]];
request.delegate = self;
//开始异步下载
[request startAsynchronous];
}
//下载成功
- (void)requestFinished:(ASIHTTPRequest *)request
{
//打印下载的字符串
// NSLog(@"%@",request.responseString);
//request.responseData : 下载的数据
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:request.responseData options:0 error:nil];
NSLog(@"%@",dic);
}
//下载失败
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSLog(@"error");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end