iOS开发-NSURLSession详解

简介:

Core Foundation中NSURLConnection在2003年伴随着Safari浏览器的发行,诞生的时间比较久远,iOS升级比较快,AFNetWorking在3.0版本删除了所有基于NSURLConnection API的所有支持,新的API完全基于NSURLSession。AFNetworking 1.0建立在NSURLConnection的基础之上 ,AFNetworking 2.0使用NSURLConnection基础API,以及较新基于NSURLSession的API的选项。NSURLSession用于请求数据,作为URL加载系统,支持http,https,ftp,file,data协议。

基础知识

URL加载系统中需要用到的基础类:

iOS7和Mac OS X 10.9之后通过NSURLSession加载数据,调用起来也很方便: 

1
2
3
4
5
6
7
8
NSURL *url=[NSURL URLWithString: @"http://www.cnblogs.com/xiaofeixiang" ];
NSURLRequest *urlRequest=[NSURLRequest requestWithURL:url];
NSURLSession *urlSession=[NSURLSession sharedSession];
NSURLSessionDataTask *dataTask=[urlSession dataTaskWithRequest:urlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
     NSDictionary *content = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
     NSLog( @"%@" ,content);
}];
[dataTask resume];

 

NSURLSessionTask是一个抽象子类,它有三个具体的子类是可以直接使用的:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask。这三个类封装了现代应用程序的三个基本网络任务:获取数据,比如JSON或XML,以及上传下载文件。dataTaskWithRequest方法用的比较多,关于下载文件代码完成之后会保存一个下载之后的临时路径:

1
2
3
NSURLSessionDownloadTask *downloadTask=[urlSession downloadTaskWithRequest:urlRequest completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
     
}];

NSURLSessionUploadTask上传一个本地URL的NSData数据:

1
2
3
NSURLSessionUploadTask *uploadTask=[urlSession uploadTaskWithRequest:urlRequest fromData:[NSData  new ] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
     
}];

NSURLSession在Foundation中我们默认使用的block进行异步的进行任务处理,当然我们也可以通过delegate的方式在委托方法中异步处理任务,关于委托常用的两种NSURLSessionTaskDelegate和NSURLSessionDownloadDelegate,其他的关于NSURLSession的委托有兴趣的可以看一下API文档,首先我们需要设置delegate:

1
2
3
4
5
6
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *inProcessSession = [NSURLSession sessionWithConfiguration:sessionConfig  delegate :self delegateQueue:nil];
NSString *url =  @"http://www.cnblogs.com/xiaofeixiang" ;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSessionTask *dataTask = [inProcessSession dataTaskWithRequest:request];
[dataTask resume];

任务下载的设置delegate:

1
2
3
4
5
6
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *inProcessSession = [NSURLSession sessionWithConfiguration:sessionConfig  delegate :self delegateQueue:nil];
NSString *url =  @"http://www.cnblogs.com/xiaofeixiang" ;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSessionDownloadTask *downloadTask = [inProcessSession downloadTaskWithRequest:request];
[downloadTask resume];

关于delegate中的方式只实现其中的两种作为参考:

1
2
3
4
5
6
7
8
9
#pragma mark - NSURLSessionDownloadDelegate
-( void )URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
     NSLog( @"NSURLSessionTaskDelegate--下载完成" );
}
 
#pragma mark - NSURLSessionTaskDelegate
-( void )URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
      NSLog( @"NSURLSessionTaskDelegate--任务结束" );
}

NSURLSession状态同时对应着多个连接,不能使用共享的一个全局状态,会话是通过工厂方法来创建配置对象。

defaultSessionConfiguration(默认的,进程内会话),ephemeralSessionConfiguration(短暂的,进程内会话),backgroundSessionConfigurationWithIdentifier(后台会话)

第三种设置为后台会话的,当任务完成之后会调用application中的方法:

1
2
3
-( void )application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:( void  (^)())completionHandler{
     
}

网络封装

上面的基础知识能满足正常的开发,我们可以对常见的数据get请求,Url编码处理,动态添加参数进行封装,其中关于url中文字符串的处理

stringByAddingPercentEncodingWithAllowedCharacters属于新的方式,字符允许集合选择的是URLQueryAllowedCharacterSet,

NSCharacterSet中分类有很多,详细的可以根据需求进行过滤~

1
2
3
4
5
6
7
8
9
typedef  void  (^CompletioBlock)(NSDictionary *dict, NSURLResponse *response, NSError *error);
 
@ interface  FENetWork : NSObject
 
+( void )requesetWithUrl:(NSString *)url completeBlock:(CompletioBlock)block;
 
+( void )requesetWithUrl:(NSString *)url  params :(NSDictionary *) params  completeBlock:(CompletioBlock)block;
 
@end

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@implementation FENetWork
 
+( void )requesetWithUrl:(NSString *)url completeBlock:(CompletioBlock)block{
     NSString *urlEnCode=[url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
     NSURLRequest *urlRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:urlEnCode]];
     NSURLSession *urlSession=[NSURLSession sharedSession];
     NSURLSessionDataTask *dataTask=[urlSession dataTaskWithRequest:urlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
         if  (error) {
             NSLog( @"%@" ,error);
             block(nil,response,error);
         } else {
             NSDictionary *content = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
             block(content,response,error);
         }
     }];
     [dataTask resume];
}
 
+( void )requesetWithUrl:(NSString *)url  params :(NSDictionary *) params  completeBlock:(CompletioBlock)block{
     
     NSMutableString *mutableUrl=[[NSMutableString alloc]initWithString:url];
     if  ([ params  allKeys]) {
         [mutableUrl appendString: @"?" ];
         for  (id key  in  params ) {
             NSString *value=[[ params  objectForKey:key] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
             [mutableUrl appendString:[NSString stringWithFormat: @"%@=%@&" ,key,value]];
         }
     }
     [self requesetWithUrl:[mutableUrl substringToIndex:mutableUrl.length-1] completeBlock:block];
}
 
@end

本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/5153247.html,如需转载请自行联系原作者

相关文章
|
2月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
106 3
|
4月前
|
存储 iOS开发
iOS 开发,如何进行应用的本地化(Localization)?
iOS 开发,如何进行应用的本地化(Localization)?
123 2
|
4月前
|
存储 数据建模 数据库
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
43 0
|
4月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
106 2
|
2月前
|
API 开发工具 Android开发
iOS 和 Android 平台的开发有哪些主要区别?
iOS与Android开发区别:iOS用Objective-C/Swift,App Store唯一下载渠道;Android用Java/Kotlin,多商店发布(如Google Play、华为市场)。设计上,iOS简洁一致,Android灵活可定制。开发工具,iOS用Xcode,Android用Android Studio。硬件和系统多样性,iOS统一,Android复杂。权限管理、审核流程及API各有特点,开发者需依据目标平台特性进行选择。
38 3
|
12天前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
12天前
|
存储 Swift iOS开发
使用Swift开发一个简单的iOS应用的详细步骤。
使用Swift开发iOS应用的步骤包括:创建Xcode项目,设计界面(Storyboard或代码),定义数据模型,实现业务逻辑,连接界面和逻辑,处理数据存储(如Core Data),添加网络请求(必要时),调试与测试,根据测试结果优化改进,最后提交至App Store或其它平台发布。
32 0
|
12天前
|
安全 Swift iOS开发
【Swift 开发专栏】Swift 与 UIKit:构建 iOS 应用界面
【4月更文挑战第30天】本文探讨了Swift和UIKit在构建iOS应用界面的关键技术和实践方法。Swift的简洁语法、类型安全和高效编程模型,加上与UIKit的紧密集成,使开发者能便捷地创建用户界面。UIKit提供视图、控制器、布局、动画和事件处理等功能,支持灵活的界面设计。实践中,遵循设计原则,合理组织视图层次,运用布局和动画,以及实现响应式设计,能提升界面质量和用户体验。文章通过登录、列表和详情界面的实际案例展示了Swift与UIKit的结合应用。
|
12天前
|
存储 安全 Swift
【Swift 开发专栏】使用 Swift 开发一个简单的 iOS 应用
【4月更文挑战第30天】本文介绍了使用 Swift 开发简单 iOS 待办事项应用的步骤。首先,阐述了 iOS 开发的吸引力及 Swift 语言的优势。接着,详细说明了应用的需求和设计,包括添加、查看和删除待办事项的功能。开发步骤包括创建项目、界面搭建、数据存储、功能实现,并提供了相关代码示例。最后,强调了实际开发中需注意的细节和优化,旨在帮助初学者掌握 Swift 和 iOS 开发基础。
|
20天前
|
iOS开发 开发者 UED
利用SwiftUI构建动态列表:iOS开发的新范式
【4月更文挑战第22天】在本文中,我们将深入探讨如何使用SwiftUI来创建动态列表。SwiftUI是苹果最新推出的用户界面工具集,它允许开发者以声明式的方式描述用户界面,从而简化了代码的复杂性。我们将通过具体的代码实例,展示如何利用SwiftUI的List和ForEach视图来创建动态列表,并讨论其在实际开发中的应用。
20 2