YTK理解

一、YTK的Git庫地址

https://github.com/yuantiku/YTKNetwork/blob/master/Docs/BasicGuide_cn.md
里面有YTK的中文說明,以及一些場景的用法,下面我們來看一下我們項目的一些使用場景

二、基類的封裝

1、我們現(xiàn)在所用的接口請求是在YTK的基礎(chǔ)上在封裝了一層(房信平臺封裝了2層,因為要加上緩存以及加密等邏輯),那房信平臺的FangChaChaRequest來說,繼承于EtopBaseRequest,EtopBaseRequest主要做了設(shè)置接口的請求方式(有兩種請求方式,POST和GET,注上兩者區(qū)別https://www.cnblogs.com/logsharing/p/8448446.html,一般都用POST(更安全));重寫自定義請求頭的方法,塞入請求頭的樣式;以及解析返回結(jié)果的格式(JSON,XML,Data三種,一般都用JSON);封裝調(diào)用請求的方法;

image.png

image.png

2、下面我們看FangChaChaRequest做了什么?
(1)首先涉及加密的邏輯處理,我們要對接口的請求參數(shù)進(jìn)行加密,這里的加密會每次根據(jù)App啟動隨機(jī)變成加密值,加密的代碼附上如下圖
image.png

(2)設(shè)置請求失敗提示時間(一般都是15s)

- (NSTimeInterval)requestTimeoutInterval {
//    if (DEBUG) {
//        return 5;
//    }
    return 15;
}

(3)重寫- (void)startWithCompletionHandlerWithSuccess:(nullable ETopRequestSuccessBlock)success failure:(nullable ETopRequestFailureBlock)failure方法,請求成功的時候先判斷開沒開起緩存,如果有先返回緩存數(shù)據(jù),這里一定要注意的是如果用戶開啟了緩存,即使緩存成功,我們也需在重新調(diào)用一次請求方法,更新緩存,否則每次拿到的都是頭一次緩存的結(jié)果;
a、請求成功


image.png

b、請求失敗,拿到錯誤信息,判斷是否是證書錯誤


image.png

(4)特別注意的是因為我們對請求參數(shù)進(jìn)行了加密,然后YTK的緩存是把請求參數(shù)當(dāng)做Key,前面有提過APP啟動的時候加密會隨機(jī),這個時候我們的緩存的Key變了,我們就拿不到上一次緩存數(shù)據(jù)的值,所以,我們加密后必須在FangChaChaRequest里面重寫YTK的獲取Key的- (id)cacheFileNameFilterForRequestArgument:(id)argument這個方法,返回我們未加密前的請求參數(shù)

- (id)cacheFileNameFilterForRequestArgument:(id)argument {
    if ((NSNull *)self.unEncryptorArgument != [NSNull null] && self.unEncryptorArgument.count > 0) {
        return self.unEncryptorArgument;
    } else {
        return argument;
    }
}

三、應(yīng)用場景

1、緩存使用

在上面封裝完畢后,只需要在我們的API文件中,重寫- (NSInteger)cacheTimeInSeconds這個方法,并設(shè)置你想要緩存的時間(一般我們返回最大值)

- (NSInteger)cacheTimeInSeconds {
    return NSIntegerMax;
}

2、異步請求

(1)YTK的異步請求適用于兩個接口之間沒什么依賴;但是YTK的異步請求會有一個接口請求失敗,接口就返回失敗;正常來說,邏輯也應(yīng)該這么處理,雖然兩個接口沒有依賴,但是如果一個界面有兩個接口,又是異步請求,如果不知道那個接口先回來,布局比較麻煩,所以還是一個接口接口失敗直接失敗處理比較好;最先我不會YTK的異步請求的時候?qū)懥艘粋€非常low的請求方法(捂臉),block里面調(diào)用block,請求成功調(diào)用一次,失敗在調(diào)用一次


image.png

所以使用YTK的異步請求后,我們只需要調(diào)用一個方法,也不需要寫這么多回調(diào)的block


image.png

(2)值得注意的是我們也在YTK的異步請求YTKBatchRequest做了一層我們項目邏輯的封裝FangChaChaBatchRequest,因為如果我們直接調(diào)用YTKBatchRequest,這個時候我們一些成功回調(diào)里面返回的其他狀態(tài)碼不會判斷,所以我們要在YTK的基礎(chǔ)上封裝一層加上我們邏輯處理的基類

- (void)startWithCompletionHandlerWithSuccess:(nullable ETopBatchCompletionBlock)success failure:(nullable ETopBatchCompletionBlock)failure {
    [super startWithCompletionBlockWithSuccess:^(YTKBatchRequest *_Nonnull batchRequest) {
        for (YTKRequest *request in batchRequest.requestArray) {
            id responseObjec = [request responseJSONObject];
            NSInteger statusCode = [responseObjec[@"StatsCode"] integerValue];
            statusCode = (statusCode == 0 ? [responseObjec[@"status"] integerValue] : statusCode);
            if (statusCode == SUCCEEDED_BatchRequest) {
                if (success) {
                    success((ETopBatchRequest *)batchRequest);
                }
            } else {
                if (statusCode == LoginFailCodeType) {
                    // 清空用戶信息
                    [LoginManager saveUserModel:nil];
                } else if (statusCode == AuthorizationFailedCodeType) {
                    NSLog(@"重新獲取token");
                    [[DDOAuthClient shareInstance] getTokenAndLoginWithSuccess:nil];
                }
                if (failure) {
                    NSString *message = request.responseObject[@"Message"];
                    message = message ?: request.responseObject[@"msg"];
                    failure((ETopBatchRequest *)batchRequest);
                }
            }
        }        
    }
        failure:^(YTKBatchRequest *_Nonnull batchRequest) {
            if (failure) {
                // 失敗
                NSString *description = batchRequest.failedRequest.error.localizedDescription;
                description = [description stringByReplacingOccurrencesOfString:@"." withString:@""];
                description = [description stringByReplacingOccurrencesOfString:@"。" withString:@""];
                if (batchRequest.failedRequest.error.localizedRecoverySuggestion) { // 證書錯誤
                    NSData *errorData = [[NSData alloc] initWithData:[batchRequest.failedRequest.error.localizedRecoverySuggestion dataUsingEncoding:NSUTF8StringEncoding]];
                    NSDictionary *recoverySuggestion = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingMutableLeaves error:nil];
                    if (recoverySuggestion) {
                        NSString *message = recoverySuggestion[@"Message"];
                        message = message ?: recoverySuggestion[@"msg"];
                        description = message;
                    }
                }
                failure((ETopBatchRequest *)batchRequest);
            }
        }];
}

3、同步請求

(1)同步請求適用于兩個接口直接存在依賴,第二個接口請求的參數(shù)必須從第一個接口請求成功后的結(jié)果而來,前面也提到過,我們請求的時候有自己的狀態(tài)碼邏輯處理,所以同理異步請求我們也需要做一層基于YTKChainRequest的封裝;同步請求不像異步請求,它的返回回調(diào)是兩個代理方法- (void)chainRequestFinished:(YTKChainRequest *)chainRequest(完成的代理方法),- (void)chainRequestFailed:(YTKChainRequest *)chainRequest failedBaseRequest:(YTKBaseRequest *)request (失敗的代理方法),所以我們在封裝的時候首頁要遵循代理,設(shè)置代理為自己以及請求成功和失敗的回調(diào),在請求成功后我們返回請求成功的block,失敗的時候判斷失敗的錯誤,并返回失敗的回調(diào)
a、初始化,遵循代理

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.delegate = self;
    }
    return self;
}

b、調(diào)用父類的同步請求方法,回調(diào)請求數(shù)據(jù)

- (void)addYTRequest:(ETopBaseRequest *)request callback:(nullable ETopChainCallback)callback{
    [super addRequest:request callback:^(YTKChainRequest * _Nonnull chainRequest, YTKBaseRequest * _Nonnull baseRequest) {
        if (callback) {
            callback((ETopChainRequest *)chainRequest,(ETopBaseRequest *)baseRequest);
        }
    }];
}

c、實現(xiàn)請求成功的代理方法,加上項目的狀態(tài)碼等邏輯判斷,并且回調(diào)請求成功的數(shù)據(jù)

- (void)chainRequestFinished:(YTKChainRequest *)chainRequest {

    for (YTKBaseRequest *request in chainRequest.requestArray) {
        id responseObjec = [request responseJSONObject];
        NSInteger statusCode = [responseObjec[@"StatsCode"] integerValue];
        statusCode = (statusCode == 0 ? [responseObjec[@"status"] integerValue] : statusCode);
        if (statusCode == SUCCEED_ChainRequest) {
            if (self.ChainRequestSuccessBlock) {
                self.ChainRequestSuccessBlock((ETopChainRequest *)chainRequest);
            }
        } else {
            if (statusCode == LoginFailCodeType) {
                // 清空用戶信息
                [LoginManager saveUserModel:nil];
            } else if (statusCode == AuthorizationFailedCodeType) {
                NSLog(@"重新獲取token");
                [[DDOAuthClient shareInstance] getTokenAndLoginWithSuccess:nil];
            }
            if (self.ChainRequestFailureBlock) {
                NSString *message = request.responseObject[@"Message"];
                message = message ?: request.responseObject[@"msg"];
                self.ChainRequestFailureBlock((ETopChainRequest *)chainRequest, message);
            }
        }
    }
}

b、實現(xiàn)請求失敗的代理,判斷是否是證書錯誤的邏輯判斷,并且返回失敗的數(shù)據(jù)和提示

- (void)chainRequestFailed:(YTKChainRequest *)chainRequest failedBaseRequest:(YTKBaseRequest *)request {
    // 失敗
    NSString *description = request.error.localizedDescription;
    description = [description stringByReplacingOccurrencesOfString:@"." withString:@""];
    description = [description stringByReplacingOccurrencesOfString:@"。" withString:@""];
    if (request.error.localizedRecoverySuggestion) { // 證書錯誤
        NSData *errorData = [[NSData alloc] initWithData:[request.error.localizedRecoverySuggestion dataUsingEncoding:NSUTF8StringEncoding]];
        NSDictionary *recoverySuggestion = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingMutableLeaves error:nil];
        if (recoverySuggestion) {
            NSString *message = recoverySuggestion[@"Message"];
            message = message ?: recoverySuggestion[@"msg"];
            description = message;
        }
    }
    self.ChainRequestFailureBlock((ETopChainRequest *)chainRequest, description);
}

(2)具體使用方法
請求數(shù)據(jù),(兩個接口直接一定具有依賴性,這里只是舉例,其實舉例的這兩個接口沒有啥依賴)


image.png

a、請求失敗的處理


image.png

b、請求成功,UI布局


image.png

4、YTK的文件流上傳功能

我們可以通過重寫constructingBodyBlock的方法,來實現(xiàn)上傳(例如我們上傳語音和圖片),我們項目中的UploadFileAPI接口有用到

- (AFConstructingBlock)constructingBodyBlock {
    return ^(id<AFMultipartFormData> formData) {
        for (UploadFileModel *model in _fileModelsArray) {
            [formData appendPartWithFileData:model.data name:model.fileName fileName:model.fileName mimeType:@""];
        }
    };
}

5、斷點續(xù)傳

要啟動斷點續(xù)傳功能,我們只需要覆蓋resumableDownloadPath方法,指定斷點續(xù)傳時文件的存儲路徑即可,文件會被自動保存到此路徑;(項目暫時沒有用到,這里現(xiàn)附上YTK的用例,假設(shè)我們需要從服務(wù)器下載一張圖片到本地)

- (NSString *)resumableDownloadPath {
    NSString *libPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *cachePath = [libPath stringByAppendingPathComponent:@"Caches"];
    NSString *filePath = [cachePath stringByAppendingPathComponent:_imageId];
    return filePath;
}

總結(jié)

YTK隔離出了業(yè)務(wù)邏輯層,一些小的方法比較省代碼,會提高效率

最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

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