iOS开发之网络编程(一)

iOS9引入了新特性App Transport Security (ATS)。新特性要求App内访问的网络必须使用HTTPS协议。但是现在公司的项目使用的是HTTP协议,使用私有加密方式保证数据安全。现在也不能马上改成HTTPS协议传输。

最终找到以下解决办法:

Info.plist中添加NSAppTransportSecurity类型Dictionary。

在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES,如图:


下面来介绍iOS开发中网络编程实现方案:NSURLConnection

苹果原生(自带)的网络编程API:NSURLConnection

NSURL:请求地址

NSURLRequest:封装一个请求,保存发给服务器的全部数据,包括:一个NSURL对象、请求方法、请求头、请求体等等

NSMutableURLRequest:NSURLRequest的子类

NSURLConnection

负责发送请求,建立客户端和服务器的连接

发送NSURLRequest的数据给服务器,并收集来自服务器的响应数据

NSURLConnection的使用步骤

1.    创建一个NSURL对象,设置请求路径

2.    传入NSURL创建一个NSURLRequest对象,设置请求头和请求体(可不用设置

3.    使用NSURLConnection发送NSURLRequest

下面是向网络请求一张图片数据的代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建url
    NSURL *url = [NSURL URLWithString:@"http://a2.att.hudong.com/38/59/300001054794129041591416974.jpg"];
    
    // 创建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 建立连接,并异步发送请求(这里就不赘述原因了)
    NSOperationQueue *<span style="color:#3333FF;">queue</span> = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:request queue:<span style="color:#3333FF;">queue</span> completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        NSLog(@"%lu---%@", data.length, [NSThread currentThread]);
    }];
}

打印结果:

注意:在block中有数据返回,且数据长度为79064,但是block中的执行代码是在number = 2的线程中,因为之前创建的一个新线程。在block中获得数据后,应该在主线程刷新\显示数据,所以这里不能是子线程,只能是主线程,queue的参数应该传:[NSOperationQueue mainQueue]

此时运行结果:

总结:NSURLConnection发送请求方式:

1.同步请求

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;

2.异步请求:根据对服务器返回数据的处理方式的不同,又可以分为2种

1)block回调

+(void)sendAsynchronousRequest:(NSURLRequest*)request queue:(NSOperationQueue*) queue 
completionHandler:(void (^)(NSURLResponse* response, NSData* data,NSError* connectionError)) handler;

2)代理

- (id)initWithRequest:(NSURLRequest*)request delegate:(id)delegate;

+(NSURLConnection*)connectionWithRequest:(NSURLRequest *)requestdelegate:(id)delegate;

- (id)initWithRequest:(NSURLRequest*)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;

在这种情况下,需要调用start方法开始发送请求

- (void)start;

成为NSURLConnection的代理,最好遵守 NSURLConnectionDataDelegate协议

用上面请求图片的例子,使用代理的方法请求

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建url
    NSURL *url = [NSURL URLWithString:@"http://a2.att.hudong.com/38/59/300001054794129041591416974.jpg"];
    
    // 创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 设置请求超时
    request.timeoutInterval = 10.0;
    request.HTTPMethod = @"GET";// 默认GET
    
    // 建立连接,发送请求(异步)
// NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
// NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
// NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:<span style="color:#ff0000;">YES</span>];
// 上面三种方式发送异步请求是一样的,不需要调用start方法即可发送异步请求。
    
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
    [conn start];// 这种方式需要调用start方法,发送异步请求操作
    NSLog(@"请求已经发出");
}

#pragma mark -NSURLConnectionDataDelegate
/**
 *  开始接收到服务器的响应时调用
 */
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    self.data = [NSMutableData data];
    NSLog(@"开始接收数据- %@", [NSThread currentThread]);
}
/**
 *  接收到服务器返回的数据时调用(服务器返回的数据比较大时会调用多次)
 */
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.data appendData:data];
    NSLog(@"接收到服务器返回的数据时调用- %@", [NSThread currentThread]);
}
/**
 *  服务器返回的数据完全接收完毕后调用
 */
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"完全接收完毕--%lu--%@", self.data.length, [NSThread currentThread]);
}
/**
 *  请求出错时调用(比如请求超时)
 */
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"请求出错");
}

 

当控制器view加载完毕后,会打印出:请求已经发出。说明发送的请求是异步的,没有阻塞主线程。请求之后会回调代理方法,代理方法是在主线程的返回数据的。

运行结果:

NSMutableURLRequest

NSMutableURLRequest NSURLRequest 的子类,常用方法有
设置请求超时等待时间(超过这个时间就算超时,请求失败)

- (void)setTimeoutInterval:(NSTimeInterval)seconds;

设置请求方法(比如 GET POST

- (void)setHTTPMethod:(NSString*)method;

设置请求体

- (void)setHTTPBody:(NSData*)data;

设置请求头

- (void)setValue:(NSString*)value forHTTPHeaderField:(NSString*)field;

创建GET请求
NSString *urlStr = [@"http://192.168.1.102:8080/MJServer/login?name=shx&pwd=123" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSURL *url = [NSURLURLWithString:urlStr];

NSMutableURLRequest*request = [NSMutableURLRequestrequestWithURL:url];
创建POST请求
NSString*urlStr = @"http://192.168.1.102:8080/MJServer/login";

NSURL *url= [NSURLURLWithString:urlStr];

NSMutableURLRequest*request = [NSMutableURLRequestrequestWithURL:url];

request.HTTPMethod = @"POST";

// 请求体

NSString *bodyStr = @"name=shx&pwd=123";

request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];// 编码

iOS 7之后NSURLConnection就过期了,新出了NSURLSession替代NSURLConnection,用法差不多,如下(只是简单的使用NSURLSession):

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建url
    NSURL *url = [NSURL URLWithString:@"http://a2.att.hudong.com/38/59/300001054794129041591416974.jpg"];
    
    // 创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 设置请求超时
    request.timeoutInterval = 10.0;
    request.HTTPMethod = @"GET";// 默认GET
    
    // 1.创建NSURLSession
    NSURLSession *session = [NSURLSession sharedSession];
    // 2.利用NSURLSession创建Task
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        /*
         data: 服务器返回给我们的数据
         response : 响应头
         error: 错误信息
         */
        NSLog(@"%lu-%@", data.length, [NSThread currentThread]);
    }];
    // 3.执行Task
    [task resume];
}
运行结果:

注意:block也是在子线程中返回数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值