iOS个人整理30-网络请求Session与Connection

2023-05-16

一、网络请求的基本知识

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





二、使用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(@"异步链接下面");
}

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);
}

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);
}



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS个人整理30-网络请求Session与Connection 的相关文章

  • Rust 类型、泛型和特征

    Rust 创建泛型 generic function rs fn give me lt T gt value T let 61 value fn main let a 61 34 generics 34 let b 61 1024 give
  • Vmware虚拟机硬盘扩容: Linux下虚拟机硬盘空间扩展及挂载配置

    都是自己使用过程中的小经验 xff0c 分享给大家 希望能互相帮助 进入正题 xff1a 大家是不是会遇到最初分配linux虚拟机硬盘后期不够用的情况 xff0c xff08 因为是我之前用友善之臂的虚拟机配ARM板学习 xff0c 只有2
  • 数据结构之冒泡排序

    文字描述 xff08 以升序为例 依次比较数组中相邻两个元素大小 xff0c 若a i gt a 43 1 xff0c 则交换两个元素 xff0c 两两都比较一遍称为一轮冒泡 xff0c 结果是让最大的元素排至最后重复以上步骤 xff0c
  • 十进制转八进制的方法

    include lt stdio h gt int main int n printf 34 请输入一个十进制的数 xff1a 34 scanf 34 d 34 amp n int i 61 0 int arr 100 while n 61
  • Nodejs之目录介绍及app.js说明

    随时随地阅读更多技术实战干货 xff0c 获取项目源码 学习资料 xff0c 请关注源代码社区公众号 ydmsq666 转自 xff1a https www cnblogs com Chen xy p 4466351 html nodejs
  • 源码学习笔记之Openssl

    目录 xff1a apps apps c apps h app rand c asn1pars c build info ca cert srl ca key pem ca req pem ca c CA pl in cert pem ci
  • Segmentation Fault错误原因总结

    一 什么是 Segmentation fault in Linux 所谓的段错误就是指访问的内存超过了系统所给这个程序的内存空间 通常这个值是由gdtr来保存的 他是一个48位的寄存器 其中的32位是保存由它指向的gdt表 后13位保存相应
  • 树莓派使用MobaXterm实现SSH和VNC

    树莓派使用MobaXterm实现SSH和VNC terminal推荐 xff1a MobaXterm 一 开机SSH无线连接 前提 xff1a 树莓派和PC在同一局域网下 xff0c 通过路由器获得树莓派ip 打开ssh boot目录新建文
  • 【Qt】QtCreator远程部署、调试程序

    1 添加远程设备 1 QtCreator 工具 gt 选项 gt 设备 gt 添加 2 设备设置向导选择 gt Generic Linux Device gt 开启向导 3 填写 标识配置的名称 随便写 设备IP 用户名 gt 下一步 4
  • Debian备份与还原

    备份 xff1a sudo su cd tar cvpzf backup tgz exclude 61 proc exclude 61 lost 43 found exclude 61 backup tgz exclude 61 mnt e
  • 微信开放平台-第三方平台开发配置及常见的问题

    目录 概述 参考文档 开源项目 amp 工具 第三方平台设置 问题及解决方法 概述 本实例 xff1a 第三方平台 43 微信公众号 xff08 服务号 xff09 微信开放平台 第三方平台 xff0c 为广大公众号和小程序提供运营服务和行
  • 【Python包管理系列1】python打包发布到PyPI全过程(入门版)

    文章目录 目的准备知识PyPIPyPAsetuptoolsbuildtwine 实战过程总结 目的 如果发布一个python包到pypi上 xff0c 共他人使用 xff0c 本文试图讲清楚 准备知识 PyPI 官网地址 xff1a htt
  • Web自动化测试(二)—— Selenium-API操作

    其他Web测试知识参考 xff1a Web自动化测试 目录 一 元素定位 1 如何进行元素定位 xff1f 2 浏览器开发者工具 2 1 如何使用浏览器开发者工具 二 元素定位方式 1 id定位 2 name定位 3 class name定
  • Java中字符串中子串的查找共有四种方法(indexof())

    亲测可用 xff0c 若有疑问请私信 indexOf 方法返回一个整数值 xff0c 指出 String 对象内子字符串的开始位置 如果没有找到子字符串 xff0c 则返回 1 如果 startindex 是负数 xff0c 则 start
  • 使用rust构建一个js引擎

    转载于 https my oschina net lilugirl2005 blog 3067895
  • Linux下使用acme.sh 配置https 免费证书

    acme sh 简单来说acme sh 实现了 acme 协议 可以从 let s encrypt 生成免费的证书 acme sh 有以下特点 xff1a 一个纯粹用Shell xff08 Unix shell xff09 语言编写的ACM
  • iOS 性能优化之内存优化

    近四年没更CSDN了 xff0c 感慨万千 近年来在搞一款比较大的APP xff0c 项目中代码量100w 43 xff0c 里面使用的三方库 其他领域的二进制包比较多 xff1b 以前这些三方 二进制都挤在同一个工程目录下 xff0c 导
  • 内核升级和降级

    查看已安装的内核 sudo dpkg get selections grep linux 不一样的系统版本升级内核要装的东西对应也不一样 xff0c 需要根据 get selections 安装对应的内核组件 使用apt get 即可完成安
  • Docker: Debian安装Docker

    Debian安装Docker 内容由 网络搜罗整理而来 xff0c 记录与共享 一 APT安装 官方Debian存储库中提供的Docker安装包可能不是最新版本 为了确保我们获得最新版本 xff0c 我们将从官方Docker存储库安装Doc
  • CodeBlocks快捷键

    原文地址 xff1a https blog csdn net lxt lucia article details 79572829 一 汇总 1 编辑部分 xff1a 按住Ctrl xff0c 滚动鼠标滚轮 xff0c 放大或缩小字体 Ct

随机推荐