2012-04-28 90 views
0

我使用ASIHTTPRequest框架在我的iOS應用程序中進行網絡調用。但我不想直接在我的應用程序中的所有控制器中使用它。所以我想到圍繞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的屬性,我一次只能創建一個請求,並且失去了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 

要使用它,只需要導入RequestPerformer.hUIViewController,做水木清華這樣的:

[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是類的屬性,而不是函數的局部變量。如果您嘗試在第一個請求的getRequest對象的響應將被第二個請求的響應替換之前發出第二個請求,並且您永遠不會獲得第一個請求的響應。 ASIHTTPRequest從NSOperation派生並且每個請求都在NSOperation隊列中運行,您可以同時觸發多個請求。 – 2012-04-30 05:12:49

+0

在ASIHTTPRequest中,您可以通過創建一個局部變量來觸發多個請求,並將其添加到NSOperationQueue中,從而保持活動狀態直到響應恢復。 ASIHTTPRequest * req = [ASIHTTPRequest requestWithURL:url]; req.tag = MemberPrescriptionRequestTypeDrug; [req setDelegate:self]; [req startAsynchronous]; – 2012-04-30 05:32:42

+1

這個包裝旨在執行一個請求。如果您需要同時執行更多操作,則應該使用其他字典和回調選擇器(它是邏輯的)創建另一個「RequestPerformer」實例,並執行來自此實例的請求。 – demon9733 2012-04-30 06:55:22

0

在上面的答案(demon9733)中,包裝類已經使用retain創建了delegate屬性。一般來說,應該分配委託屬性來刪除保留週期。