OC-UI阶段学习30-网络请求Session与Connection

一、网络请求的基本知识

1.get方法与post方法

1. get是从服务器上获取数据,post是向服务器传送数据。
2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,
   在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起
   传送到ACTION属性所指的URL地址。用户看不到这个过程。
3. 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.
   Form获取提交的数据。
4.get是明文传输,post是转为NSData 
还是不明白,回头再看

这篇原创文章讲了些post和get的问题,观点有些不同
http://www.nowamagic.net/librarys/veda/detail/1919

这是400、500、301、200等网站状态码的含义

http://www.maolvge.cn/news/jianzhanchangshi/29.html


2.同步和异步

同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事

异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

session自己内部封装了线程,不存在同步请求的问题了


3. NSURLConnectionNSURLConnection
iOS7以前,使用的都是NSURLConnection
在WWDC2013中,推出了NSURLSession作为替代。

下面这篇文章比较清楚地讲了NSURLConnection和NSURLSession的一些区别和内容
URLSession是一种任务模式
iOS 7系列译文:忘记NSURLConnection,拥抱NSURLSession吧!


4.设置Info.plist文件
添加一条App Transport Secutity Settings
把其下的Allow Arbitrary Loads 属性改为YES

OC-UI阶段学习30-网络请求Session与Connection_第1张图片



二、使用NSURLConnection

1.get方法
//get的同步请求
-(void)getAndSynchronize
{
    NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?date=20151031&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    //得到网址
    NSURL *url = [NSURL URLWithString:urlStr];
    //创建请求
    NSURLRequest *req = [NSURLRequest requestWithURL:url];
    //创建同步链接
    NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil];
    
    //json解析
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"11%@",dic);
    
}

//get的异步请求,使用block方法
-(void)getAndAsynchronize
{
    NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?date=20151031&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    //得到网址
    NSURL *url = [NSURL URLWithString:urlStr];
    //创建请求
    NSURLRequest *req = [NSURLRequest requestWithURL:url];
    
    __block NSDictionary *dic = [NSDictionary dictionary];
    //创建异步
    [NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
    
        dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        NSLog(@"%@",dic);
    }];
    NSLog(@"异步链接下面");
}</span>

2.post方法同步请求
//post同步请求
-(void)postAndSynchronize
{
    //post请求,一般只包含 协议://host/路径
    NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";
    //得到网址
    NSURL *url = [NSURL URLWithString:urlStr];
    //请求方式为post,所有要创建为NSMutableURLRequest
    NSMutableURLRequest *mReq = [[NSMutableURLRequest alloc]initWithURL:url];
    //设置情感方式,不设置时,默认为GET请求
    [mReq setHTTPMethod:@"POST"];
    //创建参数
    NSString *pStr = @"date=20151031&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    NSData *pData = [pStr dataUsingEncoding:NSUTF8StringEncoding];
    //设置参数
    [mReq setHTTPBody:pData];
    
    //建立同步链接
    NSData *resultData = [NSURLConnection sendSynchronousRequest:mReq returningResponse:nil error:nil];
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:resultData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"%@",dic);
}</span>

post方法,使用block和代理方式
//POST异步请求
-(void)postAndAsynchronize
{
    NSString *str = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";
    NSURL *url = [NSURL URLWithString:str];
    NSMutableURLRequest *mReq = [NSMutableURLRequest requestWithURL:url];
    //cahce策略,超时time
    NSMutableURLRequest *mReq1 = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30];
    
    [mReq setHTTPMethod:@"POST"];
    //设置参数
    NSString *pStr = @"date=20151031&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    NSData *pData = [pStr dataUsingEncoding:NSUTF8StringEncoding];
    [mReq setHTTPBody:pData];
    
    
    //1.block
    __block NSDictionary *dic = [NSDictionary dictionary];
    //建立异步链接
    [NSURLConnection sendAsynchronousRequest:mReq queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
//        NSLog(@"%@",dic);
    }];
    
    
    //2.使用协议代理方法
    NSURLConnection *conn = [NSURLConnection connectionWithRequest:mReq delegate:self];
}

#pragma mark -- connect的异步代理方法

//开始
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"开始相应,可以在此代理方法中初始化容器");
    _mData = [[NSMutableData alloc]init];
}

//接收数据,data只是数据片段,不是完整数据,需要拼接
-(void)connection:(NSURLConnection *)connection didReceiveData:(nonnull NSData *)data
{
    NSLog(@"开始返回数据片段");
    
    [_mData appendData:data];
}

//本次链接完成
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"链接完成");
    //可以在此解析数据
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:self.mData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"%@",dic);
}

//链接出错
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"error - %@",error);
}




三、使用NSURLSession

在WWDC2013中,推出了NSURLSession作为替代。

支持后台运行的网络任务
暂停、停止、重启网络任务、不再需要NSOpation封装
请求可以使用同样的配置容器
不同的session可以使用不同的私有存储,block和代理可以同时起作用
直接从文件系统上传下载
为了方便程序员使用,苹果提供了一个全局session
所有的任务(Task)都是由Session发起的
所有的任务默认是挂起的,需要Resume

NSURLSession的三种工作模式
默认会话模式(default)
瞬间会话模式(ephemeral)//不会有任何缓存
后台会话模式(background)//在后台进行网络请求,在没有session以前使用gcd可以让应用程序在进入后台时继续运行0分钟

支持三种任务
加载瞬间,下载,上传,父类都是NSURLSessionTask
NSURLSessionDataTask
NSURLSessionUploadTask
NSURLSessionDownloadTask

1.session get block的方法
//session get block
-(void)sessionGet
{
    //第一种方式创建session,单例,获取全局session对象
    NSURLSession *session = [NSURLSession sharedSession];

    //第二种方式创建session,可以给session设置工作模式
//    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
//    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
    
    //创建url对象
    NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/
    publish/Handler/APINewsList.ashx?date=20151031&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    //得到网址
    NSURL *url = [NSURL URLWithString:urlStr];
    
//    //建立请求任务.block方式,通过url建立task,不需要建立request
//    NSURLSessionDataTask *task = [session dataTaskWithURL:url 
      completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) 
      {
//        
//        //解析数据
//        
//    }];
    
    //如果需要设置缓存策略、请求超时等,需要创建请求对象request
    NSURLRequest *req = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy 
                        timeoutInterval:30];
    
    //通过request方式建立任务
    NSURLSessionTask *task = [session dataTaskWithRequest:req 
        completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) 
   {
        NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@",str);
    }];
    
    //启动任务
    [task resume];
}

2.session get 代理方法
导入NSURLSessionDelegate,NSURLSessionDataDelegate协议
//session post delegate
-(void)sessionDelegate
{
    
    //创建url对象
    NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";
    //得到网址
    NSURL *url = [NSURL URLWithString:urlStr];
    
    //创建参数
    NSString *pStr = @"date=20151031&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    NSData *pData = [pStr dataUsingEncoding:NSUTF8StringEncoding];
    
    NSMutableURLRequest *mReq = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
    //设置请求超时
    [mReq setTimeoutInterval:30];
    [mReq setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    [mReq setHTTPMethod:@"POST"];
    [mReq setHTTPBody:pData];
    
    //代理的方法,主线程
    NSURLSession *session_1 = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    //创建任务(因为要使用代理方法,就不需要block方法初始化)
    NSURLSessionDataTask *task_1 = [session_1 dataTaskWithRequest:mReq];
    //启动
    [task_1 resume];

}

#pragma mark -- session delegate

//服务器开始响应,准备返回数据
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    //运行出来服务器的响应
    completionHandler(NSURLSessionResponseAllow);
    //当网络请求是基于http协议的时候,response的本质为NSHTTPURLResponse
//    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
    
    //初始化容器
    _mData = [NSMutableData data];
}

//客户端接收数据
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    [_mData appendData:data];
}

//数据请求完成网络请求成功,当error不为空,说明响应出错
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    if (error) {
        NSLog(@"error -- %@",error);
    }
    else
    {
        NSString *str = [[NSString alloc]initWithData:_mData encoding:NSUTF8StringEncoding];
        NSLog(@"delegate  -- %@",str);
    }
}



3.session post方法 block
-(void)sessionPost
{
    //创建url对象
    NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";
    //得到网址
    NSURL *url = [NSURL URLWithString:urlStr];
    
    //创建参数
    NSString *pStr = @"date=20151031&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    NSData *pData = [pStr dataUsingEncoding:NSUTF8StringEncoding];


    //创建request
  NSMutableURLRequest *mReq = [[NSMutableURLRequest alloc]initWithURL:url 
      cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];

    //设置
    [mReq setHTTPMethod:@"POST"]; 
    [mReq setHTTPBody:pData]; 
//建session 
    NSURLSession *session = [NSURLSession sharedSession]; 
//加载任务的数据对象 
    NSURLSessionTask *task = [session dataTaskWithRequest:mReqcompletionHandler:^
   (NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
   { 
    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; 
    NSLog(@"%@",str); }]; 

//开启任务 
    [task resume]; 
}

缓存策略NSURLRequestCachePolicy 1> NSURLRequestUseProtocolCachePolicy = 0, 默认的缓存策略,如果缓存不存在,直接从服务端获取。如果缓存存在,会根据response中的Cache-Control字段判断下一步操作,如:Cache-Control字段为must-revalidata,则询问服务端该数据是否有更新,无更新的话直接返回给用户缓存数据,若已更新,则请求服务端.2> NSURLRequestReloadIgnoringLocalCacheData = 1,忽略本地缓存数据,直接请求服务端.3> NSURLRequestIgnoringLocalAndRemoteCacheData = 4,忽略本地缓存,代理服务器以及其他中介,直接请求源服务端.4> NSURLRequestReloadIgnoringCacheData =NSURLRequestReloadIgnoringLocalCacheData5> NSURLRequestReturnCacheDataElseLoad= 2, 有缓存就使用,不管其有效性(即忽略Cache-Control字段), 无则请求服务端.6> NSURLRequestReturnCacheDataDontLoad =3, 死活加载本地缓存. 没有就失败.(确定当前无网络时使用)7>NSURLRequestReloadRevalidatingCacheData =5, 缓存数据必须得得到服务端确认有效才使用(貌似是NSURLRequestUseProtocolCachePolicy中的一种情况)Tips: URL Loading System默认只支持如下5中协议: 其中只有http://和https://才有缓存策略./(1) http://(2) https://(3) ftp://(4) file://(5) data://四、session 下载
-(void)startDownLoadVideo
{
    NSURLSessionConfiguration *configure = [NSURLSessionConfiguration defaultSessionConfiguration];//默认设置
    //初始化session
    self.currentSession = [NSURLSession sessionWithConfiguration:configure delegate:self delegateQueue:nil];
    //描述
    self.currentSession.sessionDescription = self.downLoadVideoModel.flv;
    //下载地址
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://sc.111ttt.com/up/mp3/39165/2EC8D31900361E607A92BC17EDAFF6BC.mp3"]];
    
    
    self.task = [self.currentSession downloadTaskWithRequest:request];
    [self.task resume];//任务开始
    _isDownLoading = YES;
    while (_isDownLoading) {
        //当前线程一直跑?
        [[NSRunLoop currentRunLoop]runUntilDate:[NSDate distantFuture]];
    }

}


 
#pragma mark -- session代理方法

//下载完成
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
    NSURL *documentsDirectory = [URLs objectAtIndex:0];
    //下载任务的url
    NSURL *originalURL = [[downloadTask originalRequest] URL];
    //存储位置的url
    NSURL *destinationURL = [documentsDirectory URLByAppendingPathComponent:[originalURL lastPathComponent]];
    NSError *errorCopy;
    // For the purposes of testing, remove any esisting file at the destination.
    //移除目标url上的内容
    [fileManager removeItemAtURL:destinationURL error:NULL];
    //移动
    BOOL success = [fileManager copyItemAtURL:location toURL:destinationURL error:&errorCopy];
    if (success) {
        dispatch_async(dispatch_get_main_queue(), ^{
            
            self.destinationURL = destinationURL;
            
            
        });
    } else {
        NSLog(@"复制文件发生错误: %@", [errorCopy localizedDescription]);
    }
}


//收到数据的代理
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    
    NSLog(@"上此执行代理到此次传送的字节数 %lld , 已经下载的总量%lld , 总共要下载的%lld",bytesWritten,totalBytesWritten,totalBytesExpectedToWrite);
    
    //进度    
    double progress = (double)totalBytesWritten / totalBytesExpectedToWrite;
    
    dispatch_async(dispatch_get_main_queue(), ^{
        self.progressView.progress = progress;
        
        self.progressLabel.text = [NSString stringWithFormat:@"%% %.0f",progress*100];
    });
    
}

//下载完成后执行
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    if (error == nil) {
        NSLog(@"任务: %@ 成功完成", task);
    } else {
        NSLog(@"任务: %@ 发生错误: %@", task, [error localizedDescription]);
    }
}


//恢复下载后执行的方法
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
    NSLog(@"%.0f",fileOffset/(float)expectedTotalBytes);
}



你可能感兴趣的:(session,网络,服务器,异步,oc)