网络编程
NSURL
url,统⼀资源定位符,也被称为⺴址,因特⺴上标准的资源⺴址
url的语法: 协议://授权/路径?查询
- url作为网址字符串包含很多请求参数,NSURL对网址字符串进行封装 可以使用NSURL对象获取相应的参数
- absoluteString: http://lily:123456@www.google.com/search?
hl=en&source=hp&q=mysql&aq=f&oq=&aqi=g10#page
- scheme: http
- host: www.google.com
- user: lily
- password: 123456
- port: 8080
- query: hl=en&source=hp&q=mysql&aq=f&oq=&aqi=g10
请求方式
- GET
- POST
相同点: - 都能给服务器传输数据
不同点:
- 给服务器传输数据的方式:
- GET:通过⺴址字符串
- POST:通过data
- 传输数据的⼤⼩:
- GET:⺴址字符串最多255字节
- POST:使⽤NSData,容量超过1G
- 安全性:
- GET:所有传输给服务器的数据,显⽰在⺴址⾥,类似于密码的明⽂输⼊,直接可⻅
- POST:数据被转成NSData(⼆进制数据),类似于密码的密⽂输⼊,⽆法直接读取
- 给服务器传输数据的方式:
连接方式
- 同步连接:程序容易出现卡死现象
- 异步连接:等待数据返回
- 异步联接有两种实现⽅式:
- 设置代理,接收数据
- 实现block
同步连接
+ (NSData *)sendSynchronousRequest:(NSURLRequest
*)request returningResponse:(NSURLResponse **)response
error:(NSError **)error;
具体代码实现:
GET方式同步连接
// 获得网址字符串
NSString *str = @"http://api.map.baidu.com/place/v2/search?query=公厕®ion=上海&output=json&ak=6E823f587c95f0148c19993539b99295";
// 如果网址中有中文需要转化一下格式
str = [str stringByAddingPercentEscapesUsingEncoding:(NSUTF8StringEncoding)];
> Xcode 7 之后不推荐使用此方法,用下面方法代替
> NSString *str = [kSearchURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
// 把字符串转化成网址对象
NSURL *url = [NSURL URLWithString:str];
// 根据网址创建一个请求
// timeoutInterval 请求超时的时间 单位为秒
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:30];
// 设置一个GET方式请求的标识符
[request setHTTPMethod:@"GET"];
// 创建一个错误对象
NSError *error = nil;
// 创建空的服务器一个响应信息的对象
NSURLResponse *response = nil;
// 简历同步连接
// 利用请求创建一个链接
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
// 解析数据
NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableContainers) error:nil];
PSOT方式同步连接
POST请求方式比GET多了一个请求体
// 获得网址字符串
NSString *str = http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx
// 创建网址对象
NSURL *url = [NSURL URLWithString:str];
// 创建一个请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:30];
// 为了看的比较清楚 设置一个标识
request.HTTPMethod = @"post";
// 请求体字符串
NSString *string = @"date=20131129&startRecord=1&len=30&udid=1234567890&terminalType=Iphone&cid=213";
// 把字符串转化成data使用UTF-8的编码格式(携带的请求体)
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
// 注意: Post请求 可以携带一个请求体
[request setHTTPBody:data];
// 继续创建同步链接
NSData *newData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// 解析数据
NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:newData options:(NSJSONReadingMutableContainers) error:nil];
NSLog(@"%@",dataDic);
异步连接(代理)
步骤:
- 设置NSURLConnection代理(注:Xcode7.0之后使用NSURLSession代替,使用:http://blog.csdn.net/wanglongblog/article/details/50155191)
- 实现相应的代理⽅法:开始响应接收数据、接收数据、成功、失败
// 已经接收到服务器的响应 链接成功
- (void)connection:(NSURLConnection *)connection didReceiveResponse:
(NSURLResponse *)response
// 已经接收到数据 (根据网速与数据大小,触发次数不一定)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData
*)data
// 已经完成加载
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
// 加载失败,请求没成功
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError
*)error
GET异步链接代理方法具体实现:
定义宏:
#define kSearchURL @"http://api.map.baidu.com/place/v2/search?query=公厕®ion=上海&output=json&ak=6E823f587c95f0148c19993539b99295"
// 以下请求使用Post
#define kNewsListURL @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx"
#define kNewsListParam @"date=20131129&startRecord=1&len=30&udid=1234567890&terminalType=Iphone&cid=213"
#define kImageURL @"http://image.zcool.com.cn/56/13/1308200901454.jpg"
// 申明属性
@interface GetViewController ()
<NSURLConnectionDataDelegate, NSURLConnectionDelegate>
// 申明一个链接属性
@property (nonatomic, retain) NSURLConnection *connection;
// 申明一个可变的data 用于接收完整的data
@property (nonatomic, retain) NSMutableData *receiveData;
@end
方法实现:
// 获取网址对象(有中文转码)
NSString *urlStr = [kSearchURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 利用网址 创建网址对象
NSURL *url = [NSURL URLWithString:urlStr];
// 利用网址对象创建一个请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:30];
// 标识
request.HTTPMethod = @"GET";
#pragma mark ---- 代理方法 异步链接
// 利用请求 创建一个异步链接
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
// 开始链接
[self.connection start];
// 注意:当界面跳转,界面被pop时,需要销毁链接,在dealloc方法中实现
- (void)dealloc{
[_connection cancel];
[_connection release];
[super dealloc];
}
代理方法实现
#pragma mark --- 代理方法实现
// 已经接收到服务器的响应信息
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
// 初始化data
self.receiveData = [NSMutableData data];
NSLog(@"已经接收到服务器的响应信息,链接成功了");
NSLog(@"%@",response);
}
// 接收到数据触发的方法
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
// 多次触发这个方法才能 接收到完整的data
// 所以这个时候需要拼接一下data
[self.receiveData appendData:data];
NSLog(@"接收到数据触发的方法");
}
// 已经完成数据加载 触发的方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@"%@",self.receiveData);
// 解析数据
NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:self.receiveData options:(NSJSONReadingMutableContainers) error:nil];
// 如果在tableView上显示的话
// 注意:要刷新界面
NSLog(@"已经完成数据加载 触发的方法");
}
// 请求失败时
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"请求失败时触发 %@",error);
}
block方法异步链接
// 请求之前一样
// 链接
// 代表回到 主线程
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 当数据请求完成的时候 会指定这个block
NSLog(@"%@",data);
// 判断是否在主线程
NSLog(@"%d",[NSThread isMainThread]);
// 此处刷新界面
}];
异步请求代理方法显示加载进度
定义宏申明属性:
#import "ImageViewController.h"
#define kImageURL @"http://image.zcool.com.cn/56/13/1308200901454.jpg"
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
@interface ImageViewController ()
<NSURLConnectionDelegate, NSURLConnectionDataDelegate>
@property (nonatomic, retain) UIImageView *imageV;
@property (nonatomic, retain) UILabel *label;
@property (nonatomic, retain) NSURLConnection *connection;
@property (nonatomic, retain) NSMutableData *receiveData;
// 声明一个属性保存总大小
@property (nonatomic, assign) long long totalLength;
@end
实现:
@implementation ImageViewController
- (void)dealloc{
[_connection cancel];
[_imageV release];
[_label release];
[_connection release];
[_receiveData release];
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor greenColor];
[self addSubViews];
[self loadData];
}
- (void)addSubViews{
self.imageV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
[self.view addSubview:self.imageV];
[_imageV release];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(100, 300, 200, 40)];
self.label.backgroundColor = [UIColor yellowColor];
[self.view addSubview:self.label];
[_label release];
}
- (void)loadData{
NSURL *url = [NSURL URLWithString:kImageURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:30];
request.HTTPMethod = @"get";
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
[self.connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
// 取出总大小
self.totalLength = response.expectedContentLength;
// 链接成功
self.receiveData = [NSMutableData data];
NSLog(@"%@",response);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
// 拼接data
[self.receiveData appendData:data];
// 显示进度
self.label.text = [NSString stringWithFormat:@"%f", (float)self.receiveData.length / self.totalLength];
self.imageV.image = [UIImage imageWithData:self.receiveData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@"请求成功");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"请求失败");
}