2012-04-28 10 views
0

iOSアプリケーションでネットワークコールを行うためにASIHTTPRequestフレームワークを使用しています。しかし、私はアプリケーションのすべてのコントローラーで直接使用したくありません。だから私はASIHTTPRequestの周りにレイヤーを書くことを考えました。私のコードはASIHTTPRequestを使うためにこの層を使います。将来、このフレームワークを他のフレームワークに置き換えることができ、コードが変更されるだけで、レイヤーが変更されるはずです。私はそれをするための戦略が何であるべきかを知りたい。クラスをASIHTTPRequestクラスから継承するか、独自のクラスを実装する必要があります。私は実装を検討すべき方法は何でしょうか。ASIHTTPRequestのラッパー

現在、私はこれをこのように実装しています。 私のラッパーは

MyRequestHandler.h : NSObject  
@property ASIHTTPRequest *asiHttpReq;  

-(void) sendAsyncGetRequest 
{ 
    self.asiRequest = [ASIHTTPRequest requestWithURL:self.url]; 
    if(self.tag != 0){ 
     self.asiRequest.tag = self.tag; 
    } 
    [self.asiRequest setDelegate:self]; 
    [self.asiRequest startAsynchronous];   
} 

- (void)requestFinished:(ASIHTTPRequest *)request{ 
    MyResponseObj *respone = <From request obj> 
    if([delegate respondsToSelector:@selector(requestFinished:)]){ 
      [delegate performSelector:@selector(requestFinished:) withObject:response]; 
     } 
} 

であると私のViewControllerに私はこれを行うだろう:

MyViewController.h : UIViewContoller 
@property MyRequestHandler *reqHandler; 

-(void) fireRequest 
{ 
NSString* requestUrl = <create URL>; 
if(requestUrl){ 

    // [self showLoadingIndicatorView]; 

    // Proceed for request. 
    NSURL *url = [NSURL URLWithString:requestUrl]; 
    reqHandler = [MyRequestHandler requestWithURL:url]; 
    reqHandler.tag = 1000; 
    [reqHandler setDelegate:self]; 
    [reqHandler sendAsyncGetRequest]; 
} 
} 

- (void)requestFinished:(MyResponse*) responseData{ 
     // Do Your parsing n all here. 
} 

- (void)requestFailed:(MyResponse*) responseData{ 
     // Handle the error here. 
} 

が、これはそれを行うための正しい方法です。ここでの問題は、私がviewcontrollerでmyrequesthandlerのプロパティを作成したときに、一度に1つのリクエストしか作成できず、同時に複数のリクエストを行うASIHTTPRequestの機能を失うことです。

このような問題にアプローチする方法を教えてください。

答えて

2

これは私が使用しているものです:

#import "ASIFormDataRequest.h" 

@interface RequestPerformer : NSObject { 
    id localCopy; // to avoid exec_bad_access with arc 
    ASIHTTPRequest *getRequest; 
    ASIFormDataRequest *postRequest; 
} 

@property (nonatomic, retain) id delegate; 
@property (nonatomic, readwrite) SEL callback; 
@property (nonatomic, readwrite) SEL errorCallback; 

- (void)performGetRequestWithString:(NSString *)string stringDictionary:(NSDictionary *)stringDictionary delegate:(id)requestDelegate requestSelector:(SEL)requestSelector errorSelector:(SEL)errorSelector; 
- (void)performPostRequestWithString:(NSString *)string stringDictionary:(NSDictionary *)stringDictionary dataDictionary:(NSDictionary *)dataDictionary delegate:(id)requestDelegate requestSelector:(SEL)requestSelector errorSelector:(SEL)errorSelector; 

@end 

//

#import "RequestPerformer.h" 
#import "ASIHTTPRequest.h" 
#import "ASIFormDataRequest.h" 

@implementation RequestPerformer 

@synthesize delegate; 
@synthesize callback, errorCallback; 

- (void)performGetRequestWithString:(NSString *)string stringDictionary:(NSDictionary *)stringDictionary delegate:(id)requestDelegate requestSelector:(SEL)requestSelector errorSelector:(SEL)errorSelector { 

    localCopy = self; 

    self.delegate = requestDelegate; 
    self.callback = requestSelector; 
    self.errorCallback = errorSelector; 

    NSMutableString *requestStringData = [[NSMutableString alloc] init]; 
    if (stringDictionary) 
     for (NSString *key in [stringDictionary allKeys]) 
      [requestStringData appendFormat:@"%@=%@&", key, [stringDictionary objectForKey:key]]; 
    NSString *resultString = [requestStringData substringToIndex:[requestStringData length]-1]; 

    getRequest = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", string, [resultString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]]; 
    [getRequest setDelegate:self]; 
    [getRequest setRequestMethod:@"GET"]; 

    //NSLog(@"request url = %@", [getRequest.url absoluteString]); 
    [getRequest startAsynchronous]; 
} 

- (void)performPostRequestWithString:(NSString *)string stringDictionary:(NSDictionary *)stringDictionary dataDictionary:(NSDictionary *)dataDictionary delegate:(id)requestDelegate requestSelector:(SEL)requestSelector errorSelector:(SEL)errorSelector { 

    localCopy = self; 

    self.delegate = requestDelegate; 
    self.callback = requestSelector; 
    self.errorCallback = errorSelector; 

    NSURL *url = [NSURL URLWithString:string]; 

    postRequest = [[ASIFormDataRequest alloc] initWithURL:url]; 
    [postRequest setDelegate:self]; 
    [postRequest setRequestMethod:@"POST"]; 

    if (stringDictionary) 
     for (NSString *key in [stringDictionary allKeys]) 
      [postRequest setPostValue:[stringDictionary objectForKey:key] forKey:key]; 

    if (dataDictionary) 
     for (NSString *key in [dataDictionary allKeys]) 
      [postRequest setData:[dataDictionary objectForKey:key] forKey:key]; 

    //NSLog(@"request url = %@", [postRequest.url absoluteString]); 
    [postRequest startAsynchronous]; 
} 

#pragma mark - ASIHTTPRequest Delegate Implementation 

- (void)requestFinished:(ASIHTTPRequest *)crequest { 
    NSString *status = [crequest responseString]; 

    if (self.delegate && self.callback) { 
     if([self.delegate respondsToSelector:self.callback]) 
      [self.delegate performSelectorOnMainThread:self.callback withObject:status waitUntilDone:YES]; 
     else 
      NSLog(@"No response from delegate"); 
    } 
    localCopy = nil; 
} 
- (void)requestFailed:(ASIHTTPRequest *)crequest { 
    if (self.delegate && self.errorCallback) { 
     if([self.delegate respondsToSelector:self.errorCallback]) 
      [self.delegate performSelectorOnMainThread:self.errorCallback withObject:crequest.error waitUntilDone:YES]; 
     else 
      NSLog(@"No response from delegate"); 
    } 
    localCopy = nil; 
} 

@end 

を、それを使用するには、ちょうどあなたのUIViewControllerRequestPerformer.hをインポートし、同様になめらかん:

[requestManager performGetRequestWithString:tempString stringDictionary:stringDictionary dataDictionary:dataDictionary delegate:self requestSelector:@selector(requestSucceeded:) errorSelector:@selector(requestFailed:)]; 

パラメータ:

  • (NSString *)string - あなたのリクエストを投稿するURL文字列。
  • (NSDictionary *)stringDictionary - すべての テキスト情報(名前、IDなど)を含む辞書。
  • (NSDictionary *)dataDictionary - すべてのデータ情報(写真、ファイルなど)を含む辞書。
  • (id)requestDelegate - 以下のセレクタを実行する代理人。
  • (SEL)requestSelector - 正常に要求されている間に実行されるセレクタ。
  • (SEL)errorSelector - エラーが発生している間に実行されるセレクタ。
+0

こんにちは、あなたが提供した解決策、多かれ少なかれ私が使っている解決策。私はちょうどここにそれのビットを与えた。ラッパーでは、getRequestは関数のローカル変数ではなくクラスのプロパティであるため、一度に1つのリクエストしか作成できません。最初のリクエストのレスポンスの前に2番目のリクエストを作成しようとすると、getRequestオブジェクトは2番目のリクエストに置き換えられ、最初のリクエストのレスポンスは返されません。 ASIHTTPRequestがNSOperationから派生し、各要求がNSOperationキューで実行される場合、複数の要求を同時に起動できます。 –

+0

ASIHTTPRequestでは、NSOperationQueueに追加されるローカル変数を作成することで、このような複数のリクエストを発生させることができ、応答が返るまで生き続けることができます。 ASIHTTPRequest * req = [ASIHTTPRequest requestWithURL:url]; req.tag = MemberPrescriptionRequestTypeDrug; [req setDelegate:self]; [req startAsynchronous]; –

+1

このラッパーは、1回の要求だけを実行することを目的としています。より多くを同時に実行する必要がある場合は、他の辞書やコールバックセレクタ(論理的なもの)を使用して 'RequestPerformer'の別のインスタンスを作成し、このインスタンスからリクエストを実行する必要があります。 – demon9733

0

上記の回答(demon9733)では、retainを使用してラッパークラスが作成されました。一般に、デリゲートプロパティは、保持サイクルを削除するために割り当てられる必要があります。