-
官方网络框架 NSURLConnection
-
重要概念
- ShowAPI:web server提供网站
-
NSURLSessionTask类结构
-
NSURLSessionDataTask
-
get方式
-
创建NSURLRequest(URL请求)对象
NSURL *url = [NSURL URLWithString:strUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
-
获取单例NSURLSession(URL会话)对象
必须使用单例,因为单例已经配置好NSURLSession对象。设置好了其他未设置好的参数
NSURLSession *session = [NSURLSession sharedSession];
-
创建NSURLSessionDataTask(URLSession会话任务)对象,负责执行会话任务 completionHandler:回调block
NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",jsonData);
} else {
NSLog(@"请求错误:%@",error);
}
}];
-
会话任务 重新开始
[sessionDataTask resume];
-
-
post方式
-
创建NSMutableURLRequest(可变URL请求)对象,需要设置参数
NSURL *url = [NSURL URLWithString:@"https://route.showapi.com/213-4"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
-
设置请求模式为post
request.HTTPMethod = @"post";
-
设置请求体,POST请求的参数数据要使用HTTPBody(请求体)的方式发送,需设置请求方式(HTTPMethod)为POST.
NSString *appid = @"16469";
NSString *timestamp = [NSDate formatDateStringForCurrDate];
NSString *topid = @"5";
NSString *sign = @"8f39335f503741ed96744cda3c0a7b52";
NSString *strHttpBody = [NSString stringWithFormat:@"showapi_appid=%@&showapi_timestamp=%@&topid=%@&showapi_sign=%@",appid,timestamp,topid,sign];
NSData *data_httpBody = [strHttpBody dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = data_httpBody;
-
获取单例NSURLSession(URL会话)对象
NSURLSession *session = [NSURLSession sharedSession];
-
创建 NSURLSessionTask(URL会话任务)对象,负责执行会话任务 completionHandler:回调block
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",jsonData);
} else {
NSLog(@"请求错误:%@",error);
}
}];
-
会话任务 重新开始
[dataTask resume];
-
-
NSURLSessionConfiguration(URL会话配置)
-
创建请求模式
/* 创建请求模式
1、defaultSessionConfiguration 默认模式,会有缓存、cookie
2、ephemeralSessionConfiguration 不会缓存,无痕浏览
3、backgroundSessionConfigurationWithIdentifier 后台任务模式
*/
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
-
设置缓存机制,属性requestCachePolicy
NSURLRequestUseProtocolCachePolicy = 0, 默认机制,有缓存先加载缓存,没有进行网络获取。但是会判断缓存的有效性,缓存过期不会加载。
NSURLRequestReloadIgnoringLocalCacheData = 1, 不加载缓存,总是请求网络
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
NSURLRequestReturnCacheDataElseLoad = 2, 有缓存先加载缓存,没有进行网络获取。不会判断缓存的有效性
NSURLRequestReturnCacheDataDontLoad = 3, 只使用缓存,没有也不进行网络请求
-
-
-
NSURLSessionDownloadTask 下载任务
-
使用方式
NSString *strUrl = @"http://tsmusic24.tc.qq.com/105593336.mp3";
NSURL *url = [NSURL URLWithString:strUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
[downloadTask resume];
-
NSURLSessionDownloadDelegate委托
-
下载会话,每次从服务器获取到数据时触发
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
-
下载完成后触发
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
-
-
-
NSURLSessionUploadTask 上传任务
-
基本使用
-
创建上传路径URL
NSURL *uploadUrl = [NSURL URLWithString:@"http://www.mftp.info"];
-
创建可变URL请求,并设置请求模式为POST
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:uploadUrl cachePolicy:0 timeoutInterval:20];
request.HTTPMethod = @"post";
-
创建会话(URLSession),并设置处理会话的委托。
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
-
创建上传的文件本地URL
NSURL *fileUrl = [NSURL fileURLWithPath:@"文件路径"];
-
创建上传任务(URLSessionUploadTask) 设置请求、要上传的文件本地URL
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileUrl];
-
上传任务开始
[uploadTask resume];
-
-
NSURLSessionDataDelegate委托
-
每当上传数据时调用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
-
上传完成时调用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
-
-
-
后台下载
-
设置NSURLSessionConfiguration对象为后台下载模式
NSURLSessionConfiguration *config= [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.pengjing.background"];
- 在backgroundSessionConfiguration:方法中的identifier参数指定了会话的ID,用于标记后台的session。
-
在AppDelegate类中要实现的方法
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
- 在切到后台之后,Session的Delegate不会再收到,Task相关的消息,直到所有Task全都完成后,系统会调用ApplicationDelegate的之后"汇报"下载工作,对每一个后台下载的Task调用Session的Delegate中的URLSession:downloadTask:didFinishDownloadingToURL:
- 在方法中需要将completionHandler Block作为属性公开,在后面的Session的委托方法中didFinish时候调用一下
-
实现NSURLSessionDownloadDelegate委托方法
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
- (程序进入后台,但UIApplication却任然在监听)UIApplication监听到downloadTask(下载任务)完成后,会先调用UIApplication的代理方法handleEventsForBackgroundURLSession,然后汇报下载工作,最后每个后台下载完成了的任务都会调用URLSessionDidFinishEventsForBackgroundURLSession委托方法
- 在这个方法中需要调用存放completionHandler的属性,并执行一下,否则会报错
-
如果是一个BackgroundSession,在Task执行的时候,用户切到后台,Session会和ApplicationDelegate做交互。当程序切到后台后,在BackgroundSession中的Task还会继续下载,这部分文档叙述比较少,现在分三个场景分析下Session和Application的关系:
-
当加入了多个Task,程序没有切换到后台。
这种情况Task会按照NSURLSessionConfiguration的设置正常下载,不会和ApplicationDelegate有交互。
-
当加入了多个Task,程序切到后台,所有Task都完成下载。
在切到后台之后,Session的Delegate不会再收到,Task相关的消息,直到所有Task全都完成后,系统会调用ApplicationDelegate的application:handleEventsForBackgroundURLSession:completionHandler:回调,之后"汇报"下载工作,对于每一个后台下载的Task调用Session的Delegate中的URLSession:downloadTask:didFinishDownloadingToURL:(成功的话)和URLSession:task:didCompleteWithError:(成功或者失败都会调用)。之后调用Session的Delegate回调URLSessionDidFinishEventsForBackgroundURLSession:。
-
当加入了多个Task,程序切到后台,下载完成了几个Task,然后用户又切换到前台。(程序没有退出)
切到后台之后,Session的Delegate仍然收不到消息。在下载完成几个Task之后再切换到前台,系统会先汇报已经下载完成的Task的情况,然后继续下载没有下载完成的Task,后面的过程同第一种情况。
-
当加入了多个Task,程序切到后台,几个Task已经完成,但还有Task还没有下载完的时候关掉强制退出程序,然后再进入程序的时候。(程序退出了)
最后这个情况比较有意思,由于程序已经退出了,后面没有下完Session就不在了后面的Task肯定是失败了。但是已经下载成功的那些Task,新启动的程序也没有听"汇报"的机会了。经过实验发现,这个时候之前在NSURLSessionConfiguration设置的NSString类型的ID起作用了,当ID相同的时候,一旦生成Session对象并设置Delegate,马上可以收到上一次关闭程序之前没有汇报工作的Task的结束情况(成功或者失败)。但是当ID不相同,这些情况就收不到了,因此为了不让自己的消息被别的应用程序收到,或者收到别的应用程序的消息,起见ID还是和程序的Bundle名称绑定上比较好,至少保证唯一性。
-
-
UILocalNotification本地推送
- 当下载任务、上传任务完成后可以发送一条本地推送,告知用户任务已完成
-
创建方式
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
-
常用属性
-
fireDate:开始时间
例如:localNotification.fireDate = [[NSDate date] dateByAddingTimeInterval:3];
- timeZone:时区
-
soundName:推送的声音
例如:localNotification.soundName = UILocalNotificationDefaultSoundName;
- alertBody:消息内容
- applicationIconBadgeNumber:显示在icon上的红色圈中的数字,默认为0
-
-
使用
-
将本地推送添加到UIApplication中
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
-
要想实现本地推送,首先要得到用户的授权
// instanceMethodForSelector 为NSObject的类方法。判断每个类是否定义了 SEL 这个方法,返回IMP(真正的函数指针)
if ([UIApplication instanceMethodForSelector:@selector(registerUserNotificationSettings:)]) {
/*
UIUserNotificationTypeNone = 0 无任何效果
UIUserNotificationTypeBadge = 1 << 0 在状态栏中显示图标
UIUserNotificationTypeSound = 1 << 1 弹出消息框时伴随着声音(音效)
UIUserNotificationTypeAlert = 1 << 2 在悬浮框中弹出消息框
*/
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert tegories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:setting];
//将设置好的本地通知进行注册,即询问用户是否同意
}
-
-
-
断点续传
- 创建一个下载任务并开始,创建同上
-
使用NSURLSessionDownloadTask对象的实例方法
cancelByProducingResumeData:^(NSData * _Nullable resumeData) 暂停下载任务,并执行block代码块(将resumeData数据保存到本地)
// cancelByProducingResumeData暂停下载任务,并执行block代码块。
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
resumeFileData = resumeData;
// NSUserDefaults写入plist文件
NSUserDefaults *userInfo = [NSUserDefaults standardUserDefaults];
[userInfo setValue:resumeData forKey:LWResumeData];
float progressValue = (float)self.downloadTask.countOfBytesReceived/self.downloadTask.countOfBytesExpectedToReceive;
self.viewProgress.progress = progressValue;
[userInfo setValue:@(progressValue) forKey:LWProgressValue];
[userInfo synchronize];
}];
-
当要重新开始时,获取本地resumeData数据
使用NSURLSession的实例方法downloadTaskWithResumeData: 创建下载任务,并让下载任务继续开始
// 让下载任务从 某个数据端的末尾 重新开始
self.downloadTask = [self.session downloadTaskWithResumeData:resumeFileData];
// 下载任务 重新开始
[self.downloadTask resume];
-
-
第三方网络框架 AFNetWorking
-
重点知识点
-
CocoaPods导入AFNetworking命令
pod 'AFNetworking','~>3.0'
-
常用到的类
AFHTTPSessionManager:GET、POST请求
AFURLSessionManager:dataTask、uploadTask、downloadTask
-
请求格式类
AFHTTPRequestSerializer:二进制格式
AFJSONRequestSerializer:JSON
AFPropertyListRequestSerializer:PList(是一种特殊的XML,解析起来相对容易)
-
返回格式类
AFHTTPResponseSerializer:二进制格式
AFJSONResponseSerializer:JSON
AFXMLParserResponseSerializer:XML,只能返回XMLParser,还需要自己通过代理方法解析
AFXMLDocumentResponseSerializer:(Mac OS X)
AFPropertyListResponseSerializer:PList
AFImageResponseSerializer:Image
AFCompoundResponseSerializer:组合
注意:默认提交的请求数据是二进制,返回的则是JSON。如果提交的数据是JSON,需将请求格式设置为AFJSONRequestSerializer。如果返回的数据是二进制,需将返回格式设置为AFHTTPResponseSerializer
-
-
使用AFHTTPSessionManager类发送POST请求
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSString *postUrlStr = @"http://www.mftp.info";
NSURLSessionDataTask *dataTask = [manager POST:postUrlStr parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/tens03/Desktop/0.jpg"];
[formData appendPartWithFileURL:fileUrl name:@"image" fileName:@"0.jpg" mimeType:@"image/jpeg" error:nil];
} progress:^(NSProgress * _Nonnull uploadProgress) {
NSLog(@"%lld, %lld",uploadProgress.totalUnitCount,uploadProgress.completedUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"上传成功:%@",[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"上传失败");
}];
[dataTask resume];
-
使用AFHTTPSessionManager类上传文件
// 1、创建可变URL请求(因为是上传任务,所以必须设置为POST方式)
// 第一种 通过AFJSONRequestSerializer创建 当需要传递参数时使用
AFHTTPRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
NSString *strUrl = @"http://www.mftp.info";
NSMutableURLRequest *request = [requestSerializer requestWithMethod:@"POST" URLString:strUrl parameters:nil error:nil];
/* 第二种 通过NSMutableURLRequest创建 当不需要传递参数时使用
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.mftp.info"]];
request.HTTPMethod = @"POST";
*/
// 2、创建AFURLSessionManager(Session管理)对象 相当于NSURLSession对象
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
// 设置服务器响应数据序列化的代理对象,默认是AFJsonResponseSerializer对象
manager.responseSerializer = [AFHTTPResponseSerializer serializer];// 通过类方法serializer创建,会对属性进行默认设置
NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/tens03/Desktop/0.jpg"];
// 3、创建NSURLSessionUploadTask(上传任务)对象,通过AFURLSessionManager对象的uploadTaskWithRequest实例方法
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:fileUrl progress:nil completionHandler:^(NSURLResponse * _Nonnull sponse, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
NSLog(@"success: %@",response);
} else {
NSLog(@"error: %@",error);
}
}];
// 4、上传任务 重新开始
[uploadTask resume];
-
iOS学习之路06 - 网络编程
最新推荐文章于 2021-05-01 18:22:07 发布