iOS-網(wǎng)絡(二)--AFNetWorking

之前有總結(jié)iOS原生網(wǎng)絡的使用,今天來總結(jié)一下基于NSURLSession封裝的優(yōu)秀開源框架AFNetWorking烙丛。

不知道有沒人和我一樣跳纳,接觸網(wǎng)絡是從AFNetWorking開始的疟暖,那個時候就覺得AFNetWorking是相當?shù)膬?yōu)秀紊搪,極大的降低了iOS開發(fā)工程師處理網(wǎng)絡請求的難度蜜葱,讓iOS開發(fā)變成一件愉快的事情,當然現(xiàn)在也是這么覺得耀石,因為自己還沒有接觸文件的上傳下載牵囤,所以這篇文章只說HTTP的兩個請求:Get和Post。

1.AFHTTPSessionManager

AFHTTPSessionManager請求管理者滞伟,是為了便利使用HTTP請求揭鳞,當一個baseURL提供時,用相對路徑構(gòu)造GET/POST等便利的方法創(chuàng)建請求梆奈,扒出部分源碼聲明如下:

@interfaceAFHTTPSessionManager:AFURLSessionManager
// 當baseURL提供時汹桦,用相對路徑構(gòu)造GET/POST等便利方法來創(chuàng)建請求
@property (readonly, nonatomic, strong, nullable) NSURL *baseURL;
// 請求數(shù)據(jù)序列化
@property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer;
// 響應數(shù)據(jù)序列化   
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;                                                                                                                                                     
// 創(chuàng)建會話使用的安全策略  
@property (nonatomic, strong) AFSecurityPolicy *securityPolicy;                                                                                                                                              
// 創(chuàng)建并返回一個‘AFHTTPSessionManager’對象 
+ (instancetype)manager;                                                                                                                          
// 使用指定的基本URL初始化對象   
- (instancetype)initWithBaseURL:(nullable NSURL *)url;                                                                                                                                                   
//Get請求
- (NSURLSessionDataTask *)GET:(NSString *)URLString

                   parameters:(id)parameters

                      success:(void(^)(NSURLSessionDataTask*task,idresponseObject))success

                      failure:(void(^)(NSURLSessionDataTask*task,NSError*error))failure

{

    return[selfGET:URLStringparameters:parametersprogress:nilsuccess:successfailure:failure];

}
//Post請求
- (NSURLSessionDataTask *)POST:(NSString *)URLString

                    parameters:(id)parameters

                       success:(void(^)(NSURLSessionDataTask*task,idresponseObject))success

                       failure:(void(^)(NSURLSessionDataTask*task,NSError*error))failure

{

    return[selfPOST:URLStringparameters:parametersprogress:nilsuccess:successfailure:failure];

}

@end

處理Get請求

 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    NSString*urlString =  @"http://localhost:3030/userinfo";

   NSDictionary *parameters=@{@"name":@"zyp",@"pwd":@"666"};

    [manager GET:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

         NSLog(@"請求成功");

    }failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

        NSLog(@"請求失敗");

    }];

處理Post請求

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    NSString*urlString =  @"http://localhost:3030/userinfo";

NSDictionary *parameters=@{@"name":@"zhaoyipei",@"pwd":@"yang"};

[manager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {

         NSLog(@"請求成功");

}failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

        NSLog(@"請求失敗");

    }];

AFNetWorking內(nèi)存泄露
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];一般來說鉴裹,我們會認為,這個manager是個單例钥弯,但是我們來看一下源碼:

+ (instancetype)manager {

    return [[[self class] alloc] initWithBaseURL:nil];

}

然后發(fā)現(xiàn)被騙了径荔,它其實是每次都實例化一個AFHTTPSessionManager對象,所以必要的時候需要自己封裝一下脆霎。
簡單實現(xiàn)NSURLSession封裝
.h文件

//請求序列化格式

typedef enum {

    HTTPRequestSerializationURLEncoded =0,

    HTTPRequestSerializationJSON

} HTTPRequestSerializationType;

@interface HTTPRequestManager : NSObject

+ (instancetype)manager;

@property (nonatomic, assign) HTTPRequestSerializationType serializationType;

- (void)GET:(NSString *)URL

 parameters:(NSDictionary *)parameters

    success:(void(^)(idobject))success

    failure:(void(^)(NSError*error))failure;

- (void)POST:(NSString *)URL

  parameters:(NSDictionary *)parameters

     success:(void(^)(idobject))success

     failure:(void(^)(NSError*error))failure;

@end

.m文件

#import "HTTPRequestManager.h"

@implementation HTTPRequestManager

+ (instancetype)manager
{
    return [[self alloc] init];
}

- (void)GET:(NSString *)URL
 parameters:(NSDictionary *)parameters
    success:(void (^)(id _Nonnull))success
    failure:(void (^)(NSError * _Nonnull))failure
{
    if (URL.length == 0) {
        if (failure) {
            failure([NSError errorWithDomain:@"123" code:-1 userInfo:nil]);
        }
        return;
    }
    //Get請求的內(nèi)容是拼接在URL后面的总处,所以要通過NSURLComponents對parameters進行處理
    NSURLComponents *URLcomponents = [NSURLComponents componentsWithString:URL];
    NSArray *old = URLcomponents.queryItems;
    NSMutableArray *array = old ? [old mutableCopy] : [NSMutableArray new];   
    [parameters enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        
        NSURLQueryItem *queryItem = [NSURLQueryItem queryItemWithName:key value:obj];
        [array addObject:queryItem];
    }];
    
    URLcomponents.queryItems = array;
    
    // 1.創(chuàng)建請求會話
    NSURLSession *session = [NSURLSession sharedSession];
    
    // 2.創(chuàng)建請求
    NSURLRequest *request = [NSURLRequest requestWithURL:URLcomponents.URL];
    // 3.創(chuàng)建請求任務
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            if (failure) {
                failure(error);
            }
            return;
        }
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        if (success) {
            success(json);
        }
    }];
    // 4.開始任務
    [task resume];
}

- (void)POST:(NSString *)URL
  parameters:(NSDictionary *)parameters
     success:(void (^)(id _Nonnull))success
     failure:(void (^)(NSError * _Nonnull))failure
{
    NSURL *requestURL = [NSURL URLWithString:URL];
    NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:requestURL];
    mRequest.HTTPMethod = @"POST";
    //根據(jù)MIME類型睛蛛,對parameters進行處理
    if (parameters.count) {
        if (self.serializationType == HTTPRequestSerializationJSON) {
            [mRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
            mRequest.HTTPBody = [NSJSONSerialization dataWithJSONObject:parameters options:kNilOptions error:NULL];
        } else {
            [mRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
            NSMutableArray *array = [[NSMutableArray alloc]initWithCapacity:parameters.count];
            [parameters enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
                [array addObject:[NSString stringWithFormat:@"%@=%@", key, obj]];
            }];
            NSString *urlEncode = [array componentsJoinedByString:@"&"];
            mRequest.HTTPBody = [urlEncode dataUsingEncoding:NSUTF8StringEncoding];
        }
    }
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:mRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            if (failure) {
                failure(error);
            }
            return;
        }
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        if (success) {
            success(json);
        }
    }];
    // 4.開始任務
    [task resume];
}
@end

然后呢鹦马,就會發(fā)現(xiàn)這個看起來太臃腫,并且很明顯忆肾,在Get請求和Post請求都涉及到NSURLSession和NSURLSessionDataTask荸频,只是在NSURLRequest的處理上有差異,所以我們可以進一步將NSURLSessionDataTask進行封裝客冈,完了之后結(jié)果如下:

- (void)GET:(NSString *)URL
 parameters:(NSDictionary *)parameters
    success:(void (^)(id _Nonnull))success
    failure:(void (^)(NSError * _Nonnull))failure
{
    if (URL.length == 0) {
        if (failure) {
            failure([NSError errorWithDomain:@"123" code:-1 userInfo:nil]);
        }
        return;
    }
    NSURLComponents *URLcomponents = [NSURLComponents componentsWithString:URL];
    NSArray *old = URLcomponents.queryItems;
    
    NSMutableArray *array = old ? [old mutableCopy] : [NSMutableArray new];
    
    [parameters enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        
        NSURLQueryItem *queryItem = [NSURLQueryItem queryItemWithName:key value:obj];
        [array addObject:queryItem];
    }];
    
    URLcomponents.queryItems = array;
    // 2.創(chuàng)建請求
       NSURLRequest *request = [NSURLRequest requestWithURL:URLcomponents.URL];
      [self request:request success:success failure:failure];
}

- (void)POST:(NSString *)URL
  parameters:(NSDictionary *)parameters
     success:(void (^)(id _Nonnull))success
     failure:(void (^)(NSError * _Nonnull))failure
{
    NSURL *requestURL = [NSURL URLWithString:URL];
    NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:requestURL];
    mRequest.HTTPMethod = @"POST";
    if (parameters.count) {
        if (self.serializationType == HTTPRequestSerializationJSON) {
            [mRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
            mRequest.HTTPBody = [NSJSONSerialization dataWithJSONObject:parameters options:kNilOptions error:NULL];
        } else {
            [mRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
            NSMutableArray *array = [[NSMutableArray alloc]initWithCapacity:parameters.count];
            [parameters enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
                [array addObject:[NSString stringWithFormat:@"%@=%@", key, obj]];
            }];
            NSString *urlEncode = [array componentsJoinedByString:@"&"];
            mRequest.HTTPBody = [urlEncode dataUsingEncoding:NSUTF8StringEncoding];
        }
    }
    [self request:mRequest success:success failure:failure];
}
- (void)request:(NSURLRequest *)request
            success:(void (^)(id _Nonnull))success
            failure:(void (^)(NSError * _Nonnull))failure {
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            if (failure) {
                failure(error);
            }
            return;
        }
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        if (success) {
            success(json);
        }
    }];
    // 4.開始任務
    [task resume];
    
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旭从,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子场仲,更是在濱河造成了極大的恐慌和悦,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渠缕,死亡現(xiàn)場離奇詭異鸽素,居然都是意外死亡,警方通過查閱死者的電腦和手機亦鳞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門馍忽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棒坏,“玉大人,你說我怎么就攤上這事舵匾】〉郑” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵坐梯,是天一觀的道長徽诲。 經(jīng)常有香客問我,道長吵血,這世上最難降的妖魔是什么谎替? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮蹋辅,結(jié)果婚禮上钱贯,老公的妹妹穿的比我還像新娘。我一直安慰自己侦另,他們只是感情好秩命,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著褒傅,像睡著了一般弃锐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上殿托,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天霹菊,我揣著相機與錄音,去河邊找鬼支竹。 笑死旋廷,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的礼搁。 我是一名探鬼主播饶碘,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼馒吴!你這毒婦竟也來了熊镣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤募书,失蹤者是張志新(化名)和其女友劉穎绪囱,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體莹捡,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡鬼吵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了篮赢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片齿椅。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡琉挖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涣脚,到底是詐尸還是另有隱情示辈,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布遣蚀,位于F島的核電站矾麻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏芭梯。R本人自食惡果不足惜险耀,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望玖喘。 院中可真熱鬧甩牺,春花似錦、人聲如沸累奈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澎媒。三九已至赠群,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旱幼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工突委, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留柏卤,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓匀油,卻偏偏與公主長得像缘缚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子敌蚜,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容