iOS网络编程
2015-09-27 22:03
337 查看
一、使用NSURLConnection发送请求
NSURLConnection常见的发送请求方法有以下几种同步请求
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
异步请求:根据对服务器返回数据的处理方式不同又可以分为两种
block回调
+ (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler
代理:NSURLConnectionDataDelegate,在这种情况下需要调用start方法开始发送请求
/** * 请求错误(失败)的时候调用(请求超时、断网、没有网络,一般指客户端错误) */ - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; /** * 当接收到服务器的响应(连通了服务器)就会调用 */ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; /** * 当接收到服务器的数据就会调用(可能会被调用多次,每次调用只会传递部分数据) */ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; /** * 当服务器的数据接收完毕后就会调用 */ - (void)connectionDidFinishLoading:(NSURLConnection *)connection;
1. 发送GET请求
- (void)viewDidLoad { [super viewDidLoad]; NSString *username = @"zhangsan"; NSString *pwd = @"12345"; // 发送请求GET给服务器 // GET请求:请求行\请求头 // 1.设置请求路径 NSString *urlStr = [NSString stringWithFormat:@"http://localhost:8080/MJServer/login?username=%@&pwd=%@", username, pwd]; NSURL *url = [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; // 2.创建请求对象(默认就是GET请求) NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 3.发送请求(同步) // [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; // 在队列中执行请求(可同步也可异步) [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { // 服务器处理请求后返回的数据在这里进行解析,即解析data }]; }
2. 发送POST请求
- (void)viewDidLoad { [super viewDidLoad]; NSString *username = @"zhangsan"; NSString *pwd = @"12345"; // 发送请求POST给服务器 // POST请求:请求体 // 1.设置请求路径 NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login"]; // 2.创建请求对象(默认就是GET请求) NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 设置请求超时 request.timeoutInterval = 5; // 设置为POST请求 request.HTTPMethod = @"POST"; // 设置请求体 NSString *param = [NSString stringWithFormat:@"username=%@&pwd=%@", username, pwd]; request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding]; // 通过请求头告诉服务器客户端的类型 [request setValue:@"iOS" forHTTPHeaderField:@"User-Agent"]; // 3.发送请求(同步) // 在队列中执行请求(可同步也可异步) [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { // 服务器处理请求后返回的数据在这里进行解析,即解析data }]; }
二、大文件下载
小文件下载直接用NSData的+ (instancetype)dataWithContentsOfURL:(NSURL *)url;
利用NSURLConnection发送一个HTTP请求去下载
如果是下载图片,可以利用SDWebImage框架
1. 简单下载
@property (nonatomic, strong) NSFileHandle *writeHandle; - (void)viewDidLoad { [super viewDidLoad]; // 创建并发送请求 NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/video.zip"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection connectionWithRequest:request delegate:self]; } #pragma mark - NSURLConnectionDataDelegate 代理方法 /** * 当接收到服务器的响应(连通了服务器)就会调用 */ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { // 1.文件的存储路径 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString *filePath = [caches stringByAppendingPathComponent:@"video.zip"]; // 2.创建一个空的文件到沙盒中 NSFileManager *manager = [NSFileManager defaultManager]; // 刚创建完毕的大小是0字节 [manager createFileAtPath:filePath contents:nil attributes:nil]; // 3.创建写数据的文件句柄 self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filePath]; } /** * 当接收到服务器的数据就会调用(可能会被调用多次,每次调用只会传递部分数据) */ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { // 移动到文件的尾部 [self.writeHandle seekToEndOfFile]; // 从当前移动的位置(文件尾部)开始写入数据 [self.writeHandle writeData:data]; } /** * 当服务器的数据接收完毕后就会调用 */ - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // 关闭连接(不再输入数据到文件中) [self.writeHandle closeFile]; }
2. 暂停、恢复下载
思路:当暂停下载是请求就已经结束了,要恢复下载需要重新发送请求。可以在发送请求时设置请求头告诉服务器从哪里开始下载。// 只下载前100个字节 [request setValue:@"bytes=0-99" forKey:@"Range"];
Range示例
bytes=0-99 从0到100的头100个字节
bytes=500-999 从500到999的第二个500租户额
bytes=500- 从500字节以后的所有字节
bytes=-500 最后的500字节
bytes=500-599,800-899 同时指定几个范围
三、NSURLCache缓存
一般只对GET请求进行缓存,不必对POST请求进行缓存。NSURLCache的常见用法
获得全局缓存对象(没必要手动创建)
NSURLCache *cache = [NSURLCache sharedURLCache];
设置内存缓存的最大容量(单位是字节,默认为512KB)
@property NSUInteger memoryCapacity;
设置硬盘缓存的最大容量(单位是字节,默认为10MB),硬盘缓存位置:沙盒/Library/Caches
@property NSUInteger diskCapacity;
只要设置了缓存策略,系统就会自动利用NSURLCache进行数据缓存
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 设置缓存策略 request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;
iOS对NSURLRequest提供了7中缓存策略(实际上只有4中可用)
// 默认的缓存策略(取决于协议) NSURLRequestUseProtocolCachePolicy = 0, // 忽略缓存,重新请求 NSURLRequestReloadIgnoringLocalCacheData = 1, //未实现(不可用) NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // 忽略缓存,重新请求 NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData, // 有缓存就用缓存,没缓存就重新请求 NSURLRequestReturnCacheDataElseLoad = 2, // 有缓存就用缓存,没有缓存就不发送请求,当做请求出错处理(离线模式) NSURLRequestReturnCacheDataDontLoad = 3, //未实现(不可用) NSURLRequestReloadRevalidatingCacheData = 5,
缓存的相关操作
NSURLCache *cache = [NSURLCache sharedURLCache]; // 取得某个请求的缓存 NSCachedURLResponse *response = [cache cachedResponseForRequest:request]; if (response) { NSLog(@"这个请求已经存在缓存"); }else { NSLog(@"这个请求没有缓存"); } // 清除某个请求的缓存 [cache removeCachedResponseForRequest:request]; // 清除所有缓存 [cache removeAllCachedResponses];
四、检测网络状态
苹果官方提供了一个叫Reachability的示例程序,便于开发者检测网络状态https://developer.apple.com/library/ios/samplecode/Reachability/Reachability.zip
将Reachability.h和Reachability.m拖放到项目中,并导入SystemConfiguration.framework即可使用Reachability。
// 检测wifi状态 Reachability *wifi = [Reachability reachabilityForLocalWiFi]; if ([wifi currentReachabilityStatus] != NotReachable) { NSLog(@"有wifi"); }else { NSLog(@"无wifi"); } // 检测手机自带网络功能(能否上网) Reachability *connection = [Reachability reachabilityForInternetConnection]; if ([connection currentReachabilityStatus] != NotReachable) { NSLog(@"有网络"); }else { NSLog(@"无网络"); }
较老版本的Reachability是使用非ARC编写的,需要在项目的Build Phases的Complie Sources修改Reachability.m文件的Complie Flags为-fno--objc-arc
五、使用AFNetworking发送请求
github地址:https://github.com/AFNetworking/AFNetworking导入主头文件: #import "AFNetworking.h"
要使用AFN发送请求,需要先创建一个请求管理者
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
然后只需调用block即可发送HTTP请求
/** * 发送GET请求 * @param GET: 请求地址 * @param parameters: 请求参数 */ [manager GET:@"" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { // 请求成功时的回调 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // 请求失败时的回调 }]; /** * 发送POST请求 * @param POST: 请求地址 * @param parameters: 请求参数 */ [manager POST:@"" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { // 请求成功时的回调 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // 请求失败时的回调 }];
使用AFNetworking发送请求实例
下面以获取新浪OAuth授权的接口文档为例子。用AFN向新浪服务器发送请求![](https://images2015.cnblogs.com/blog/806466/201509/806466-20150928104230777-945604679.png)
发送POST请求代码:
// 创建请求管理类 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; // 设置请求参数 NSMutableDictionary *params = [NSMutableDictionary dictionary]; params[@"client_id"] = @"2740450720"; params[@"client_secret"] = @"717606369d8f7dcda59d78f4b25e8e30"; params[@"grant_type"] = @"authorization_code"; params[@"code"] = code; params[@"redirect_uri"] = @"http://www.baidu.com"; // 发送请求 [manager POST:@"https://api.weibo.com/oauth2/access_token" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { // 请求成功 NSString *accessToken = responseObject[@"access_token"]; NSLog(@"请求成功:%@ - %@", responseObject ,accessToken); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // 请求失败 NSLog(@"请求失败:%@", error); }];
发送GET请求和发送POST请求的操作步骤相同,只是调用的方法不同而已。同样将get请求的参数用一个字典装起来作为请求参数即可。
相关文章推荐
- 网络编程 select模型
- TCP应用层主要协议
- CentOS 7 安装lamp,并实现https
- c# HttpWebRequest post和get请求http
- 使用adb将tcpdump的流量导到wireshark
- ImageCache——图片三级缓存(内存、文件、网络)
- WebView(网络视图)
- 《Python网络编程基础》第四章 域名系统
- 网络知识小笔记
- HDU 5493 Queue (合肥网络赛 1010 )
- HDU 5489 Removed Interval (合肥网络赛 1006 )
- No mapping found for HTTP request with URI [/...] in DispatcherServlet with name ...的解决方法
- sendmsg和recvmsg
- HDU 5491 The Next (二进制) 2015合肥网络赛
- Android之Http沟通——4.Android HTTP索取信息:HttpClient
- 【2015/9/27】Linux学习日志_Day2 终端命令 一些网络命令
- 黑马程序员——网络编程
- HDU 5478 Can you find it 2015ICPC上海网络赛
- HDU 5492 Find a path (dp) 2015合肥网络赛
- 大型网站的 HTTPS 实践(1):HTTPS 协议和原理