本文介绍iOS中几种常见的iOS客户端与服务端进行网络交互的方案以及使用过程中需要注意的事项。
NSURLConnection
发送请求跟服务器交互,iOS中可以使用NSURLConnection类操作。
创建一个NSURL对象,设置请求路径
//这里对字符串进行的处理是因为URL里面不支持中文,而进行的百分号变换,将中文变成百分号格式
NSString *urlStr = [@"http://119.29.166.106:8080/login?username=123&pwd=123" stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
传入NSURL创建一个NSURLRequest对象,设置请求头和请求体等
//NSURLRequest *request = [NSURLRequest requestWithURL:url];
//要进行更细致的设置,如请求方式,请求头等的设置,只能使用NSURLRequest的子类NSMutableURLRequest:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
// 请求体
NSString *bodyStr = @"username=123&pwd=123";
request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
//设置请求超时等待时间(超过这个时间就算超时,请求失败)
- (void)setTimeoutInterval:(NSTimeInterval)seconds;
//设置请求方法(比如GET和POST)
- (void)setHTTPMethod:(NSString *)method;
//设置请求体
- (void)setHTTPBody:(NSData *)data;
//设置请求头
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
使用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;
异步请求,代理方式回调:
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
+ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;
//在startImmediately = NO的情况下,需要调用start方法开始发送请求
- (void)start;
NSURLSession
iOS7以后苹果推荐使用NSURLSession进行网络交互的请求部分,NSURLSession也是一组相互依赖的类,它的大部分组件和NSURLConnection中的组件相同如NSURLRequest,NSURLCache等。而NSURLSession的不同之处在于,它将NSURLConnection替换为NSURLSession和NSURLSessionConfiguration,以及3个NSURLSessionTask的子类:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。
使用NSURLSession进行GET请求:
// 1、构造URL资源地址
NSURL *url = [NSURL URLWithString:@"http://apistore.xiantaosc.com/apiworks/servicedetail/112.html"];
// 2、创建Request请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 3、配置Request请求
// 设置请求方法
request.HTTPMethod = @"GET";
// 设置请求超时
request.timeoutInterval = 10.0;
// 设置头部参数
[request addValue:Get_Url_Apikey forHTTPHeaderField:@"apikey"];
// 4、构造NSURLSessionConfiguration
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// 5、构造NSURLSession,网络会话;
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];;
// 6、构造NSURLSessionTask,会话任务;
NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 请求失败,打印错误信息
if (error) {
NSLOG(error.localizedDescription);
}
// 8、请求成功,解析数据
else {
// 直接将data数据转成OC字符串(NSUTF8StringEncoding);
// NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// JSON数据格式解析
id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
// 9、判断是否解析成功
if (error) {
NSLOG(error.localizedDescription);
}else {
NSLOG(object);
// 解析成功,处理数据,通过GCD获取主队列,在主线程中刷新界面。
dispatch_async(dispatch_get_main_queue(), ^{
// 刷新界面....
});
}
}
}];
// 7、执行任务
[task resume];
使用NSURLSession进行POST请求:
// 1、创建URL资源地址
NSURL *url = [NSURL URLWithString:@"http://www.xiantaosc.com/docs/api/id/46/aid/131"];
// 2、创建Reuest请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 3、配置Request
request.timeoutInterval = 10.0;
request.HTTPMethod = @"POST";
// 4、构造请求参数
// 4.1、创建字典参数,将参数放入字典中,可防止程序员在主观意识上犯错误,即参数写错。
NSDictionary *parametersDict = @{@"id":Post_Url_Parameter_Id, @"key":Post_Url_Apikey, @"dtype":Post_Url_Parameter_Dtype};
// 4.2、遍历字典,以“key=value&”的方式创建参数字符串。
NSMutableString *parameterString = [NSMutableString string];
for (NSString *key in parametersDict.allKeys) {
// 拼接字符串
[parameterString appendFormat:@"%@=%@&", key, parametersDict[key]];
}
// 4.3、截取参数字符串,去掉最后一个“&”,并且将其转成NSData数据类型。
NSData *parametersData = [[parameterString substringToIndex:parameterString.length - 1] dataUsingEncoding:NSUTF8StringEncoding];
// 5、设置请求报文
request.HTTPBody = parametersData;
// 6、构造NSURLSessionConfiguration
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// 7、创建网络会话
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
// 8、创建会话任务
NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 10、判断是否请求成功
if (error) {
NSLOG(error.localizedDescription);
}else {
// 如果请求成功,则解析数据。
id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
// 11、判断是否解析成功
if (error) {
NSLOG(error.localizedDescription);
}else {
// 解析成功,处理数据,通过GCD获取主队列,在主线程中刷新界面。
NSLOG(object);
dispatch_async(dispatch_get_main_queue(), ^{
// 刷新界面...
});
}
}
}];
// 9、执行任务
[task resume];
AFNetworking
AFNetworking是iOS上一个经常用到的第三方库,它继承了NSURLSession和NSURLConnection的诸多优点,同时也增加了对NSOperation多线程的处理,解决了Cache缓存的方案。
AFNetworking进行GET请求(基于NSURLSession,苹果已不推荐使用NSURLConnection)
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[[NSURL alloc] initWithString:@"hostname"]];
[manager GET:@"relative_url" parameters:nil progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@" ,responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@", error);
}];
AFNetworking进行POST请求
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSMutableDictionary *parameters = @{@"we":@"dd",@"rea":@"gg"};
[manager POST:URL parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
NSLog(@"%@" ,responseObject);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@" ,error);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
使用AFNetworking3.0进行网络资源下载
- (void)downLoad{
//1.创建管理者对象
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.确定请求的URL地址
NSURL *url = [NSURL URLWithString:@""];
//3.创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//下载任务
NSURLSessionDownloadTask *task = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
//打印下下载进度
NSLog(@"%lf",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
//下载地址
WKNSLog(@"默认下载地址:%@",targetPath);
//设置下载路径,通过沙盒获取缓存地址,最后返回NSURL对象
NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
return [NSURL URLWithString:filePath];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
//下载完成调用的方法
NSLog(@"下载完成:");
NSLog(@"%@--%@",response,filePath);
}];
//开始启动任务
[task resume];
}
使用AFNetworking进行资源上传
- (void)upLoad1{
//1.创建管理者对象
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.上传文件
NSDictionary *dict = @{@"username":@"1234"};
NSString *urlString = @"22222";
[manager POST:urlString parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
//上传文件参数
UIImage *iamge = [UIImage imageNamed:@"123.png"];
NSData *data = UIImagePNGRepresentation(iamge);
//这个就是参数
[formData appendPartWithFileData:data name:@"file" fileName:@"123.png" mimeType:@"image/png"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
//打印下上传进度
WKNSLog(@"%lf",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//请求成功
WKNSLog(@"请求成功:%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//请求失败
WKNSLog(@"请求失败:%@",error);
}];
}
使用AFNetworking根据路径上传沙盒或者相册资源
- (void)upLoda2{
//1.创建管理者对象
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.上传文件
NSDictionary *dict = @{@"username":@"1234"};
NSString *urlString = @"22222";
[manager POST:urlString parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
[formData appendPartWithFileURL:[NSURL fileURLWithPath:@"文件地址"] name:@"file" fileName:@"1234.png" mimeType:@"application/octet-stream" error:nil];
} progress:^(NSProgress * _Nonnull uploadProgress) {
//打印下上传进度
WKNSLog(@"%lf",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//请求成功
WKNSLog(@"请求成功:%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//请求失败
WKNSLog(@"请求失败:%@",error);
}];
}
使用AFNetworking进行网络状态检查:
//下面都需要于用户做交互.比如做一个弹窗提醒用户什么的.
- (void)checkNetworkState
{
// 1.检测wifi状态
Reachability *wifi = [Reachability reachabilityForLocalWiFi];
// 2.检测手机是否能上网络(WIFI\3G\2.5G)
Reachability *conn = [Reachability reachabilityForInternetConnection];
// 3.判断网络状态
if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi
} else if ([conn currentReachabilityStatus] != NotReachable) { // 没有使用wifi, 使用手机自带网络进行上网
} else { // 没有网络
}
}