C/S :客户端/服务器;B/S:
数据的传输:服务器端的数据是分成一个个单个的数据包传入客户端; 客户端与服务器做数据传输必须约定使用同一种格式;
HTTP:超文本传输协议,浏览器和服务器之间的通信规则;HTTP协议永远都是客户端发送请求,服务器回送响应;
HTTP常见的请求方式:
1.get请求,是向服务器索取数据的一种请求方式;(例如:获取电影列表的数据)
2.post请求,事项服务器提交数据的一种请求方式(发送密码和账号);
HTTP的请求包结构:
1.HTTP请求包得结构由两部分组成:HTTP请求头、HTTP请求体
2.post请求方式才有请求体,get请求只有请求头
3.get/post请求,客户端向服务器提交的数据,可以放入请求体或URL后面
HTTP响应包结构:
1.HTTP响应包有两部分组成:响应头和响应体;
2.HTTP响应有个状态码,表示响应结果,例如:200表示成功,404表示未能找到页面
3、服务器通过响应包将数据发送给客户端,数据主要在响应包得响应体内,而数据格式可以用:JSON 和 XML
4.响应头中的content-Type表示响应体中数据的类型:主要类型有:text/html application/json text/json text/xml image/jpeg
同步、异步请求
1.同步请求:如果数据的请求过程是在主线程执行的,网络数据传输的过程会导致线程阻塞;
2.异步请求:数据的请求过程在多线程执行,会保存主线程的流畅性
3.UI界面的渲染与刷新在主线中执行,主线程不流畅会导致UI界面卡顿
———————————网络组件(
NSURLConnection
)(
NSURLSession
)(系统自动给它在后台开一个线程)
1.CFNetWork是ui低层的高性能框架,他是基于BSD sockets的基础上做的
2.
NSURLConnection 是iOS7之前的组件
3.ios7之后,苹果推出了NSURLconnection 的继任者:NSURLSession
4.NSURLSession的使用流程
1· 构造NSURL实例(链接地址)
2· 构造NSURLRequest请求
3· 构造NSURLSessionConfiguration (可选的)(是为了配置session的类型)有三个类方法:
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSessionConfiguration *config1 = [NSURLSessionConfiguration ephemeralSessionConfiguration];
NSURLSessionConfiguration *config2 = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@" "];
4· 构造NSURLSession 发送请求(指的是一个会话,一个网络会话可以发起多个任务(task))
Session的类型:1>默认类型:使用持久化的,局域磁盘的缓存;
2>.临时的:不再磁盘存储任何数据,所有的缓存都存储在内存中;
3>.后台:和默认类型的很像,不同的时有一个独立的进程处理所有的网络请求;
———————————————— 演示GET请求——————————
//GET
请求
,
也可以给服务器发送信息
,
也有参数
(
微博用户名
,
用户
id)
//1.
构造
URL,
参数直接拼接在
url
连接后 例如:( http://api.hudong.com/iphonexml.do?type=focus-c
)
NSURL *url = [NSURL URLWithString:@"http://news-at.zhihu.com/api/3/news/4602734"
];
//2.
构造
Request
//
把
get
请求的请求头保存在
request
里
//NSURLRequest *request = [NSURLRequest requestWithURL:url];
//
参数
// (1)url
// (2)
缓存策略
// (3)
超时的时间
,
经过
120
秒之后就放弃这次请求
//NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:120];
//NSURLRequest
不可变
,
不能动态的添加请求头信息
//
可变的对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL
:url];
//(1)
设置请求方式
[request
setHTTPMethod:@"GET"
];
//(2)
超时时间
[request
setTimeoutInterval:120
];
//(3)
缓存策略
[request
setCachePolicy:NSURLRequestReturnCacheDataElseLoad
];
//(4)
设置请求头其他内容
//[request setValue:<#(NSString *)#> forHTTPHeaderField:<#(NSString *)#>];
//[request addValue:<#(NSString *)#> forHTTPHeaderField:<#(NSString *)#>];
//[request setAllHTTPHeaderFields:<#(NSDictionary *)#>];
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
//
告诉服务
,
返回的数据需要压缩
//(5)
设置请求体
//[request setHTTPBody:(NSData *)];
//3.
构造
Session
NSURLSession *session = [NSURLSession sharedSession
];
//4.Task
/**
* task
*
* @param data
返回的数据
* @param response
响应头
* @param error
错误信息
*
*/
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error == nil) {
//
打印数据可以知道服务器返回的数据是什么类型
NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"data: %@"
, dataStr);
/*
options:
1.
读取
reading
NSJSONReadingMutableContainers
生成可变的对象
,
不设置这个
option,
默认是创建不可变对象
NSJSONReadingMutableLeaves
生成可变的字符串
MutableString(iOS7+
有
bug)
NSJSONReadingAllowFragments
允许
json
数据最外层不是字典或者数组
2.
写入
writing
NSJSONWritingPrettyPrinted
生成
json
数据是格式化的
,
有换行
,
可读性高
*/
//data --> json
//
将数据转换成
json
数据
NSJSONSerialization
*jsonData = [
NSJSONSerialization
JSONObjectWithData
:data
options
:
NSJSONReadingMutableContainers
error
:
nil
];
NSLog
(
@"json: %@"
, jsonData);
}
}];
//5.
[task resume
];
—————————————— 演示POST请求———————————
//POST
请求
//1.
构造
URL
NSURL *url = [NSURL URLWithString:@"https://api.weibo.com/2/statuses/update.json"
];
//2.
构造
Request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL
:url];
//(1)
设置为
POST
请求
[request setHTTPMethod:@"POST"
];
//(2)超时
[request setTimeoutInterval:60];
//(3)
设置请求头
//[request setAllHTTPHeaderFields:nil];
//(4)
设置请求体
//
发微博
//
请求体里需要包含至少两个参数
//
指定用户的令牌
微博正文
//access_token status
NSString
*bodyStr =
@"access_token=2.00TpCOFGgvN4eB4c8f6ca3cdBurugD&status=无限互联"
;
NSData *bodyData = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody
:bodyData];
//3.
构造
Session
NSURLSession *session = [NSURLSession sharedSession
];
//4.task
//response
是响应体的响应头内容
// data 是返回的数据
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"response : %@"
, response);
}];
//5.
请求
[task resume
];
————————————————— 代理对象通过协议方法监听网络加载事件(block只能监听数据加载完成事件)
————————--------配置 session--------------------
//1.url
NSURL *url = [NSURL URLWithString:@"http://news-at.zhihu.com/api/3/news/latest"
];
//2.(request) configuration
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration
];
/*
requestCachePolicy
:
设置缓存策略
networkServiceType
:
设置网络服务的类型:网络流量,网络电话,语音,视频
..
timeoutIntervalForRequest
:设置超时时间
HTTPAdditionalHeaders
:
设置请求头
discretionary
:
用于后台请求,会把
WiFi
和电量的可用性考虑在内
allowsCellularAccess
:
是否允许使用蜂窝数据
*/
config.
timeoutIntervalForRequest = 120;
config.allowsCellularAccess = NO
;
//3.session
//NSURLSession *session = [NSURLSession sharedSession];
//
通过配置
config
对象来创建
session
//
如果只是发送请求
,
使用以下方法
,
系统会默认创建一个
queue
来处理
session
的消息
//NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSOperationQueue *queue = [NSOperationQueue mainQueue
];
//(1)
配置对象
//(2)
代理对象
,
可以监测请求过程
,
是强引用的
(strong)
//(3)
操作队列
,
可以设定
delegate
在指定的
queue
上面执行代理方法
NSURLSession *session = [NSURLSession sessionWithConfiguration:config
delegate:self
delegateQueue
:queue];
//4.task(一般分为:数据任务,上传任务,下载任务)
NSURLSessionDataTask *task = [session dataTaskWithURL:url];
//5.resume
[task resume
];
}
#pragma mark -
代理方法
//1.
服务器返回响应头
,
就会调用
- (
void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
//
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(@"%ld", httpResponse.statusCode)
;
//
接收到响应头
,
调用
block,
可以取消或者继续后面的数据传输
/*
NSURLSessionResponseCancel = 0,
取消后面的数据传输
NSURLSessionResponseAllow = 1,
继续传输
NSURLSessionResponseBecomeDownload = 2,
把加载数据的模式转换为下载
*/
//
调用
block
completionHandler(
NSURLSessionResponseAllow
);
}
//2.
响应体数据全部接收的时候
,
调用
-
(void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
//data 是接收到的响应体数据
}
//3.
一次任务执行完成
- (
void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
NSLog(@"网络请求完成"
);
}
-----------------监听下载进度------------------------
第一种使用bolok只能监听下载是否完成 不能监听下载进度
想要监听下载进度 需要配置 session 对象 使用协议方法监听下载进度
- (
IBAction
)downLoadAction:(
UIButton
*)sender {
// 1.
获取
URL
NSString
*urlStr =
@"http://ra01.sycdn.kuwo.cn/resource/n3/32/56/3260586875.mp3"
;
NSURL
*url = [
NSURL
URLWithString
:urlStr];
// 2,
构造
request
对象
NSMutableURLRequest
*request = [[
NSMutableURLRequest
alloc
]
initWithURL
:url];
// 3.
构造
session
对象
NSURLSession
*session = [
NSURLSession
sharedSession
];
// 4.
链接服务器
取得下载任务
block
方法只能监听下载完成
不能监听下载进度
需要监听下载进度需要配置
session
对象
使用协议方法监听
NSURLSessionDownloadTask
*task = [session
downloadTaskWithRequest
:request
completionHandler
:^(
NSURL
*location,
NSURLResponse
*response,
NSError
*error) {
//
拼接一个本地路径
NSString
*filePath = [
NSHomeDirectory
()
stringByAppendingPathComponent
:
@"Documents/music.mp3"
];
//
本地
url
NSURL
*fileURL = [
NSURL
fileURLWithPath
:filePath];
NSLog
(
@"%@"
,fileURL);
NSFileManager
*manager = [
NSFileManager
defaultManager
];
//
把下载的
URL
路径移动到拼接的本地
url
路径
BOOL
isSuccess = [manager
moveItemAtURL
:location
toURL
:fileURL
error
:
nil
];
if
(isSuccess) {
NSLog
(
@"isSuccess"
);
}
}];
//
开始任务
[task resume]
配置 NSURLSessionConfiguration 监听下载进度
//
构造
URL
NSString
*urlStr =
@"http://ra01.sycdn.kuwo.cn/resource/n3/32/56/3260586875.mp3"
;
NSURL
*url = [
NSURL
URLWithString
:urlStr];
//
配置
session
NSURLSessionConfiguration
*config = [
NSURLSessionConfiguration
defaultSessionConfiguration
];
//
构造
session
_session
= [
NSURLSession
sessionWithConfiguration
:config
delegate
:
self
delegateQueue
:[
NSOperationQueue
mainQueue
]];
//
链接服务器
_task
= [
_session
downloadTaskWithURL
:url];
//
开始任务
[
_task
resume
];
}
//
代理方法
当开始下载时调用
- (
void
)URLSession:(
NSURLSession
*)session downloadTask:(
NSURLSessionDownloadTask
*)downloadTask
didWriteData:(
int64_t
)bytesWritten
totalBytesWritten:(
int64_t
)totalBytesWritten
totalBytesExpectedToWrite:(
int64_t
)totalBytesExpectedToWrite
{
_progressView
.
progress
= (
CGFloat
)totalBytesWritten / totalBytesExpectedToWrite;
CGFloat
value = (
CGFloat
)totalBytesWritten / totalBytesExpectedToWrite;
_label
.
text
= [
NSString
stringWithFormat
:
@"%.2f%%"
,value *
100
];
}
//
当下载完成时调用
- (
void
)URLSession:(
NSURLSession
*)session downloadTask:(
NSURLSessionDownloadTask
*)downloadTask
didFinishDownloadingToURL:(
NSURL
*)location
{
NSString
*filePath = [
NSHomeDirectory
()
stringByAppendingPathComponent
:
@"Documents.music.mp3"
];
NSURL
*fileURL = [
NSURL
fileURLWithPath
:filePath];
NSFileManager
*manager = [
NSFileManager
defaultManager
];
BOOL
isSuccess = [manager
moveItemAtURL
:location
toURL
:fileURL
error
:
nil
];
if
(isSuccess) {
NSLog
(
@"
数据下载完成
"
);
}
_label.text = @"下载完成";
—————————————— 上传任务请求网络(传照片)———————————
//1.
构造
URL
NSURL
*url = [
NSURL
URLWithString
:
@"https://api.weibo.com/2/statuses/upload.json"
];
//2.
构造
request
NSMutableURLRequest
*request = [[
NSMutableURLRequest
alloc
]
initWithURL
:url];
//
设置请求方式
[request
setHTTPMethod
:
@"POST"
];
[request
setTimeoutInterval
:
30
];
//
设置请求头
NSString
*contentType = [
NSString
stringWithFormat
:
@"multipart/form-data; charset=utf-8;boundary=%@"
,
StringMark
];
[request
setValue
:contentType
forHTTPHeaderField
:
@"Content-Type"
];
//3.
创建会话对象
NSURLSession
*session = [
NSURLSession
sharedSession
];
NSData
*data = [
self
getBodyData
];
NSURLSessionUploadTask
*task = [session
uploadTaskWithRequest
:request
fromData
:data
completionHandler
:^(
NSData
*data,
NSURLResponse
*response,
NSError
*error) {
NSString
*str = [[
NSString
alloc
]
initWithData
:data
encoding
:
NSUTF8StringEncoding
];
NSLog
(
@"str:%@"
,str);
}];
[task
resume
];
}
/*
--AaB03x
Content-Disposition: form-data; name="key1"
value1
--AaB03x
Content-disposition: form-data; name="key2"
value2
AaB03x
Content-disposition: form-data; name="key3"; filename="file"
Content-Type: application/octet-stream
图片数据
...
--AaB03x--
*/
/*
access_token : 2.00Nx36WDqSQJKBbe72fbff89wtNbKE
status :
文字内容
pic :
图片
*/
- (
NSData
*)getBodyData {
NSMutableString
*bodyString = [[
NSMutableString
alloc
]
init
];
//
拼接
[bodyString
appendFormat
:
@"--%@\r\n"
,
StringMark
];
//
(
1
)拼接
access_token
[bodyString
appendFormat
:
@"Content-Disposition: form-data; name=\"access_token\"\r\n\r\n"
];
[bodyString
appendFormat
:
@"2.00Nx36WDqSQJKBbe72fbff89wtNbKE\r\n"
];
[bodyString
appendFormat
:
@"--%@\r\n"
,
StringMark
];
//
(
2
)拼接发布的微博的内容
[bodyString
appendFormat
:
@"Content-disposition: form-data; name=\"status\"\r\n\r\n"
];
[bodyString
appendFormat
:
@"
上课好累啊
\r\n"
];
[bodyString
appendFormat
:
@"--%@\r\n"
,
StringMark
];
//
(
3
)设置图片数据
[bodyString
appendFormat
:
@"Content-disposition: form-data; name=\"pic\"; filename=\"file\"\r\n"
];
[bodyString
appendFormat
:
@"Content-Type: application/octet-stream\r\n\r\n"
];
//
创建可变的
data
NSMutableData
*sumData = [[
NSMutableData
alloc
]
init
];
//
将字符串转换成
data
NSData
*data = [bodyString
dataUsingEncoding
:
NSUTF8StringEncoding
];
[sumData
appendData
:data];
//
获取图片
NSString
*imgPath = [[
NSBundle
mainBundle
]
pathForResource
:
@"1.png"
ofType
:
nil
];
NSData
*imgData = [
NSData
dataWithContentsOfFile
:imgPath];
[sumData
appendData
:imgData];
NSString
*lastString = [
NSString
stringWithFormat
:
@"\r\n--%@--\r\n"
,
StringMark
];
NSData
*lastData = [lastString
dataUsingEncoding
:
NSUTF8StringEncoding
];
[sumData
appendData
:lastData];
return sumData;
——————------------------断点续传--------------------
- (
IBAction
)dodwnLoa:(
UIButton
*)sender {
//
构造
URL
NSString
*urlStr =
@"http://ra01.sycdn.kuwo.cn/resource/n3/32/56/3260586875.mp3"
;
NSURL
*url = [
NSURL
URLWithString
:urlStr];
//
配置
session
NSURLSessionConfiguration
*config = [
NSURLSessionConfiguration
defaultSessionConfiguration
];
//
构造
session
_session
= [
NSURLSession
sessionWithConfiguration
:config
delegate
:
self
delegateQueue
:[
NSOperationQueue
mainQueue
]];
//
链接服务器
_task
= [
_session
downloadTaskWithURL
:url];
//
开始任务
[
_task
resume
];
}
//
代理方法
当开始下载时调用
- (
void
)URLSession:(
NSURLSession
*)session downloadTask:(
NSURLSessionDownloadTask
*)downloadTask
didWriteData:(
int64_t
)bytesWritten
totalBytesWritten:(
int64_t
)totalBytesWritten
totalBytesExpectedToWrite:(
int64_t
)totalBytesExpectedToWrite
{
_progressView
.
progress
= (
CGFloat
)totalBytesWritten / totalBytesExpectedToWrite;
CGFloat
value = (
CGFloat
)totalBytesWritten / totalBytesExpectedToWrite;
_label
.
text
= [
NSString
stringWithFormat
:
@"%.2f%%"
,value *
100
];
}
//
当下载完成时调用
- (
void
)URLSession:(
NSURLSession
*)session downloadTask:(
NSURLSessionDownloadTask
*)downloadTask
didFinishDownloadingToURL:(
NSURL
*)location
{
NSString
*filePath = [
NSHomeDirectory
()
stringByAppendingPathComponent
:
@"Documents.music.mp3"
];
NSURL
*fileURL = [
NSURL
fileURLWithPath
:filePath];
NSFileManager
*manager = [
NSFileManager
defaultManager
];
BOOL
isSuccess = [manager
moveItemAtURL
:location
toURL
:fileURL
error
:
nil
];
if
(isSuccess) {
NSLog
(
@"
数据下载完成
"
);
}
_label
.
text
=
@"
下载完成
"
;
}
//
暂停下载
- (
IBAction
)pauseAction:(
UIButton
*)sender {
[
_task
cancelByProducingResumeData
:^(
NSData
*resumeData) {
_data
= resumeData;
}];
_task
=
nil
;
}
//
继续下载
- (
IBAction
)continueAction:(
UIButton
*)sender {
_task
= [
_session
downloadTaskWithResumeData
:
_data
];
[
_task
resume
];
}
//
后台下载
- (
IBAction
)backgroudAction:(
UIButton
*)sender {
NSURL
*url = [
NSURL
URLWithString
:
@"http://www.soge8.com/1424215157/e4eaa401acb097ad2745efe7f8213352.mp3"
];
NSURLSessionConfiguration
*config = [
NSURLSessionConfiguration
backgroundSessionConfigurationWithIdentifier
:
@"music"
];
NSURLSession
*session = [
NSURLSession
sessionWithConfiguration
:config
delegate
:
self
delegateQueue
:[
NSOperationQueue
mainQueue
]];
NSURLSessionDownloadTask
*task = [session
downloadTaskWithURL
:url];
[task
resume
];
}
———————————第三方框架 AFNetWorking------------------------
//http://piao.163.com/m/cinema/list.html?app_id=1&mobileType=iPhone&ver=2.6&channel=appstore&deviceId=9E89CB6D-A62F-438C-8010-19278D46A8A6&apiVer=6&city=110000
- (
void
)viewDidLoad {
[
super
viewDidLoad
];
//ASIHTTP AFNetWorking MKNetWorking
}
//GET
请求
- (
IBAction
)getAction:(
id
)sender {
//1.
获取链接
NSString
*stringURL =
@"http://piao.163.com/m/cinema/list.html?app_id=1&mobileType=iPhone&ver=2.6&channel=appstore&deviceId=9E89CB6D-A62F-438C-8010-19278D46A8A6"
;
//2.
创建管理者
AFHTTPSessionManager
*manager = [
AFHTTPSessionManager
manager
];
//3.
/*
1.userName=Jack&passWord=123456 AFHTTPRequestSerializer (
默认的
)
2.JSON AFJSONRequestSerializer
*/
//
设置请求参数的格式
manager.
requestSerializer
= [
AFHTTPRequestSerializer
serializer
];
//4.
/*
JSON AFJSONResponseSerializer
(默认的)
XML AFXMLDocumentResponseSerializer
图片数据
AFImageResponseSerializer
不解析
AFHTTPResponseSerializer
*/
//
设置响应的数据解析方式
manager.
responseSerializer
= [
AFJSONResponseSerializer
serializer
];
//GET
NSDictionary
*dic =
@{
@"city"
:
@"110000"
,
@"apiVer"
:
@"6"
}
;
[manager
GET
:stringURL
parameters
:dic
success
:^(
NSURLSessionDataTask
*task,
id
responseObject) {
// id result = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
NSLog
(
@"responseObject:%@"
,responseObject);
}
failure
:^(
NSURLSessionDataTask
*task,
NSError
*error) {
NSLog
(
@"error:%@"
,error);
}];
}
//POST
请求
/*
POST
请求参数:
movie_id=43485
http://piao.163.com/m/movie/detail.html?app_id=1&mobileType=iPhone&ver=2.6&channel=appstore&deviceId=9E89CB6D-A62F-438C-8010-19278D46A8A6&apiVer=6&city=110000
*/
- (
IBAction
)postAction:(
id
)sender {
//1.stringURL
NSString
*stringURL =
@"http://piao.163.com/m/movie/detail.html?app_id=1&mobileType=iPhone&ver=2.6&channel=appstore&deviceId=9E89CB6D-A62F-438C-8010-19278D46A8A6&apiVer=6&city=110000"
;
//2.
创建管理者
AFHTTPSessionManager
*manager = [
AFHTTPSessionManager
manager
];
//
设置发送数据的格式
manager.
requestSerializer
= [
AFHTTPRequestSerializer
serializer
];
//
接收的数据格式
manager.
responseSerializer
= [
AFJSONResponseSerializer
serializer
];
//3.
发布请求
NSDictionary
*dic =
@{
@"movie_id"
:
@"43485"
}
;
[manager
POST
:stringURL
parameters
:dic
success
:^(
NSURLSessionDataTask
*task,
id
responseObject) {
NSLog
(
@"responseObject:%@"
,responseObject);
}
failure
:^(
NSURLSessionDataTask
*task,
NSError
*error) {
NSLog
(
@"error:%@"
,error);
}];