目录展开

目录
网络请求
1,用 NSString 创建 URL
2,创建 NSURL 对象:用 URLSession 对象进行网络请求
3,创建 URLRequeset 对其进行相关请求,分为 GET 和 POST 方法
4,根据会话创建任务
5,启动任务

在与 web 服务器进行通信的过程中,这些类各自扮演了重要的角色。
NSURL对象负责以 URL 的格式保存 web 应用的位置。对大多数 web 服务,URL 将包含基地址(base address)、web 应用名和需要传送的参数。
NSURLRequest对象负责保存需要传送给 web 服务器的全部数据,这些数据包括:一个NSURL对象、缓存方案(caching policy)、等待 web 服务器响应的最长时间和需要通过 HTTP 协议传送的额外信息(NSMutableURLRequest 是 ** NSURLRequest** 的可变子类)。
每一个NSURLSessionTask对象都表示一个NSURLRequest 的生命周期。NSURLSessionTask可以跟踪 NSURLRequest 的状态,还可以对 NSURLRequest 执行取消、暂停和继续操作。NSURLSessionTask 有多种不同功能 的子类,包括NSURLSessionDataTask,NSURLSessionUploadTask 和 ** NSURLSessionUDownloadTask** 。
NSURLSession对象可以看作是一个生产NSURLSessionTask对象的工厂。可以设置其生产出的NSURLSessionTask对象的通用属性,例如请求头的内容、是否允许在蜂窝网络下发送请求等。NSURLSession 对象还有一个功能强大的委托,可以跟踪 NSURLSessionTask 对象的状态、处理服务器的认证要求等。
-(void) fetchData { //1、创建URL NSString *key = @"YOUR_WEATHERAPI_KEY"; // 示例占位符;真实密钥不得硬编码或提交到仓库 NSURLComponents *components = [NSURLComponents componentsWithString:@"https://api.weatherapi.com/v1/forecast.json"]; components.queryItems = @[ [NSURLQueryItem queryItemWithName:@"key" value:key], [NSURLQueryItem queryItemWithName:@"q" value:self.cityName], [NSURLQueryItem queryItemWithName:@"days" value:@"7"], [NSURLQueryItem queryItemWithName:@"lang" value:@"zh"], [NSURLQueryItem queryItemWithName:@"aqi" value:@"yes"] ]; //2、创建URL对象 NSURL *url = components.URL; //3、创建URL Request,创建任务 NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSDictionary *weatherDic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; self.weatherData = weatherDic; //最终数据落脚在weatherData NSLog(@"%@",weatherDic); dispatch_async(dispatch_get_main_queue(), ^{ /* 分别显示基本天气 每日天气 每小时天气 */ [self setupWeatherData]; [self setupDailyForecastData]; [self setupHourlyForecastData]; }); }]; //启动任务 [task resume];}
为什么你的图片要异步加载?
在仿写天气预报时,我们常常需要从网络加载天气图标,例如显示某个小时的天气状态图标。这看似简单的事情,如果处理不当,却很容易造成界面卡顿,甚至影响整个 App 的用户体验。
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];self.weatherIcon.image = [UIImage imageWithData:data];这段同步读取本身会阻塞调用它的线程;只有从主线程调用时才会阻塞主线程。
- 若在主线程或 TableView 滚动回调中执行,网络等待会阻塞主线程并导致卡顿。
UIKit 的界面状态更新和事件处理通常应在主线程;具体渲染由系统渲染管线处理。
dataWithContentsOfURL: 是同步 API;编译器通常不会自动提示它可能阻塞主线程。
因此,我们需要异步网络请求。
什么是 “异步网络请求”
URLSession 异步调度网络 I/O,并通过回调或代理交付结果;回调队列由会话配置决定。若需要更新 UI,应显式切回主线程。
1,URLSession + completion handler(块回调)
最常用、简单。适合大多数 GET/POST、加载图片等。
2,URLSession + delegate(代理)
适合需要 “边下边写文件/显示进度/断点续传” 的下载或大文件上传。
3,URLSession + background session
App 退到后台仍能传输(系统托管),适合较大文件上传下载。
异步加载 + 主线程更新 UI
下面是一段优化后的代码:
- (void)loadWeatherIcon:(NSString *)urlString { NSURL *url = [NSURL URLWithString:urlString]; NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (data) { UIImage *image = [UIImage imageWithData:data]; dispatch_async(dispatch_get_main_queue(), ^{ self.weatherIcon.image = image; }); } }]; [task resume];}这段代码我们使用的是第一种:URLSession + completion handler 的 dataTask 异步请求。
解释:
dataTask : 适合获取内存数据(图片,JSON)
回调方式:completion handler 在请求完成后由会话回调队列执行;具体线程取决于 session/delegate queue 配置,UI 更新应切回主队列。
配置:sharedSession
dataTaskWithURL: 会异步执行网络任务,不会等待网络响应后才返回;完成回调运行于会话的回调队列,具体线程不应写成固定线程池。更新 UI 时应显式切回主队列。
- dispatch_async (dispatch_get_main_queue (), ^{…}) 是我们手动回到主线程更新 UI
使用异步请求后,会显著提升页面响应速度。
至于线程及其他本人暂时还未了解,以后再来填坑。

GET 与 POST
GET
优点:请求资源和查询参数通常由 URL 表示,易于分享、缓存或重放;查询参数不应承载密码、访问令牌等敏感信息。 缺点:参数通常编码在 URL 中,敏感信息可能进入浏览器历史、服务端或代理日志;传输是否加密取决于 HTTPS/TLS,而不是 GET 方法本身。
NSString *urlString = @"https://api.weatherapi.com/v1/current.json?key=xxx&q=beijing";NSURL *url = [NSURL URLWithString:urlString];NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (!error) { NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSLog(@"%@", json); } }];[task resume];#### POST
POST 常把数据放在请求体中,但请求体不是密文;是否加密取决于是否使用 HTTPS/TLS。它适合按接口约定发送结构化或较大载荷,实际容量仍受各层配置限制。缺点:需要按接口约定构造请求方法、请求头、请求体和编码;POST 也可由浏览器发送,不能作为保密机制。HTTP 协议没有统一的“GET最多1024字节、POST无限制”规则;URI、请求头和请求体大小都可能受客户端、服务端、代理或网关限制。
因为post我还没详细了解,给出一段ai代码:
```objective-cNSURL *url = [NSURL URLWithString:@"https://example.com/api/login"];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];request.HTTPMethod = @"POST";
// 参数放在请求体NSString *bodyString = @"username=YOUR_USERNAME&password=YOUR_PASSWORD";request.HTTPBody = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
// 设置请求头[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (!error) { NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSLog(@"%@", json); } }];[task resume];因为本人的这个天气预报类似于一个小 demo,所以使用 GET,较为简便
原文发布于 CSDN:【iOS】网络请求与异步加载