5

동일하게 만드는 여러보기가 있습니다 NSURLRequest/NSURLConnection request. 이상적으로, 일부 코드를 재사용하려면 (비동기식) 요청/연결을 생성/실행하고 모든 대리자 메서드를 설정하는 등 모든 기본 작업을 수행하는 "프록시"를 사용하고 싶습니다. 따라서 각 뷰에 모든 NSURLConnection 대리자 메서드 처리기를 복사 할 필요가 없습니다. 우선,이 설계 방식이 합리적입니까? 둘째, 그런 일을 어떻게하면 할 수 있을까요?NSURLConnection 비동기 웹 서비스 호출 용 NSURLRequest 프록시

약간의 배경 정보 때문에이 작업을 시도하여 "작동"시키지만 비동기 적으로 실행되지는 않습니다.

@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 

I합니다 (NSURLConnection 위임 방법도 포함) 다른 웹 서비스 호출에 대한 인스턴스 메서드가있는 Proxy.h/m 파일을 생성 이를 사용하기 위해서는 View Controller가 응답을 잡기 위해 WSResponseProtocol 프로토콜을 준수하기 만하면됩니다. 웹 서비스 호출은 다음과 같이 수행됩니다.

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

우리 아이바이다. 그럼 당신은 이런 식으로 그것을 확인할 수 있습니다

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

당신은 확실히 당신이 제시 한 다음 프로토콜을 준수 위임 밖으로 다시 전화하고 그것을 자신의 프로토콜을 만들어 구현할 수 있지만, 당신은 더 나은 방금 될 수있다 확인할 수있는 성공 및 실패 선택기를 사용하여 개체를 인스턴스화합니다. 이런 식으로 뭔가 : dataDidDownloadSelector는이 모든 코드가 포함되어 다운로드 대리자를 만들 때 설정 SEL 인스턴스 변수입니다

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

- 프록시 개체를. 이런 식으로 뭔가 :

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

아 - 아주 좋습니다! 나는 당신이 말하는 것을 보았습니다 - 당신의 해결책은 프로토콜의 필요성을 제거 할 것입니다. 훨씬 더 똑바로! 고마워! 그러나 나는 켄들이 제안한 해결책 인 NSORLConnections를 NSOperation에 랩핑하고 대기열에 던져 놓는 것이 좋습니다. 이 솔루션은 비동기식 웹 서비스 호출 프레임 워크를 만드는 문제에 대한보다 직접적인 해결책 일 수 있지만 내 접근 + 통찰력은 여전히 ​​실행 가능합니다. – tbehunin

+0

내 의견을 일찍 되돌립니다. 이 접근법은 NSOperation 내에서 NSURLConnections와 동기화하는 방식입니다. NSURLConnection은 이미 NSOperation에 넣지 않고 필요한 스레딩을 제공합니다. 또한 더 많은 블로그를 읽은 후 동기식 NSURLConnections + 인증은 비동기 호출만큼 많은 "후크"를 제공하지 않습니다. – tbehunin

+0

여기서 \ how는 receiveData가 선언되었습니다. 문서는 다른 곳에서 선언되었다고 말하고 있지만 어떻게해야하는지에 대한 정보는 제공하지 않습니다. –

1

코드는, 나는 아무것도 할 것이라고 생각합니다.

내가 사용하고자하는 접근 방식은 NSOperationQueue에 의해 차례대로 관리되는 NSOperation 내부에서 동기 NSURLConnection 호출입니다. 큐 객체가 Singleton에 존재하도록 만들었으므로 어디서나 인스턴스에 액세스하여 새 연결이 필요할 때 알려줍니다.

+0

Nice! NSOperation에서 래핑 된 동기 NSURLConnection 호출의 접근 방식에 대해서는 생각해 본 적이 없습니다. 나는 이것이 내가 찾고있는 해결책이라고 생각한다. 그러나이 솔루션을 사용하면 정보를 검색 할 수있는 방법이 필요합니다. 다음은이 문제에 대한 또 다른 SO 응답에 대한 링크입니다. http://stackoverflow.com/questions/1297733/cocoa-return-information-from-nsoperation – tbehunin

+0

결과를 전달하기 위해 나는 보통 싱글 톤을 통해 중앙에 어딘가에 데이터 결과를 저장하고,/또는 통지에 래핑 된 모든 사용자에게 객체를 전달합니다 (통지 userInfo 사전에 객체를 래핑 할 수 있음). –