iOS基础 - 网络:Get和Post | NSURLConnection

▶ NSURLConnection

1 - NSURLConnection 已被 NSURLSession 所代替,在 WWDC2013 上 NSURLSession 随 iOS 7 一起发布,它是对 NSURLConnection 重构、优化后的新的网络访问接口。从 iOS 9.0 开始 NSURLConnection 中发送请求的两个方法已过期(同步请求、异步请求),并且初始化网络连接 initWithRequest: delegate: 方法也被置为过期,不再推荐使用

2 - 我们在开发中常用到的类

① NSURLRequest/NSMutableURLRequest:封装一个请求,用来保存发给服务器的全部数据。它包括 NSURL 对象,请求方法、请求头、请求体....

② NSURLConnection:负责发送请求、建立客户端和服务器的连接,发送 NSURLRequest 的数据给服务器,并收集来自服务器的响应数据

3 - 发送请求步骤

① 配置请求路径,就是 NSURL 对象:URL 作为网址字符串包含很多请求参数,它对网址字符串进行封装,我们可以使用 NSURL 对象获取相应的参数

② 创建请求对象,就是 NSURLRequest 对象:包含请求头和请求体

③ 发送请求:使用 NSURLConnection 发送 NSURLRequest

4 - 请求方式

① 同步请求:在主线程中完成,程序会一直在等待服务器返回数据,正在进行网络请求的代码,其后的程序代码不再执行!一旦服务器没有返回数据,那么在主线程的 UI 就会卡顿

② 异步请求:在子线程中进行,不会造成 UI 假死的问题,无网络返回数据。如果要监听服务器返回的数据,要配合 <NSURLConnectionDataDelegate> 协议使用,或者使用 Block

5 - NSMutableURLRequest

// 请求超时等待时间
- (void)setTimeoutInterval:(NSTimeInterval)seconds;
// 请求方法(Get/Post)
- (void)setHTTPMethod:(NSString *)method;
// 请求体
- (void)setHTTPBody:(NSData *)data;
// 请求头
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

▶ Get | Post

1 - 相同点:两者均可以请求或者提交数据。Get 通常用于获取数据;Post 通常用于提交数据

2 - 不同点

① 请求的格式不一样

Get 请求接口的地址和参数之间用 ? 连接,参数与参数之间使用 & 连接,每一个参数的 键/值 用 = 连接

Post 请求是把参数转成 NSData 后放在 HttpBody 中提交给服务器

② 安全程度不一样

Get 请求可以直接看到请求的参数

Post 请求看不到请求参数

注:Get 网址字符串最多 255 字节;而 Post 使⽤ NSData,容量可超过 1G

      iOS 中任何 NSURLRequest 默认都是 Get

代码示例实现网络请求。UI 布局如下图(点击 下载图片 后的效果图)

// - ViewController.m

复制代码
  1 #import "ViewController.h"
  2 #define SCREEN_WIDTH   [UIScreen mainScreen].bounds.size.width
  3 @interface ViewController ()
  4 
  5 @property(nonatomic,strong)NSMutableData *data; // 数据容器:存放服务器返回的数据
  6 @property(nonatomic,strong)NSURLConnection *connection;
  7 
  8 @end
  9 
 10 @implementation ViewController
 11 
 12 - (void)viewDidLoad {
 13     
 14     [super viewDidLoad];
 15     self.view.backgroundColor = [UIColor cyanColor];
 16     
 17     // 请求按钮
 18     [self addBUttonWithFrame:CGRectMake(100, 50,  SCREEN_WIDTH - 200, 40) title:@"异步 Get" target:self selector:@selector(asynchronizeGet)];
 19     [self addBUttonWithFrame:CGRectMake(100, 120, SCREEN_WIDTH - 200, 40) title:@"异步 Post" target:self selector:@selector(asynchronizePost)];
 20     [self addBUttonWithFrame:CGRectMake(100, 190, SCREEN_WIDTH - 200, 40) title:@"同步 Get" target:self selector:@selector(synchronizeGet)];
 21     [self addBUttonWithFrame:CGRectMake(100, 260, SCREEN_WIDTH - 200, 40) title:@"同步 Post" target:self selector:@selector(synchronizePost)];
 22     [self addBUttonWithFrame:CGRectMake(100, 330, SCREEN_WIDTH - 200, 40) title:@"下载图片" target:self selector:@selector(downLoadImage)];
 23     
 24     //将要下载的图片
 25     UIImageView *aImageView = [[UIImageView alloc] initWithFrame:CGRectMake(30, 400,  SCREEN_WIDTH-60, 220)];
 26     aImageView.backgroundColor = [UIColor blackColor];
 27     aImageView.layer.masksToBounds = YES;
 28     aImageView.layer.cornerRadius = 10;
 29     aImageView.tag = 100;
 30     [self.view addSubview:aImageView];
 31 }
 32 
 33 // 创建按钮
 34 - (void)addBUttonWithFrame:(CGRect)frame title:(NSString *)title target:(id)target selector:(SEL)sel{
 35     
 36     UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
 37     button.layer.cornerRadius = 10;
 38     button.frame = frame;
 39     [button setTitle:title forState:UIControlStateNormal];
 40     [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
 41     [button addTarget:target action:sel forControlEvents:UIControlEventTouchUpInside];
 42     button.backgroundColor = [UIColor blackColor];
 43     [self.view addSubview:button];
 44 }
 45 
 46 // 异步 Get
 47 - (void)asynchronizeGet{
 48     
 49     // -------------- 方式一:配合代理 ------------------
 50     // 配置请求路径
 51     NSString *urlString = @"http://api.map.baidu.com/place/v2/search?query=银行&region=郑州&output=json&ak=6E823f587c95f0148c19993539b99295";
 52     // 算是一个安全保障机制:把请求路径进行 URLEncode 编码,防止路径中含有汉字而造成编译不通过的问题
 53     NSString *newUrlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 54     NSURL *URL = [NSURL URLWithString:newUrlString];
 55     
 56     // 请求对象:根据 URL 对象生成请求
 57     NSURLRequest *requst = [NSURLRequest requestWithURL:URL];
 58     // 发送请求
 59     [NSURLConnection connectionWithRequest:requst delegate:self];
 60     
 61     
 62     // --------------- 方式二:使用 Block ------------------
 63     NSString *urlStr_bl = [NSString stringWithFormat:@"http://api.map.baidu.com/place/v2/search?query=银行&region=郑州&output=json&ak=6E823f587c95f0148c19993539b99295"];
 64     NSString *newUrlStr_bl = [urlStr_bl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 65     NSURL *url_bl = [NSURL URLWithString:newUrlStr_bl];
 66     NSURLRequest *request_bl = [NSURLRequest requestWithURL:url_bl];
 67     
 68     // 主队列
 69     NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
 70     // 异步请求
 71     [NSURLConnection sendAsynchronousRequest:request_bl queue:mainQueue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
 72         
 73         // 简单地验证下是否拿到数据
 74         if (data) {
 75             NSLog(@"Get_Block:%@---%lu", [NSThread currentThread],data.length);
 76             // 解析数据
 77             NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
 78             NSLog(@"Get_Block:Dic = %@",dict);
 79         }else{
 80             NSLog(@"Get_Block:Error = %@",connectionError);
 81         }
 82     }];
 83 }
 84 
 85 // 同步 Get
 86 - (void)synchronizeGet{
 87     
 88     NSString *imageUrl = @"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdik.img.kttpdq.com%2Fpic%2F69%2F47802%2Fb120a7942a39e844_1680x1050.jpg&refer=http%3A%2F%2Fdik.img.kttpdq.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639510061&t=dfb29886b6c2c1741cd4492a39e036bb";
 89     NSURL *url = [NSURL URLWithString:imageUrl];
 90     NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:3.0];
 91     // 同步请求有网络返回数据,并且任务在主线程完成,数据未下载完就不会往下执行,容易导致 UI 假死的问题
 92     NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
 93     UIImage *aIamge = [UIImage imageWithData:data];
 94     UIImageView *imageView = (UIImageView *)[self.view viewWithTag:100];
 95     imageView.image = aIamge;
 96 }
 97 
 98 // 异步P ost
 99 - (void)asynchronizePost{
100     
101     NSString *urlString = @"http://api.tudou.com/v3/gw";
102     NSURL *url = [NSURL URLWithString:urlString];
103     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:3.0];
104     // 请求方式
105     [request setHTTPMethod:@"POST"];
106     // 配置参数
107     NSString *paramString = @"method=user.item.get&appKey=43db911a75b88c11&format=json&user=ttr2008&pageNo=1&pageSize=10";
108     NSData *paramData = [paramString dataUsingEncoding:NSUTF8StringEncoding];
109     // 将参数放进请求体中
110     [request setHTTPBody:paramData];
111     // 需使用代理
112     [NSURLConnection connectionWithRequest:request delegate:self];
113 }
114 
115 // 同步 Post
116 - (void)synchronizePost{
117     
118     NSString *urlString = @"http://api.tudou.com/v3/gw";
119     NSURL *url = [NSURL URLWithString:urlString];
120     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:3.0];
121     [request setHTTPMethod:@"POST"];
122     NSString *paramString =@"method=user.item.get&appKey=43db911a75b88c11&format=json&user=ttr2008&pageNo=1&pageSize=10";
123     NSData *data = [paramString dataUsingEncoding:NSUTF8StringEncoding];
124     [request setHTTPBody:data];
125     NSData *resultData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
126     
127     // 注:要牢记同步请求有数据返回
128     NSLog(@"同步Post的Data == %@",resultData);
129     if(resultData){
130         NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:resultData options:0 error:nil];
131         NSLog(@"同步Post响应数据 == %@",dic);
132     }
133 }
134 
135 // 下载图片
136 - (void)downLoadImage{
137     
138     NSString *imageURLString = @"https://img0.baidu.com/it/u=2364709123,290344084&fm=253&fmt=auto&app=120&f=JPEG?w=1416&h=800";
139     NSURL *url = [NSURL URLWithString:imageURLString];
140     NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:3.0];
141     // 使用代理
142     self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
143 }
144 
145 
146 #pragma mark - <NSURLConnectionDelegate>
147 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
148     NSLog(@"---didReceiveResponse---");
149     
150     // 在这里创建的好处:清空冗余数据
151     // 一般地,在收到服务器传来的数据时接收的网络数据是二进制数据
152     self.data = [NSMutableData data];// 所以我们使用 NSMutableData
153     
154     // 终止请求
155     // [self.connection cancel];
156 }
157 
158 // NSURLConnection 收到服务器传回的数据:可能会调用多次,因为每次只传递部分数据
159 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
160     NSLog(@"---didReceiveData---");
161     
162     // 接受数据:将数据放进 self.data 中
163     [self.data appendData:data];
164 }
165 
166 // NSURLConnection 请求完成
167 - (void)connectionDidFinishLoading:(NSURLConnection *)connection{
168     NSLog(@"---didFinishLoading---");
169     
170     // 若存在多个请求,判断处理即可
171     if (connection == self.connection) {
172         
173         UIImage *aIamge = [UIImage imageWithData:self.data];
174         UIImageView *imageView = (UIImageView *)[self.view viewWithTag:100];
175         imageView.image = aIamge;
176         
177     }else{
178         
179         // 捕获错误
180         NSError *error = nil;
181         NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:&error];
182         if (error) {
183             NSLog(@"error = %@",error);
184         }
185         NSLog(@"dic = %@",dic);
186         NSLog(@"length = %ld",self.data.length);
187     }
188 }
189 
190 // NSURLConnection 请求失败
191 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
192     
193     NSLog(@"---didFailWithError---%@",error);
194 }
195 
196 @end
复制代码

注:如果使用了 http 协议进行网络请求,运行则会报 App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app‘s Info.plist file 的错误。这是因为在 iOS 9 中苹果将原 http 协议改成了 https 协议,使用 TLS1.2 SSL 加密请求数据。若要坚持使用 http 协议则需要在 Info.plist 文件中添加 App Transport SecuritySettings(Dictionary 型数据),并在 Dictionary 中添加 Allow Arbitray Loads(Bool 型数据,置 YES 即可)

 

posted on   低头捡石頭  阅读(63)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示