ASI框架的使用
- 1.同步訪問
- 2.異步訪問
- 3.塊代碼方式
- 4.指定selector方法
- 5.POST登陸
- 6.POST JSON
- 7.下載文件
- 8.斷點續(xù)傳
- 9.上傳文件
- 10.野指針
導(dǎo)入ASI框架
我們需要導(dǎo)入我們需要的一需要的一些文件
以上的文件都需要在 Build Phases\Compile Sourses -fno-objc-arc 編譯標(biāo)記
添加libz.dylib動態(tài)庫
1.同步訪問
- (void)syncDemo {
1. 只要是網(wǎng)絡(luò)訪問,就有可能出錯!
2. 超時時長!
3. 多線程!
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 1. url
NSURL *url = [NSURL URLWithString:@"http://192.168.31.2/videos.json"];
// 2. 請求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 默認(rèn)的網(wǎng)絡(luò)請求超時時長 10 秒,
request.timeOutSeconds = 2.0;
// 這種方法不能處理錯誤,只能根據(jù)data是否存在,判斷網(wǎng)絡(luò)請求是否出錯!
//NSData *data = [NSData dataWithContentsOfURL:url];
//3.同步啟動請求,會阻塞當(dāng)前線程
[request startSynchronous];
// 出錯處理
if (request.error) {
NSLog(@"%@", request.error);
return;
}
//4. 就能夠拿到響應(yīng)的結(jié)果
NSLog(@"%@ %@", request.responseData, [NSThread currentThread]);
//5. 如果返回的內(nèi)容確實是字符串,可以使用 responseString
NSLog(@"%@ %@", request.responseString, [NSThread currentThread]);
//6.如果返回的是字符串我們需要用下面的方法把他初始化為一個NSString類型
//NSString *str = [[NSString alloc] initWithData:request.responseData encoding:NSUTF8StringEncoding];
// NSLog(@"%@", str);
});
}
-
2.異步請求的三種方法
1.代理的實現(xiàn)
2.代碼塊的實現(xiàn)
3.自行定義指定網(wǎng)絡(luò)監(jiān)聽方法
// 1. url
NSURL *url = [NSURL URLWithString:@"http://192.168.31.2/videos.json"];
// 2. request
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 設(shè)置代理
request.delegate = self;
// 3. 啟動異步
[request startAsynchronous];
//下邊是代理實現(xiàn)的方法
#pragma mark 代理方法
// 開發(fā)多線程框架的時候,有一個細(xì)節(jié)
// 耗時的操作,框架來做,在后臺線程,回調(diào)方法在主線程做,使用框架的人,不需要關(guān)心線程間通訊
- (void)requestStarted:(ASIHTTPRequest *)request {
NSLog(@"%s", __FUNCTION__);
}
- (void)request:(ASIHTTPRequest *)request
didReceiveResponseHeaders:
(NSDictionary*)responseHeaders {
NSLog(@"%s %@", __FUNCTION__, responseHeaders);
}
- (void)requestFinished:(ASIHTTPRequest *)request {
NSLog(@"%s %@ %@", __FUNCTION__,
request.responseString, [NSThread currentThread]);
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSLog(@"失敗 %@", request.error);
}
// 此方法知道就行,一旦實現(xiàn)了這個方法,那么在 requestFinished 方法中,就得不到最終的結(jié)果了!
//- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data {
// NSLog(@"%s %@", __FUNCTION__, data);
//}
block代碼塊
#pragma mark 通過塊代碼來監(jiān)聽網(wǎng)絡(luò)請求
- (void)asyncBlockDemo {
// 1. url
NSURL *url = [NSURL URLWithString:@"http://192.168.31.2/videos.json"];
// 2. 請求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 設(shè)置代理
request.delegate = self;
// 2.1 塊代碼回調(diào)
// 開始
[request setStartedBlock:^{
NSLog(@"start");
}];
// 接收到響應(yīng)頭
[request setHeadersReceivedBlock:^
(NSDictionary *responseHeaders) {
NSLog(@"block - %@", responseHeaders);
}];
// 接收到字節(jié)(下載)
// request setBytesReceivedBlock:^(unsigned long long size, unsigned long long
total) {
//
// }
// 接收到數(shù)據(jù),和代理方法一樣,一旦設(shè)置,在網(wǎng)絡(luò)完成時,就沒有辦法獲得結(jié)果
// 實現(xiàn)這個方法,就意味著程序員自己處理每次接收到的二進(jìn)制數(shù)據(jù)!
//[request setDataReceivedBlock:^(NSData *data) {
// NSLog(@"%@", data);
//}];
// 簡單的網(wǎng)絡(luò)訪問
__weak typeof(request) weakRequest = request;
[request setCompletionBlock:^{
NSLog(@"block - %@", weakRequest.responseString);
}];
// 訪問出錯
[request setFailedBlock:^{
NSLog(@"block - %@", weakRequest.error);
}];
// 3. 發(fā)起異步
[request startAsynchronous];
}
自行指定網(wǎng)絡(luò)監(jiān)聽方法
- (void)asyncSelectorDemo {
// 1. url
NSURL *url = [NSURL URLWithString:@"http://192.168.31.2/videos.json"];
// 2. 請求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 指定監(jiān)聽方法 - 接收到服務(wù)器的響應(yīng)頭方法沒有指定,如果程序中實現(xiàn),會同樣會被調(diào)用!
// 開始的方法
[request setDidStartSelector:@selector(start:)];
// 完成的監(jiān)聽
[request setDidFinishSelector:@selector(finished:)];
// 失敗的監(jiān)聽
[request setDidFailSelector:@selector(failed:)];
// 需要注意的,以上方法是在修改代理監(jiān)聽的執(zhí)行方法
// 需要指定代理
request.delegate = self;
// 3. 啟動請求
[request startAsynchronous];
}
post登陸
- (void)postLogin {
NSURL *url = [NSURL URLWithString:@"http://192.168.31.2/login.php"];
// POST請求
// 如果要使用 POST 請求,一般都使用 ASIFormDataRequest
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
// 設(shè)置httpBody
[request setPostValue:@"zhangsan" forKey:@"username"];
[request setPostValue:@"123" forKey:@"password"];
__weak typeof(request) weakSelf = request;
[request setCompletionBlock:^{
NSLog(@"%@", weakSelf.responseString);
}];
[request startAsynchronous];
}
POST JSON
- (void)postJSON {
NSURL *url = [NSURL URLWithString:@"http://192.168.31.2/post/postjson.php"];
// POST JSON 的請求還是 ASIHTTPRequest
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 設(shè)置請求方法
[request setRequestMethod:@"POST"];
// 設(shè)置二進(jìn)制數(shù)據(jù)
NSDictionary *dict = @{@"productId": @(123), @"productName": @"da bao tian tain jian"};
// 序列化,字典轉(zhuǎn)JSON二進(jìn)制數(shù)據(jù)
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:NULL];
[request setPostBody:[NSMutableData dataWithData:data]];
// 設(shè)置完成塊
__weak typeof(request) weakSelf = request;
[request setCompletionBlock:^{
NSLog(@"%@", weakSelf.responseString);
}];
[request startAsynchronous];
}
POST 上傳
- (void)postUpload {
// url 是負(fù)責(zé)上傳文件的腳本
NSURL *url = [NSURL URLWithString:@"http://192.168.31.2/post/upload.php"];
// 上傳文件,同樣可以在瀏覽器測試
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
// 設(shè)置上傳的文件
參數(shù)
1. 本地文件的路徑
2. 上傳腳本中的字段名
ASI會自動計算上傳文件的 mime-Type
NSString *path = [[NSBundle mainBundle]
pathForResource:@"demo.jpg" ofType:nil];
[request addFile:path forKey:@"userfile"];
/**
參數(shù)
1. 本地文件的路徑
2. 保存到服務(wù)器的文件名
3. mime-Type
4. 上傳腳本中的字段名
*/
[request addFile:path withFileName:@"aaa.jpg" andContentType:@"image/jpg" forKey:@"userfile"];
// 發(fā)起網(wǎng)絡(luò)連接
// 設(shè)置完成塊
__weak typeof(request) weakSelf = request;
[request setCompletionBlock:^{
NSLog(@"%@", weakSelf.responseString);
}];
[request startAsynchronous];
}
下載
- (void)download {
NSString *urlString = @"http://192.168.31.2/簡介.mp4";
urlString = [urlString
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlString];
// 請求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 下載需要指定下載的路徑(緩存路徑)
NSString *cacheDir =
[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
cacheDir = [cacheDir stringByAppendingPathComponent:@"321.mp4"];
NSLog(@"%@", cacheDir);
// 1.------------------------------------------------------------
// 設(shè)置保存下載文件的目標(biāo)路徑!
// !!! 一定要指定文件名,如果指定的是桌面,桌面上的所有文件都會消失!
[request setDownloadDestinationPath:cacheDir];
// 2.------------------------------------------------------------
// 斷點續(xù)傳
[request setAllowResumeForFileDownloads:YES];
// 需要設(shè)置臨時文件(包含文件名的全路徑)
NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"aaa.tmp"];
[request setTemporaryFileDownloadPath:tmpPath];
// 3.------------------------------------------------------------
// 下載進(jìn)度跟進(jìn)
// request.downloadProgressDelegate = self;
// 進(jìn)度跟進(jìn)的代理?。?!
// 設(shè)置代理, id <遵守某一個協(xié)議> delegate;
// 設(shè)置代理, id delegate;對象不必遵守指定的協(xié)議,但是當(dāng)發(fā)生事件的時候,同樣會通知代理執(zhí)行相關(guān)的方法!
// 當(dāng)進(jìn)度發(fā)生變化是,給進(jìn)度視圖發(fā)送 setProgress 消息!
request.downloadProgressDelegate = self.progressView;
// 設(shè)置完成塊
[request setCompletionBlock:^{
NSLog(@"OK");
}];
self.request = request;
[request startAsynchronous];
}
用asi經(jīng)常犯的野指針錯誤, nav強(qiáng)引用了vc,vc強(qiáng)引用了progressView,progressView又強(qiáng)引用了Request當(dāng)vc釋放的時候,progressView 也釋放了,所以request讓progressView更新的時候會產(chǎn)生野指針錯誤
總結(jié):最近學(xué)習(xí)了一下ASI怎么用,因為一些老的程序都是asi 的框架替換的話工作量太大,所以就學(xué)習(xí)了一下,在本篇博客中學(xué)習(xí)到了asi的同步訪問,和異步訪問的三種方式
還學(xué)習(xí)到了 post登陸,和post json,下載文件和上傳,和野指針的錯誤,希望可以供大家學(xué)習(xí),有錯誤的希望大家可以給我留一下言,謝謝