YTKNetwork再次封裝

一耐量、前言

最近一段時(shí)間盒延,想著封裝一套網(wǎng)絡(luò)庫缩擂,在查資料時(shí)看到了YTKNetwork下載地址添寺,它基本包含的網(wǎng)絡(luò)請(qǐng)求的所有功能胯盯,而且在GitHub上的星星數(shù)也都有了5k+了,我就仔細(xì)的看了看计露,嗯博脑,真香憎乙,基本上能用的功能全都有了!越看越想把自己工程里的網(wǎng)絡(luò)庫給換掉(自己封裝的AFNetworking)叉趣,但又發(fā)現(xiàn)了YTKNetwork的用法跟我項(xiàng)目中本身有點(diǎn)不兼容泞边,于是乎我就想把它再次封裝一下,畢竟按照它提供的用法疗杉,一個(gè)接口就得有一個(gè)對(duì)應(yīng)的類來控制阵谚,小業(yè)務(wù)量的App還好,但是大項(xiàng)目豈不是要?jiǎng)?chuàng)建一堆的接口類烟具,我想應(yīng)該有不少小伙伴有同樣的問題梢什,伴隨著這個(gè)問題為出發(fā)點(diǎn),開始了再次封裝的嘗試朝聋。

二嗡午、思路

一個(gè)接口由一個(gè)類來控制,emm...冀痕,這是要解決的最重要的一個(gè)問題荔睹。而我要做的是由一個(gè)類來控制所有接口孔飒。首先我想到的就是寫一個(gè)接口類师抄,然后每個(gè)請(qǐng)求對(duì)應(yīng)接口類里的一個(gè)方法策泣,然后再調(diào)用YTKNetwork來轉(zhuǎn)發(fā)淤毛。其它用法要盡量不改變YTKNetwork宅此,以避免因?yàn)樵俜庋b原因而導(dǎo)致YTKNetwork內(nèi)部邏輯的bug秋秤。

三椭符、開始搬磚

1.解決YTKNetwork所有參數(shù)都是通過方法來傳遞

在官方示例中薯演,我們可以看到跟伏,方法請(qǐng)求的地址(后綴地址)丢胚、請(qǐng)求參數(shù)等都只能通過重寫- (NSString *)requestUrl- (nullable id)requestArgument,我在這里的解決思路是寫一個(gè)YTKRequest的分類受扳,然后再添加兩個(gè)屬性fUrl携龟、param,然后分別在兩個(gè)方法返回這兩個(gè)屬性值勘高。

//
//  YTKRequest+FuHttp.h
//  FuHttpDemo
//
//  Created by 付海龍 on 2019/3/25.
//  Copyright ? 2019 付海龍. All rights reserved.
//

#import "YTKRequest.h"

NS_ASSUME_NONNULL_BEGIN

@interface YTKRequest (FuHttp)
@property (nonatomic, copy) NSString *fUrl;             //requestUrl
@property (nonatomic, copy) NSDictionary *param;        //requestArgument
@end
//
//  YTKRequest+FuHttp.m
//  FuHttpDemo
//
//  Created by 付海龍 on 2019/3/25.
//  Copyright ? 2019 付海龍. All rights reserved.
//

#import "YTKRequest+FuHttp.h"
#import "FuHttpMethod.h"
#import "YYKit.h"

@implementation YTKRequest (FuHttp)

static NSString *fUrlKey            = @"F_URL_KEY";
static NSString *paramKey           = @"PARAM_KEY";
static NSString *fuHttpTypeKey      = @"RESULT_BLOCK_KEY";

- (void)setFUrl:(NSString *)fUrl {
    objc_setAssociatedObject(self, &fUrlKey, fUrl, OBJC_ASSOCIATION_COPY);
}

- (NSString *)fUrl {
    return objc_getAssociatedObject(self, &fUrlKey);
}

- (void)setParam:(NSDictionary *)param {
    objc_setAssociatedObject(self, &paramKey, param, OBJC_ASSOCIATION_COPY);
}

- (NSDictionary *)param {
    return objc_getAssociatedObject(self, &paramKey);
}

pragma mark - 重寫YTKRequest方法

- (NSString *)requestUrl {
    return self.fUrl;
}

- (nullable id)requestArgument {
    return self.param;
}

- (NSTimeInterval)requestTimeoutInterval {
    //超時(shí)時(shí)間 
    return 10;
}

- (nullable NSDictionary<NSString *, NSString *> *)requestHeaderFieldValueDictionary {
    return 請(qǐng)求頭;
}

2.數(shù)據(jù)傳遞

我們封裝了YTKNetwork那請(qǐng)求回來的數(shù)據(jù)也在封裝的類里峡蟋,解決數(shù)據(jù)傳遞,回傳給需要用到的地方华望,在這個(gè)分類里蕊蝗,使用了block

typedef void(^RequestResult)(BOOL isSuccess, id object);

@property (nonatomic, copy) RequestResult resultBlock;  //數(shù)據(jù)傳遞
static NSString *resultBlockKey     = @"RESULT_BLOCK_KEY";

- (void)setResultBlock:(void (^)(BOOL, id _Nonnull))block {
    objc_setAssociatedObject(self, &resultBlockKey, block, OBJC_ASSOCIATION_COPY);
}

- (RequestResult)resultBlock {
    return objc_getAssociatedObject(self, &resultBlockKey);
}

3.GETPOST請(qǐng)求處理

官方示例中,請(qǐng)求發(fā)送的是GET還是POST需要通過- (YTKRequestMethod)requestMethod來指定赖舟,這里我們也可以參考上面的方法

@property (nonatomic, copy) NSNumber *requestType;      //請(qǐng)求類型 Get or Post
static NSString *requestTypeKey     = @"REQUEST_TYPE_KEY";

- (void)setRequestType:(NSNumber *)requestType
{
    objc_setAssociatedObject(self, &requestTypeKey, requestType, OBJC_ASSOCIATION_COPY);
}

- (NSNumber *)requestType
{
    return objc_getAssociatedObject(self, &requestTypeKey);
}

- (YTKRequestMethod)requestMethod {
    return self.requestType.integerValue;
}

4.獲得YTKRequest對(duì)象

基本上需要用到的參數(shù)及方法都準(zhǔn)備好了蓬戚,剩下的就是將生成YTKRequest對(duì)象并將對(duì)應(yīng)的屬性賦值,這里我添加了一個(gè)類方法來實(shí)現(xiàn)

- (void)setRequestType:(NSUInteger)type param:(NSDictionary *)param requestType:(NSInteger)requestType replace:(NSString *)replace {
    NSString *url = [[FuHttpMethod sharedMethod] typeMethod:type];
    if ([url containsString:@"<id>"]) {
        if (replace.isNotBlank) {
            self.fUrl = [url stringByReplacingOccurrencesOfString:@"<id>"
                                                       withString:replace];
        }else {
            self.fUrl = [url stringByReplacingOccurrencesOfString:@"<id>"
                                                       withString:@""];
        }
    }else {
        self.fUrl = url;
    }
    self.param = param;
    self.FuHttpType = [NSNumber numberWithUnsignedInteger:type];
    self.requestType = [NSNumber numberWithInteger:requestType];
}

+ (YTKRequest *)getYTK:(NSUInteger)type param:(NSDictionary *)param requestType:(NSInteger)requestType replace:(NSString *)replace {
    YTKRequest *ytk = [[YTKRequest alloc] init];
    [ytk setRequestType:type
                  param:param
            requestType:requestType
                replace:replace];
    return ytk;
}

5.接口類的實(shí)現(xiàn)

接口類的實(shí)現(xiàn)部份比較簡(jiǎn)單宾抓,沒什么可說的子漩,就是寫上對(duì)應(yīng)的GetPost的調(diào)取方法豫喧,聲明一個(gè)代理,方便通知請(qǐng)求開始幢泼、請(qǐng)求成功請(qǐng)求失敗的三種情況紧显,然后子類繼承這個(gè)類,子類主要就是做一個(gè)接口對(duì)應(yīng)一個(gè)方法的實(shí)現(xiàn)

//
//  FuHttpRequest.h
//  FuHttpDemo
//
//  Created by 付海龍 on 2019/3/25.
//  Copyright ? 2019 付海龍. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "YTKNetwork.h"
#import "FuHttpMethod.h"
#import "FuError.h"

NS_ASSUME_NONNULL_BEGIN

@class FuHttpRequest;
@protocol FuHttpRequestDelegate <NSObject>
@optional
- (void)httpStartRequest:(YTKBaseRequest *)requestObject;
- (void)httpFinishRequest:(YTKBaseRequest *)requestObject object:(id)object;
- (void)httpFailedRequest:(YTKBaseRequest *)requestObject error:(FuError *)error;
@end

@interface FuHttpRequest : NSObject
@property (nonatomic, weak) id<FuHttpRequestDelegate> delegate;
@property (nonatomic, assign) NSInteger requestTag;
+ (id)initWithDelegate:(id<FuHttpRequestDelegate>)delegate;
- (YTKRequest *)requestGet:(NSUInteger)type param:(nullable id)param replace:(nullable NSString *)replace;
- (YTKRequest *)requestPost:(NSUInteger)type param:(nullable id)param replace:(nullable NSString *)replace;;
@end
//
//  FuHttpInterface.h
//  FuHttpDemo
//
//  Created by 付海龍 on 2019/3/25.
//  Copyright ? 2019 付海龍. All rights reserved.
//

#import "FuHttpRequest.h"
#import "YTKRequest+FuHttp.h"

NS_ASSUME_NONNULL_BEGIN

@interface FuHttpInterface : FuHttpRequest

- (YTKRequest *)http_testPost:(NSString *)str;
- (YTKRequest *)http_testGet;

@end

NS_ASSUME_NONNULL_END
//
//  FuHttpInterface.m
//  FuHttpDemo
//
//  Created by 付海龍 on 2019/3/25.
//  Copyright ? 2019 付海龍. All rights reserved.
//

#import "FuHttpInterface.h"
#import "YYKit.h"

@implementation FuHttpInterface

- (YTKRequest *)http_testPost:(NSString *)str {
    NSDictionary *param = nil;
    if (str.isNotBlank) {
        param = @{@"query":str};
    }
    return [self requestPost:TEST_POST param:param replace:nil];
}

- (YTKRequest *)http_testGet {
    return [self requestGet:TEST_GET param:nil replace:nil];
}

@end

我這里簡(jiǎn)單寫了兩個(gè)例子缕棵,按現(xiàn)在這樣孵班,如果有新的接口,只需要在這里編寫對(duì)應(yīng)的調(diào)用方法就可以了

6.關(guān)于TEST_GETTEST_POST

在上面的接口類里挥吵,并沒有看到傳入的requestUrl重父,而代替它的就是TEST_GETTEST_POST,我在封裝的時(shí)候順便也把接口的聲明也做了處理忽匈,在FuHttpMethod類里,小伙伴們?cè)谟玫臅r(shí)候矿辽,只需要在.h文件里的枚舉添加一個(gè)case丹允,在.m里添加對(duì)應(yīng)的requestUrl就可以了,至于其綁定邏輯我就不多介紹了袋倔,很簡(jiǎn)單雕蔽,想看的小伙伴可以看我在文章最后上傳的Demo。

typedef NS_ENUM(NSInteger, FuHttpType) {
    FU_HTTP_BEGIN = -1,
    
    TEST_POST,      //測(cè)試POST請(qǐng)求
    TEST_GET,       //測(cè)試GET請(qǐng)求
    
    FU_HTTP_END,
};
HTTP_INFO(@"test/post/requestUrl", TEST_POST);
HTTP_INFO(@"test/get/requestUrl", TEST_GET);

7.測(cè)試一下

AppDelegate.mdidFinishLaunchingWithOptions方法里添加對(duì)YTKNetworkConfig的配置宾娜,這里沒有改動(dòng)批狐,按照YTKNetwork的用法來就好

    YTKNetworkConfig *config = [YTKNetworkConfig sharedConfig];
    /*
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"證書名" ofType:@"后綴"];
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    config.securityPolicy.allowInvalidCertificates = YES;
    config.securityPolicy.validatesDomainName = NO;
    config.securityPolicy.pinnedCertificates = [NSSet setWithObject:certData];
     */
    config.baseUrl = @"你的baseUrl";

ViewController.mviewDidLoad里,先對(duì)接口類進(jìn)行初始化前塔,進(jìn)行測(cè)試

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.http = [[FuHttpInterface alloc] init];
    
//    [self postTest];
    [self getTest];
}

- (void)postTest {
    [[self.http http_testPost:@"abc"] setResultBlock:^(BOOL isSuccess, id  _Nonnull object) {
        if (isSuccess) {
            NSLog(@"請(qǐng)求成功");
        }else {
            NSLog(@"請(qǐng)求失敗");
        }
    }];
}

- (void)getTest {
    [[self.http http_testGet] setResultBlock:^(BOOL isSuccess, id  _Nonnull object) {
        if (isSuccess) {
            NSLog(@"請(qǐng)求成功");
        }else {
            NSLog(@"請(qǐng)求失敗");
        }
    }];
}

當(dāng)你能看到控制臺(tái)有-[FuHttpRequest requestSuccess:request:] [Line 86] 數(shù)據(jù)信息:這樣的字樣時(shí)就代表請(qǐng)求沒問題嚣艇,而后面就是對(duì)應(yīng)請(qǐng)求回來的json,我在數(shù)據(jù)處理那寫了不少的邏輯华弓,基本上都與目前我做的項(xiàng)目有關(guān)食零,如果覺得與你的項(xiàng)目不太合適,小伙伴們可以自己稍加修改寂屏。

四贰谣、額外功能

Json轉(zhuǎn)Model時(shí),我使用了YYModel迁霎,相信很多小伙伴都給接口寫過對(duì)應(yīng)的Model文件吱抚,工作量也不小,我在Demo里添加了一個(gè)FuAnalysis類考廉,用來做這個(gè)事秘豹,當(dāng)你的工程中沒有對(duì)應(yīng)的Model時(shí),就會(huì)在控制臺(tái)輸出將要添加類的內(nèi)容芝此;如果存在憋肖,則使用YYModel解析成對(duì)應(yīng)的對(duì)象因痛。文件名及相應(yīng)的類的命名都是以接口名為基礎(chǔ),例如:requestUrlabc/def岸更,那么文件名就是DefModel鸵膏,而里面的類的名字就是Def_Item
測(cè)試一下,寫一個(gè)Json

{"RC":1,"data":{"array":[{"name":"fu","address":"北京"},{"name":"hai","tel":8888},{"name":"long","is_working":true}]}}

FuAnalysis *analysis = [[FuAnalysis alloc] init];
id object = [analysis analysisData:@"abc/def" object:[jsonStr jsonValueDecoded]];
---

ClassName : DefModel 

.h文件

@interface Def_Array_Item : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *address;
@property (nonatomic, strong) NSNumber *tel;
@property (nonatomic, strong) NSNumber *is_working;
@end


@interface Def_Data_Item : NSObject
@property (nonatomic, strong) NSArray *array;
@end

@interface Def_Item : NSObject
@property (nonatomic, strong) NSNumber *RC;
@property (nonatomic, strong) Def_Data_Item *data;
@end


---

.m文件



@implementation Def_Array_Item

@end

@implementation Def_Data_Item

+ (NSDictionary *)modelContainerPropertyGenericClass {
   return @{
            @"array":[Def_Array_Item class],
           }
}

@end

@implementation Def_Item

@end


---

工程里有對(duì)應(yīng)的Model文件

if ([object isKindOfClass:[Def_Item class]]) {
        Def_Item *item = (Def_Item *)object;
        [item.data.array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            Def_Array_Item *item = (Def_Array_Item *)obj;
            NSLog(@"%@", item.name);
        }];
    }
2019-03-27 17:46:25.116733+0800 FuYTKDemo[7311:458718] fu
2019-03-27 17:46:25.116862+0800 FuYTKDemo[7311:458718] hai
2019-03-27 17:46:25.116954+0800 FuYTKDemo[7311:458718] long

測(cè)試成功怎炊!

Demo下載地址

有關(guān)代碼中出現(xiàn)的<id>谭企,它是我們項(xiàng)目中requestUrl需要拼接的參數(shù),例如在Post請(qǐng)求里评肆,test/post/123债查,這樣的123直接寫到requestUrl里就不太對(duì)了,因此我加入了替換元素<id>在請(qǐng)求發(fā)送之前再將requestUrl替換好瓜挽。

最后盹廷,歡迎小伙伴在評(píng)論留言,喜歡的點(diǎn)個(gè)心久橙!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俄占,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子淆衷,更是在濱河造成了極大的恐慌缸榄,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祝拯,死亡現(xiàn)場(chǎng)離奇詭異甚带,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)佳头,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門鹰贵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人畜晰,你說我怎么就攤上這事砾莱。” “怎么了凄鼻?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵腊瑟,是天一觀的道長。 經(jīng)常有香客問我块蚌,道長闰非,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任峭范,我火速辦了婚禮财松,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己辆毡,他們只是感情好菜秦,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著舶掖,像睡著了一般球昨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上眨攘,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天主慰,我揣著相機(jī)與錄音,去河邊找鬼鲫售。 笑死共螺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的情竹。 我是一名探鬼主播藐不,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼秦效!你這毒婦竟也來了佳吞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤棉安,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后铸抑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贡耽,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年鹊汛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒲赂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡刁憋,死狀恐怖滥嘴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情至耻,我是刑警寧澤若皱,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站尘颓,受9級(jí)特大地震影響走触,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜疤苹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一互广、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦惫皱、人聲如沸像樊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽生棍。三九已至,卻和暖如春扫皱,著一層夾襖步出監(jiān)牢的瞬間足绅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國打工韩脑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留氢妈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓段多,卻偏偏與公主長得像首量,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子进苍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361