5

我有多個視圖,它們可以製作相同的NSURLRequest/NSURLConnection request。理想情況下,爲了獲得一些代碼重用,我想有一些「代理」,它負責創建/執行(異步)請求/連接,設置所有委託方法等所有基礎工作。 ,所以我不必在每個視圖中複製所有這些NSURLConnection委託方法處理程序。首先,這種設計方法是否合理?其次,我會如何去做這樣的事情?NSURLConnection用於異步Web服務調用的NSURLRequest代理

對於一個小的背景信息,我試圖得到它「工作」,但是,它似乎不是異步執行。我創建具有用於不同的web服務調用的實例方法(和也含有NSURLConnection委託方法)一個Proxy.h /米文件:

@interface Proxy : NSObject { 

    NSMutableData *responseData; 
    id<WSResponseProtocol> delegate; 
} 

- (void)searchForSomethingAsync:(NSString *)searchString delegate:(id<WSResponseProtocol>)delegateObj; 

@property (nonatomic, retain) NSMutableData *responseData; 
@property (assign) id<WSResponseProtocol> delegate; 

@end 

的WSResponseProtocol被定義爲這樣:

@protocol WSResponseProtocol <NSObject> 

@optional 
- (void)responseData:(NSData *)data; 
- (void)didFailWithError:(NSError *)error; 

@end 

爲了使用它,視圖控制器只需要符合WSResponseProtocol協議就可以捕獲響應。使Web服務調用如下所示:

Proxy *p = [[Proxy alloc] init]; 
[p searchForSomethingAsync:searchText delegate:self]; 
[p release]; 

我可以提供更多的代碼,但其餘的可以假設。在打電話之前,我「開始動畫」一個UIActivityIndicatorView微調器。但是這個微調者永遠不會旋轉。如果我直接將NSURLConnection委託方法直接放在視圖控制器中,那麼微調器就會旋轉。所以,這讓我認爲我的實現不是異步執行的。這裏有什麼想法/想法?

回答

22

你的方法是合理的,但是,我不確定你爲什麼要創建自己的協議。這不是必需的。爲了實現這一目標,您需要的一切都在Apple的documentation on NSURLConnection中。如果從NSURLConnection實例化的頁面獲取代碼,並將連接設置爲ivar,而不是將其創建爲局部變量,則可以比較每個回調方法中的連接對象並作出相應的響應。例如,採取從文檔此代碼並改變連接對象的實例變量:

// create the request 
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"] 
         cachePolicy:NSURLRequestUseProtocolCachePolicy 
        timeoutInterval:60.0]; 
// create the connection with the request 
// and start loading the data 
theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 
if (theConnection) { 
    // Create the NSMutableData that will hold 
    // the received data 
    // receivedData is declared as a method instance elsewhere 
    receivedData=[[NSMutableData data] retain]; 
} else { 
    // inform the user that the download could not be made 
} 

可變theConnection是我們的ivar。然後,你可以檢查它像這樣:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    if (connection == theConnection) 
    { 
     // do something with the data object. 
     [connectionSpecificDataObject appendData:data]; 
    } 
} 

你當然可以實現它創建自己的協議,你是在暗示然後再打出去符合您的協議委託,但你可能會更好只使用可以檢查的成功和失敗選擇器來實例化對象。事情是這樣的:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    if (connection == theConnection) 
    { 
     if (delegate && [delegate respondsToSelector:successSelector]) 
      [delegate performSelector:successSelector 
          withObject:connectionSpecificDataObject]; 
    } 
    [connection release]; 
} 

哪裏dataDidDownloadSelector是您在創建所有這些代碼都包含在您下載的委託設置一個SEL實例變量 - 你的代理對象。事情是這樣的:

Proxy *p = [[Proxy alloc] init]; 
[p searchForSomethingAsync:searchText 
        delegate:self 
      successSelector:@selector(didFinishWithData:) 
       failSelector:@selector(didFailWithError:)]; 

實現你的選擇是這樣的:

- (void)didFinishWithData:(NSData*)data; 
{ 
    // Do something with data 
} 

- (void)didFailWithError:(NSError*)error 
{ 
    // Do something with error 
} 

這已成爲一個較長的答案比我預期的。讓我知道,如果它沒有意義,我可以嘗試澄清。

最好的問候,

+0

啊 - 非常好!我明白你的意思 - 你的解決方案將消除對協議的需求。更直截了當!感謝那!我認爲,儘管我開始熱衷於Kendal提出的解決方案,也就是說,將同步的NSURLConnections包裝在NSOperation中並引發隊列。該解決方案可能是創建異步Web服務調用框架問題的更直接的解決方案,儘管我的方法+您的洞察力仍然可行。 – tbehunin 2009-12-29 18:10:33

+0

恢復我的評論早些時候。這種方法是我在NSOperation中使用vs同步NSURLConnections的方法。 NSURLConnection已經提供了我所需要的線程,而不需要把它放到NSOperation中。另外,閱讀更多博客之後,同步NSURLConnections +身份驗證不會提供與異步調用一樣多的「鉤子」。 – tbehunin 2010-01-01 17:23:12

+0

何處\如何receivedData數據聲明。該文件只是說它在其他地方聲明,但沒有提供如何做到這一點的信息。 – 2012-10-03 17:17:09

1

你按原樣碼,我想會做什麼 - 你放開代理初始化剛過,所以它甚至從來沒有運行。

我喜歡使用的方法是同步NSURLConnection調用,在NSOperation內部,NSOperation由NSOperationQueue管理。我讓隊列生存在一個Singleton中,所以我只需從任何地方訪問實例,並在需要啓動新連接時告訴它。

+0

好!我從來沒有想過在NSOperation中包裝同步NSURLConnection調用的方法。我認爲這將是我正在尋找的解決方案。但是,使用此解決方案,您需要一種方法來檢索信息。這裏是另一個鏈接到這個問題的答案:http://stackoverflow.com/questions/1297733/cocoa-return-information-from-nsoperation – tbehunin 2009-12-29 18:39:22

+0

爲了傳遞結果我通常將數據結果存儲在某個地方通過一個單身人士,和/或將對象傳回給包裝在通知中的任何感興趣的人(您可以在通知userInfo字典中包裝任何對象)。 – 2009-12-29 23:26:32