您的位置:首页 > 理论基础 > 计算机网络

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向新浪服务器发送请求



发送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请求的参数用一个字典装起来作为请求参数即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: