iOS網(wǎng)絡(luò)請求策略——AFNetworking的基本使用

今天和大家一起來學(xué)習(xí)一下AFNetworking的基本使用,有疏忽的地方,還望各位不吝賜教。


一、AFNetworking的基本使用

1、控制器代碼

#import "ViewController.h"
#import <AFNetworking.h>
@interface ViewController ()

@end
/*
 * 在開發(fā)中進行二次封裝可以簡化步驟
 */
@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    [self download];
}
// 下載文件
- (void)download{

    // 1、創(chuàng)建文件管理者
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    // 確定URL
    NSURL *url = [NSURL URLWithString:@""];
    
    // 創(chuàng)建請求對象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 下載文件
    /*
     * 第一個參數(shù):請求對象
     * 第二個參數(shù):progress 進度回調(diào)
     * 第三個參數(shù):destination 回調(diào)(目標(biāo)位置)
                有返回值
                targetPath:臨時文件路徑
                response:響應(yīng)頭信息
     * 第三個參數(shù):completionHandler 下載完成之后的回調(diào)
                filePath:最終的文件路徑 
                error :錯誤信息
     */
    NSURLSessionDownloadTask * task = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        
        NSLog(@"%f",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
        
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        
        NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
        NSLog(@"%@",fullPath);
        return [NSURL fileURLWithPath:fullPath];
        
        
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        
        NSLog(@"%@",filePath);
    }];
    
    [task resume];
}
// 上傳文件
- (void)upload{

    // 創(chuàng)建會話管理者
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    // 發(fā)送請求上傳文件 然后就依據(jù)NSURLSession類似的方式上傳
    [manager uploadTaskWithRequest:nil fromData:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        
    }];
}
// 利用POST的方式上傳文件
- (void)upload2{

    // 創(chuàng)建會話管理者
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    // 發(fā)送post請求上傳文件
    /*
     第一個參數(shù):請求路徑
     第二個參數(shù):字典(非文件參數(shù)) 可以不傳
     第三個參數(shù):constructingBodyWithBlock 處理要上傳的文件數(shù)據(jù)
     第四個參數(shù):進度回調(diào)
     第五個參數(shù):成功回調(diào) responseObject:響應(yīng)體信息
     第六個參數(shù):失敗回調(diào)
     */
    [manager POST:@"" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        //使用formData來拼接數(shù)據(jù)
        /*
         第一個參數(shù):二進制數(shù)據(jù) 要上傳的文件參數(shù)
         第二個參數(shù):服務(wù)器規(guī)定的
         第三個參數(shù):該文件上傳到服務(wù)器以什么名稱保存
         */
        //[formData appendPartWithFileData:imageData name:@"file" fileName:@"xxxx.png" mimeType:@"image/png"];
        
        //[formData appendPartWithFileURL:[NSURL fileURLWithPath:@"/Users/xiaomage/Desktop/Snip.png"] name:@"file" fileName:@"123.png" mimeType:@"image/png" error:nil];
        
        [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"/Users/xiaomage/Desktop/Snip.png"] name:@"file" error:nil];
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
    }];
}

2、請求類封裝

#import <Foundation/Foundation.h>
#import "AFNetworking.h"

@interface YYHttpTool : NSObject
/**
 *  發(fā)送一個GET請求
 *
 *  @param url     請求路徑
 *  @param params  請求參數(shù)
 *  @param success 請求成功后的回調(diào)(請將請求成功后想做的事情寫到這個block中)
 *  @param failure 請求失敗后的回調(diào)(請將請求失敗后想做的事情寫到這個block中)
 */
+ (void)get:(NSString *)url params:(NSDictionary *)params success:(void(^)(id responseObj))success failure:(void(^)(NSError *error))failure;

/**
 *  發(fā)送一個POST請求
 *
 *  @param url     請求路徑
 *  @param params  請求參數(shù)
 *  @param success 請求成功后的回調(diào)(請將請求成功后想做的事情寫到這個block中)
 *  @param failure 請求失敗后的回調(diào)(請將請求失敗后想做的事情寫到這個block中)
 */
+ (NSURLSessionDataTask *)post:(NSString *)url params:(NSDictionary *)params success:(void(^)(id responseObj))success failure:(void(^)(NSError *error))failure;
@end


#import "YYHttpTool.h"


@implementation YYHttpTool
+(void)get:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
    //1.獲得請求管理者
    AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
    
    //2.發(fā)送Get請求
    [mgr GET:url parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            success(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failure) {
            failure(error);
        }
    }];
}

+(NSURLSessionDataTask *)post:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
    //1.獲得請求管理者
    AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
    
   NSURLSessionDataTask *dataTask = [mgr POST:url parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
       
       if (success) {
           success(responseObject);
       }
       
   } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
       
       if (failure) {
           failure(error);
       }
   }];
    
    return dataTask;
}
@end

3、NSMutableURLRequest+XMGUpload 分類 上傳的時候會使用 具體參照《iOS網(wǎng)絡(luò)請求策略——NSURLSession的基本使用》中上傳操作

#import <Foundation/Foundation.h>

@interface NSMutableURLRequest (XMGUpload)

/**
 *  生成單文件上傳的 multipart/form-data 請求
 *
 *  @param URL     上傳地址
 *  @param fileURL 要上傳的本地文件地址
 *  @param name    服務(wù)器參數(shù)名稱
 *
 *  @return multipart/form-data POST 請求,保存到服務(wù)器的文件名與本地的文件名一致
 */
+ (instancetype)requestWithURL:(NSURL *)URL fileURL:(NSURL *)fileURL name:(NSString *)name;

/**
 *  生成單文件上傳的 multipart/form-data 請求
 *
 *  @param URL      上傳地址
 *  @param fileURL  要上傳的本地文件地址
 *  @param fileName 要保存在服務(wù)器上的文件名
 *  @param name     服務(wù)器參數(shù)名稱
 *
 *  @return multipart/form-data POST 請求
 */
+ (instancetype)requestWithURL:(NSURL *)URL fileURL:(NSURL *)fileURL fileName:(NSString *)fileName name:(NSString *)name;

/**
 *  生成多文件上傳的 multipart/form-data 請求
 *
 *  @param URL      上傳地址
 *  @param fileURLs 要上傳的本地文件地址 數(shù)組
 *  @param name     服務(wù)器參數(shù)名稱
 *
 *  @return multipart/form-data POST 請求,保存到服務(wù)器的文件名與本地的文件名一致
 */
+ (instancetype)requestWithURL:(NSURL *)URL fileURLs:(NSArray *)fileURLs name:(NSString *)name;

/**
 *  生成多文件上傳的 multipart/form-data 請求
 *
 *  @param URL       上傳地址
 *  @param fileURLs  要上傳的本地文件地址 數(shù)組
 *  @param fileNames 要保存在服務(wù)器上的文件名 數(shù)組
 *  @param name      服務(wù)器參數(shù)名稱
 *
 *  @return multipart/form-data POST 請求
 */
+ (instancetype)requestWithURL:(NSURL *)URL fileURLs:(NSArray *)fileURLs fileNames:(NSArray *)fileNames name:(NSString *)name;


@end


#import "NSMutableURLRequest+XMGUpload.h"

@implementation NSMutableURLRequest (XMGUpload)

+ (instancetype)requestWithURL:(NSURL *)URL fileURL:(NSURL *)fileURL name:(NSString *)name {
    return [self requestWithURL:URL fileURLs:@[fileURL] name:name];
}

+ (instancetype)requestWithURL:(NSURL *)URL fileURL:(NSURL *)fileURL fileName:(NSString *)fileName name:(NSString *)name {
    return [self requestWithURL:URL fileURLs:@[fileURL] fileNames:@[fileName] name:name];
}

+ (instancetype)requestWithURL:(NSURL *)URL fileURLs:(NSArray *)fileURLs name:(NSString *)name {
    
    NSMutableArray *fileNames = [NSMutableArray arrayWithCapacity:fileURLs.count];
    [fileURLs enumerateObjectsUsingBlock:^(NSURL *fileURL, NSUInteger idx, BOOL *stop) {
        [fileNames addObject:fileURL.path.lastPathComponent];
    }];
    
    return [self requestWithURL:URL fileURLs:fileURLs fileNames:fileNames name:name];
}

+ (instancetype)requestWithURL:(NSURL *)URL fileURLs:(NSArray *)fileURLs fileNames:(NSArray *)fileNames name:(NSString *)name {
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
    
    request.HTTPMethod = @"POST";
    
    NSMutableData *data = [NSMutableData data];
    NSString *boundary = multipartFormBoundary();
    
    if (fileURLs.count > 1) {
        name = [name stringByAppendingString:@"[]"];
    }
    
    [fileURLs enumerateObjectsUsingBlock:^(NSURL *fileURL, NSUInteger idx, BOOL *stop) {
        NSString *bodyStr = [NSString stringWithFormat:@"\n--%@\n", boundary];
        [data appendData:[bodyStr dataUsingEncoding:NSUTF8StringEncoding]];
        
        NSString *fileName = fileNames[idx];
        bodyStr = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\" \n", name, fileName];
        [data appendData:[bodyStr dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:[@"Content-Type: application/octet-stream\n\n" dataUsingEncoding:NSUTF8StringEncoding]];
        
        [data appendData:[NSData dataWithContentsOfURL:fileURL]];
        
        [data appendData:[@"\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }];
    
    NSString *tailStr = [NSString stringWithFormat:@"--%@--\n", boundary];
    [data appendData:[tailStr dataUsingEncoding:NSUTF8StringEncoding]];
    
    request.HTTPBody = data;
    
    NSString *headerString = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:headerString forHTTPHeaderField:@"Content-Type"];
    
    return request;
}

static NSString * multipartFormBoundary() {
    return [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()];
}
@end

二、XML解析(GET請求為例)

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    [self get];
}

- (void)get{
    // 創(chuàng)建會話管理者
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 返回的是xml的數(shù)據(jù),修改AFN的解析方案
    manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
    // 如果返回的數(shù)據(jù)既不是xml也不是json那么應(yīng)該修改解析方案 比如圖片
//    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    // 如果請求的是網(wǎng)站(html)
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];
    NSDictionary *params = @{
                             @"type":@"XML"
                             };
    
    // 發(fā)送get請求和發(fā)送post請求的方式相同,AFN把請求路徑和參數(shù)進行了分離
    [manager GET:@"" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        // NSLog(@"%@",responseObject);
        
        // 創(chuàng)建解析器
        
        NSXMLParser *parser = (NSXMLParser *)responseObject;
        
        // 設(shè)置代理
        parser.delegate = self;
        
        // 開始解析
        [parser parse];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (error) {
            
            NSLog(@"error--%@",error);
            
        }
        
    }];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(nonnull NSDictionary<NSString *,NSString *> *)attributeDict{

    NSLog(@"%@--%@",elementName,attributeDict);
}


三、網(wǎng)絡(luò)狀態(tài)監(jiān)測

// 檢測網(wǎng)絡(luò)狀態(tài)

- (void)kvoStatus{

    // 獲得一個網(wǎng)絡(luò)狀態(tài)管理者
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager manager];
    
    // 監(jiān)聽網(wǎng)絡(luò)狀態(tài)改變
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        /*
         AFNetworkReachabilityStatusUnknown          = -1,未知
         AFNetworkReachabilityStatusNotReachable     = 0,沒有網(wǎng)絡(luò)
         AFNetworkReachabilityStatusReachableViaWWAN = 1,蜂窩網(wǎng)絡(luò)
         AFNetworkReachabilityStatusReachableViaWiFi = 2,wifi

         */
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
                NSLog(@"AFNetworkReachabilityStatusUnknown");
                break;
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"AFNetworkReachabilityStatusNotReachable");
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"AFNetworkReachabilityStatusReachableViaWWAN");
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"AFNetworkReachabilityStatusReachableViaWiFi");
                break;
            default:
                break;
        }
        
    }];
    
    // 開始監(jiān)聽
    [manager stopMonitoring];
}

四、https請求的處理(GET請求為例)

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    [self get];
}

- (void)get{
  // 創(chuàng)建會話管理者
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 對于解析方式修改 https請求
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    // 設(shè)置證書的處理方式 接收無效的證書
    manager.securityPolicy.allowInvalidCertificates = YES;
    // 設(shè)置對域名驗證為無效
    manager.securityPolicy.validatesDomainName = NO;
    
    NSDictionary *params = @{
                          @"username":@"123",
                          @"pwd":@"123",
                          @"type":@"JSON"
                          };
    
    // 發(fā)送get請求和發(fā)送post請求的方式相同,AFN把請求路徑和參數(shù)進行了分離
    [manager GET:@"" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSLog(@"%@",responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
    }];
}

五、https簡介

/**
 * https簡單說明
 HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全為目標(biāo)的HTTP通道,簡單講是HTTP的安全版。
 即HTTP下加入SSL層,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL。 它是一個URI scheme(抽象標(biāo)識符體系),句法類同http:體系。用于安全的HTTP數(shù)據(jù)傳輸。
 https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默認(rèn)端口及一個加密/身份驗證層(在HTTP與TCP之間)。
 
 2.HTTPS和HTTP的區(qū)別主要為以下四點:
 一、https協(xié)議需要到ca申請證書,一般免費證書很少,需要交費。
 二、http是超文本傳輸協(xié)議,信息是明文傳輸,https 則是具有安全性的ssl加密傳輸協(xié)議。
 三、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
 四、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。
 
 3.簡單說明
 1)HTTPS的主要思想是在不安全的網(wǎng)絡(luò)上創(chuàng)建一安全信道,并可在使用適當(dāng)?shù)募用馨头?wù)器證書可被驗證且可被信任時,對竊聽和中間人攻擊提供合理的保護。
 2)HTTPS的信任繼承基于預(yù)先安裝在瀏覽器中的證書頒發(fā)機構(gòu)(如VeriSign、Microsoft等)(意即“我信任證書頒發(fā)機構(gòu)告訴我應(yīng)該信任的”)。
 3)因此,一個到某網(wǎng)站的HTTPS連接可被信任,如果服務(wù)器搭建自己的https 也就是說采用自認(rèn)證的方式來建立https信道,這樣一般在客戶端是不被信任的。
 4)所以我們一般在瀏覽器訪問一些https站點的時候會有一個提示,問你是否繼續(xù)。
 */
- (void)https{

    // 確定URL
    NSURL *url = [NSURL URLWithString:@""];
    
    // 創(chuàng)建請求對象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 創(chuàng)建會話對象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    // 創(chuàng)建任務(wù)
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
    }];
    // 開啟任務(wù)
    [task resume];
}
// 對于大型的網(wǎng)站并不會去質(zhì)詢,因為證書是強制安裝的,數(shù)據(jù)可以直接拿到
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{

    
    if (![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) {
        
        return;
    }
    NSLog(@"%@",challenge.protectionSpace);
    /*
     NSURLSessionAuthChallengeDisposition 如何處理證書
     NSURLSessionAuthChallengeUseCredential = 0,  使用該證書 安裝證書                                     
    NSURLSessionAuthChallengePerformDefaultHandling = 1,默認(rèn)采用方式 忽略
    NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2, 證書被忽略 請求被取消
    NSURLSessionAuthChallengeRejectProtectionSpace = 3, 拒絕安裝
     */
    
    // 創(chuàng)建身份信息
    NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
    
    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);

   }


寫在最后的話:關(guān)于AFNetworking的使用今天就分享到這里,關(guān)于AFNetworking使用方面的問題歡迎大家和我交流,共同進步,謝謝各位。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容