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