iOSネットワーク要求モジュールパッケージ-OC
10307 ワード
SwiftのAlamofireを長く使ってから、OCのアイテムを振り返って書く-request:success:failure:このような形式のネットワークリクエストはあまり慣れていません......そこでAFNetworking 3に基づいてパッケージ化しました.1フレームAlamofireスタイルのネットワークリクエストモジュール
コードgithubアドレス:ARKHTTPModule
きほんきのう要求の作成 取得要求のステータスプロセス 要求動作 応答 これらの基本機能のクラスはARKRequestです
1、要求の作成
要求アドレス、要求パラメータなどからネットワーク要求インスタンスを作成する
2、取得要求のステータスプロセス
リクエストの進行状況、実行中、一時停止中、キャンセル中、バックグラウンドリクエスト完了ステータスは、次の方法で取得できます.
3、要求された操作
リクエストの開始、一時停止、キャンセルなどの操作を行う
4、応答
ここではAlamofireのリクエスト完了コールバック形式ARKRequestクラスにNSOperationQueueシリアルキューがあります.このキューは、作成時に一時停止状態にあるユーザーがResponseを使用してコードを追加したときに、このキューにBlockコードを入れます.応答がある場合、キュー内のBlockを順次実行します.
リクエスト例
仮にJSONデータを要求
補助クラス
他にも2つの補助クラスがあります. ARKRequestCacheManager ARKNonRepetitiveRequestManager
ARKRequestCacheManager重複しない要求を開始するためのキャッシュ要求ARKNonRepetiveRequestManager
1、ARKRequestCacheManager(単例)
ARKRequestCacheManagerを使用してネットワークリクエストを開始すると、managerはリクエストインスタンスをキャッシュします.リクエストが完了すると、managerは対応するリクエストインスタンスを削除します.このアシストクラスを使用して、リクエストの一時停止とキャンセルを簡単に実現できます.
ARKRequestCacheManagerを使用して開始されたダウンロード要求の場合、managerはerrorからダウンロードに失敗します.userInfo辞書では、NSURLSessionDownloadTaskResumeDataを取り出し、URLをキーとしてNSCacheにキャッシュし、ディスクCacheディレクトリの下に保存します.
次回ダウンロードリクエストを開始すると、URLによりローカルにブレークポイントデータがあるか否かが判断されますブレークポイントデータがある場合、-downloadWithType:resumeData:destination:ブレークポイント継続 が呼び出されます.ブレークポイントデータがない場合は、ダウンロード要求 を再作成する.
ARKRequestCacheManagerを使用してネットワークリクエストを開始
2、ARKNonRepetitiveRequestManager(単例)
ARKNonRepetitiveRequestManagerも同様にARKRequestCacheManageの機能を持ち、ARKNonRepetiveRequestManagerを使用して複数の同じリクエストを開始する場合、最初に開始したリクエストのみが有効になり、残りのリクエストは無視されます.
ARKNonRepetitiveRequestManagerを使用してネットワークリクエストを開始
その他
現在OCのフレームワークにおけるネットワーク層は依然として-request:success:failure:の呼び出し形式(結局成熟しており、呼び出し形式がより普及している==)というネットワークモジュールのパッケージは一時的に興っており、セキュリティメカニズムの問題など、考慮されていない問題が多く、要するに完璧である必要がある.
皆さんのご提案を歓迎します
コードgithubアドレス:ARKHTTPModule
きほんきのう
1、要求の作成
要求アドレス、要求パラメータなどからネットワーク要求インスタンスを作成する
// HTTP , GET , 15
+ (instancetype)requestWithURLString:(NSString *)URLStr
parameters:(nullable NSDictionary *)params;
+ (instancetype)requestWithMethod:(ARKRequestMethod)method
serializer:(ARKRequestSerializerType)serializer
URLString:(NSString *)URLStr
parameters:(nullable NSDictionary *)params
requestTimeout:(NSTimeInterval)timeout;
//
+ (instancetype)uploadWithType:(ARKSessionType)type
URLString:(NSString *)URLStr
parameters:(nullable NSDictionary *)params
fromData:(nullable NSData *)bodyData;
//
+ (instancetype)downloadWithType:(ARKSessionType)type
URLString:(NSString *)URLStr
parameters:(nullable NSDictionary *)params
destination:(nonnull DownloadDidFinishTargetBlock)destination;
// etc...
2、取得要求のステータスプロセス
リクエストの進行状況、実行中、一時停止中、キャンセル中、バックグラウンドリクエスト完了ステータスは、次の方法で取得できます.
//
- (ARKRequest *(^)(_Nullable ProgressBlock))requestProgressBlock;
//
- (ARKRequest *(^)(_Nullable RequestStateBlock))requestWillResume;
//
- (ARKRequest *(^)(_Nullable RequestStateBlock))requestWillSuspend;
//
- (ARKRequest *(^)(_Nullable RequestStateBlock))requestWillCancel;
//
- (ARKRequest *(^)(_Nullable SessionDidFinishEventsForBackgroundURLSessionBlock))didFinishEventsForBackgroundURLSession;
3、要求された操作
リクエストの開始、一時停止、キャンセルなどの操作を行う
//
- (ARKRequest *(^)(void))resume;
//
- (ARKRequest *(^)(void))suspend;
//
- (ARKRequest *(^)(void))cancel;
4、応答
ここではAlamofireのリクエスト完了コールバック形式ARKRequestクラスにNSOperationQueueシリアルキューがあります.このキューは、作成時に一時停止状態にあるユーザーがResponseを使用してコードを追加したときに、このキューにBlockコードを入れます.応答がある場合、キュー内のBlockを順次実行します.
// NSData
- (ARKRequest *(^)(ResponseDataBlock))responseDataOnMainThread;
// NSString
- (ARKRequest *(^)(ResponseStringBlock))responseStringOnMainThread;
// JSON(NSArray NSDictionary)
- (ARKRequest *(^)(ResponseJSONBlock))responseJSONOnMainThread;
// JSON ( JSON )
// < ARKMappableObject >
// JSON , Class
- (ARKRequest *(^)(ResponseMappableObjectBlock, Class))responseMappableObjectOnMainThread;
// JSON ( JSON )
// , JSON ,
- (ARKRequest *(^)(ResponseMappableObjectArrayBlock, Class))responseMappableObjectArrayOnMainThread;
//
@protocol ARKMappableObject
+ (nullable id)objectWithResponseObject:(id)object;
@end
@protocol ARKMappableObjectArray
+ (nullable NSArray> *)arrayWithResponseObject:(id)object;
@end
リクエスト例
仮にJSONデータを要求
- (IBAction)startRequest:(UIButton *)sender {
//
ARKRequest *request = [ARKRequest requestWithURLString:@"http://www.example.com/json" parameters:nil];
// self request, block self , block
// , ( ViewController)
// , , block weak self
request.requestWillResume(^(ARKRequest *request) {
// ,
[self showLoadingView];
}).requestProgressBlock(^(NSProgress *progress) {
// ,requestProgressBlock
dispatch_async(dispatch_get_main_queue(), ^{
self.progressView.progress = (float)progress.completedUnitCount / (float)progress.totalUnitCount;
});
}).responseJSONOnMainThread(^(NSURLSessionTask *task, id json, NSError *error) {
//
[self hideLoadingView];
NSLog(@" , thread: %@", [NSThread currentThread]);
if (error == nil) {
//
[self requestSuccessWithJSON:json];
} else {
//
[self requestFailureWithError:error];
}
}).resume();
}
補助クラス
他にも2つの補助クラスがあります.
ARKRequestCacheManager重複しない要求を開始するためのキャッシュ要求ARKNonRepetiveRequestManager
1、ARKRequestCacheManager(単例)
ARKRequestCacheManagerを使用してネットワークリクエストを開始すると、managerはリクエストインスタンスをキャッシュします.リクエストが完了すると、managerは対応するリクエストインスタンスを削除します.このアシストクラスを使用して、リクエストの一時停止とキャンセルを簡単に実現できます.
ARKRequestCacheManagerを使用して開始されたダウンロード要求の場合、managerはerrorからダウンロードに失敗します.userInfo辞書では、NSURLSessionDownloadTaskResumeDataを取り出し、URLをキーとしてNSCacheにキャッシュし、ディスクCacheディレクトリの下に保存します.
次回ダウンロードリクエストを開始すると、URLによりローカルにブレークポイントデータがあるか否かが判断されます
ARKRequestCacheManagerを使用してネットワークリクエストを開始
- (void)startDownload {
// ARKRequestCacheManager
// ARKRequestCacheManager ,
// , ,
ARKRequestCacheManager *manager = [ARKRequestCacheManager sharedManager];
ARKRequest *request = [manager downloadWithType:ARKSessionTypeDefault
URLString:kURLString
parameters:nil
destination:^NSURL * _Nonnull(NSURL * _Nonnull location, NSURLResponse * _Nonnull response) {
//
NSString *documentDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *path = [documentDir stringByAppendingPathComponent:@"image.jpg"];
// TODO: = =
// fileURL, response
return [NSURL fileURLWithPath:path];
}];
__weak typeof(&*self) weakSelf = self;
request.requestWillResume(^(ARKRequest *request) {
//
[weakSelf showLoadingView];
}).requestWillSuspend(^(ARKRequest *request) {
NSLog(@" ,state: %ld", request.task.state);
}).requestProgressBlock(^(NSProgress *progress) {
//
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.progressView.progress = (float)progress.completedUnitCount / (float)progress.totalUnitCount;
});
}).responseDataOnMainThread(^(NSURLSessionTask *task, NSData *data, NSError *error) {
//
[weakSelf hideLoadingView];
NSLog(@" , thread: %@", [NSThread currentThread]);
if (error != nil) {
[weakSelf showErrorMessage:[NSString stringWithFormat:@" , error:%@", error.localizedDescription]];
return ;
}
if (data == nil || [data isKindOfClass:[NSNull class]]) {
[weakSelf showErrorMessage:[NSString stringWithFormat:@" "]];
return ;
}
weakSelf.imageView.image = [UIImage imageWithData:data];
}).resume();
}
//
- (IBAction)suspendDownload {
// ARKRequestCacheManager
ARKRequest *request = [[ARKRequestCacheManager sharedManager] requestCacheWithURLString:kURLString];
if (request != nil) {
request.suspend();
[self hideLoadingView];
}
}
//
- (IBAction)resumeDownload {
// ARKRequestCacheManager
ARKRequest *request = [[ARKRequestCacheManager sharedManager] requestCacheWithURLString:kURLString];
if (request != nil && (request.state == NSURLSessionTaskStateSuspended)) {
//
request.resume()
[self showLoadingView];
} else {
//
[self startDownload];
}
}
2、ARKNonRepetitiveRequestManager(単例)
ARKNonRepetitiveRequestManagerも同様にARKRequestCacheManageの機能を持ち、ARKNonRepetiveRequestManagerを使用して複数の同じリクエストを開始する場合、最初に開始したリクエストのみが有効になり、残りのリクエストは無視されます.
ARKNonRepetitiveRequestManagerを使用してネットワークリクエストを開始
- (IBAction)backgroundDownload:(UIButton *)sender {
ARKNonRepetitiveRequestManager *manager = [ARKNonRepetitiveRequestManager sharedManager];
// ,
ARKRequest *request = [manager downloadWithType:ARKSessionTypeBackground //
URLString:kImageURLString
parameters:nil
destination:^NSURL * _Nonnull(NSURL * _Nonnull location, NSURLResponse * _Nonnull response) {
NSString *documentDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *path = [documentDir stringByAppendingPathComponent:@"BackgrounDownloadImage.jpg"];
return [NSURL fileURLWithPath:path];
}];
__weak typeof(&*self) weakSelf = self;
request.responseDataOnMainThread(^(NSURLSessionTask *task, NSData *data, NSError *error) {
NSLog(@" , thread: %@", [NSThread currentThread]);
if (data.length > 0) {
weakSelf.imageView.image = [UIImage imageWithData:data];
}
}).didFinishEventsForBackgroundURLSession(^(NSURLSession *session) {
NSLog(@" ");
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
void(^completionHandler)() = delegate.didFinishEventsForBackgroundURLSession;
delegate.didFinishEventsForBackgroundURLSession = nil;
// ,
completionHandler();
}).resume();
}
その他
現在OCのフレームワークにおけるネットワーク層は依然として-request:success:failure:の呼び出し形式(結局成熟しており、呼び出し形式がより普及している==)というネットワークモジュールのパッケージは一時的に興っており、セキュリティメカニズムの問題など、考慮されていない問題が多く、要するに完璧である必要がある.
皆さんのご提案を歓迎します