首页 > 学院 > 开发设计 > 正文

iOS网络编程

2019-11-14 18:14:48
字体:
来源:转载
供稿:网友

一、使用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请求

 1 - (void)viewDidLoad { 2     [super viewDidLoad]; 3      4     NSString *username = @"zhangsan"; 5     NSString *pwd = @"12345"; 6  7     // 发送请求GET给服务器 8     // GET请求:请求行/请求头 9     10     // 1.设置请求路径11     NSString *urlStr = [NSString stringWithFormat:@"http://localhost:8080/MJServer/login?username=%@&pwd=%@", username, pwd];12     NSURL *url = [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];13     14     // 2.创建请求对象(默认就是GET请求)15     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];16     17     // 3.发送请求(同步)18 //    [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];19     20     // 在队列中执行请求(可同步也可异步)21     [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {22         // 服务器处理请求后返回的数据在这里进行解析,即解析data23     }];24 }

2. 发送POST请求

 1 - (void)viewDidLoad { 2     [super viewDidLoad]; 3      4     NSString *username = @"zhangsan"; 5     NSString *pwd = @"12345"; 6  7     // 发送请求POST给服务器 8     // POST请求:请求体 9     10     // 1.设置请求路径11     NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login"];12     13     // 2.创建请求对象(默认就是GET请求)14     NSURLRequest *request = [NSURLRequest requestWithURL:url];15     // 设置请求超时16     request.timeoutInterval = 5;17     // 设置为POST请求18     request.HTTPMethod = @"POST";19     // 设置请求体20     NSString *param = [NSString stringWithFormat:@"username=%@&pwd=%@", username, pwd];21     request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];22     23     // 通过请求头告诉服务器客户端的类型24     [request setValue:@"iOS" forHTTPHeaderField:@"User-Agent"];25     26     27     // 3.发送请求(同步)28     // 在队列中执行请求(可同步也可异步)29     [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {30         // 服务器处理请求后返回的数据在这里进行解析,即解析data31     }];32 }

二、大文件下载

小文件下载

  • 直接用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. 暂停、恢复下载

思路:当暂停下载是请求就已经结束了,要恢复下载需要重新发送请求。可以在发送请求时设置请求头告诉服务器从哪里开始下载。

1     // 只下载前100个字节2     [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进行数据缓存

1     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];2     // 设置缓存策略3     request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

iOS对NSURLRequest提供了7中缓存策略(实际上只有4中可用)

// 默认的缓存策略(取决于协议)NSURLRequestUseProtocolCachePolicy = 0,// 忽略缓存,重新请求NSURLRequestReloadIgnoringLocalCacheData = 1,//未实现(不可用)NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4,// 忽略缓存,重新请求NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,// 有缓存就用缓存,没缓存就重新请求NSURLRequestReturnCacheDataElseLoad = 2,// 有缓存就用缓存,没有缓存就不发送请求,当做请求出错处理(离线模式)NSURLRequestReturnCacheDataDontLoad = 3,//未实现(不可用)NSURLRequestReloadRevalidatingCacheData = 5,

缓存的相关操作

 1     NSURLCache *cache = [NSURLCache sharedURLCache]; 2     // 取得某个请求的缓存 3     NSCachedURLResponse *response = [cache cachedResponseForRequest:request]; 4     if (response) { 5         NSLog(@"这个请求已经存在缓存"); 6     }else { 7         NSLog(@"这个请求没有缓存"); 8     } 9     // 清除某个请求的缓存10     [cache removeCachedResponseForRequest:request];11     // 清除所有缓存12     [cache removeAllCachedResponses];

四、检测网络状态

苹果官方提供了一个叫Reachability的示例程序,便于开发者检测网络状态

https://developer.apple.com/library/ios/samplecode/Reachability/Reachability.zip

将Reachability.h和Reachability.m拖放到项目中,并导入SystemConfiguration.framework即可使用Reachability。

 1     // 检测wifi状态 2     Reachability *wifi = [Reachability reachabilityForLocalWiFi]; 3     if ([wifi currentReachabilityStatus] != NotReachable) { 4         NSLog(@"有wifi"); 5     }else { 6         NSLog(@"无wifi"); 7     } 8      9     // 检测手机自带网络功能(能否上网)10     Reachability *connection = [Reachability reachabilityForInternetConnection];11     if ([connection currentReachabilityStatus] != NotReachable) {12         NSLog(@"有网络");13     }else {14         NSLog(@"无网络");15     }

较老版本的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请求

 1     /** 2      *  发送GET请求 3      *  @param GET: 请求地址 4      *  @param parameters: 请求参数 5      */ 6     [manager GET:@"" parameters:params success:^(AFHTTPRequestOperation *operation, id responSEObject) { 7         // 请求成功时的回调 8     } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 9         // 请求失败时的回调10     }];11     12     /**13      *  发送POST请求14      *  @param POST: 请求地址15      *  @param parameters: 请求参数16      */17     [manager POST:@"" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {18         // 请求成功时的回调19     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {20         // 请求失败时的回调21     }];

使用AFNetworking发送请求实例

下面以获取新浪OAuth授权的接口文档为例子。用AFN向新浪服务器发送请求

发送POST请求代码:

 1     // 创建请求管理类 2     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 3      4     // 设置请求参数 5     NSMutableDictionary *params = [NSMutableDictionary dictionary]; 6     params[@"client_id"] = @"2740450720"; 7     params[@"client_secret"] = @"717606369d8f7dcda59d78f4b25e8e30"; 8     params[@"grant_type"] = @"authorization_code"; 9     params[@"code"] = code;10     params[@"redirect_uri"] = @"http://www.baidu.com";11     12     // 发送请求13     [manager POST:@"https://api.weibo.com/oauth2/access_token" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {14         // 请求成功15         NSString *accessToken = responseObject[@"access_token"];16         NSLog(@"请求成功:%@ - %@", responseObject ,accessToken);17     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {18         // 请求失败19         NSLog(@"请求失败:%@", error);20     }];21     

发送GET请求和发送POST请求的操作步骤相同,只是调用的方法不同而已。同样将get请求的参数用一个字典装起来作为请求参数即可。

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表