2010-02-12 2 views
4

비슷한 stackoverflow 질문/답변을 검토했지만 여전히 난처한 있습니다.iPhone NSURLConnection : connectionDidFinishLoading - 호출하는 메서드에 문자열을 반환하는 방법

저는 초보자이며이 문제로 정말 고심하고 있습니다. iPhone에서는 URL에서 XML을 다운로드 할 수 있지만 NSString 변수에 결과 문자열을 저장할 수없고 호출 함수에서 결과 문자열을 볼 수 없습니다.

내가 가지고 사용자 정의 만든 클래스에서 다음과 같은 선언 :

@interface comms : NSObject { 
    NSString *currURL, *receivedString; 
    NSMutableData *receivedData; 
    NSURLConnection *conn; 
} 

@property (copy, readwrite) NSString *currURL; 
@property (copy, readonly) NSString *receivedString; 
@property (nonatomic, assign) NSMutableData *receivedData; 
@property (nonatomic, assign) NSURLConnection *conn; 

-(void) getContentURL; 

내가 가지고있는 COMMS 클래스에서 다음과 같은 방법

-(void) getContentURL 
{ 
    NSLog(@"Begin getContentURL."); 

    // Request data related. 
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] 
            autorelease]; 
    [request setURL:[NSURL URLWithString: currURL]]; 

    // Content-Type related. 
    [request setValue:@"application/x-www-form-urlencoded" 
    forHTTPHeaderField:@"Content-Type"]; 

    // Create Connection. 
    conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

    if (conn) { 
     // The connection was established. 
     receivedData = [[NSMutableData data] retain]; 
     NSLog(@"Data will be received from URL: %@", request.URL); 
    } 
    else 
    { 
     // The download could not be made. 
     NSLog(@"Data could not be received from: %@", request.URL); 
    } 

    // PROBLEM - receivedString is NULL here. 
    NSLog(@"From getContentURL: %@", receivedString); 
} 

나는 COMMS 클래스에서 필요한 대의원 등을 만들었습니다 다음에 따라 :

-(void)connection:(NSURLConnection *)connection didReceiveResponse: 
    (NSURLResponse *)response 
{ 
    // Discard all previously received data. 
    [receivedData setLength:0]; 
} 

-(void)connection:(NSURLConnection *)connection didReceiveData: 
(NSData *)data 
{ 
    // Append the new data to the receivedData. 
[receivedData appendData:data];  
} 

-(void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    // Connection succeeded in downloading the request. 
    NSLog(@"Succeeded! Received %d bytes of data", [receivedData length]); 

    // Convert received data into string. 
    receivedString = [[NSString alloc] initWithData:receivedData 
     encoding:NSASCIIStringEncoding]; 
    NSLog(@"From connectionDidFinishLoading: %@", receivedString); 

    // release the connection, and the data object 
    [conn release]; 
    [receivedData release]; 
} 

성공적으로 receivedString str을 출력 할 수 있습니다. connectionDidFinishLoading 델리게이트에서 NSLog를 사용하면됩니다.

// Convert received data into string. 
    receivedString = [[NSString alloc] initWithData:receivedData 
     encoding:NSASCIIStringEncoding]; 
    NSLog(@"From connectionDidFinishLoading: %@", receivedString); 

그러나, I 출력은 널 년대 getContentURL에 receivedString 문자열 (따라서 또한 I는 발 COMMS 클래스 호출 ViewController.m 클래스 널 때).

// PROBLEM - receivedString is NULL here. 
    NSLog(@"From getContentURL: %@", receivedString); 

getContentURL 및 ViewController.m 클래스의 receivedString 값을 어떻게 볼 수 있습니까?

답변

4

NSURLConnection은 비동기 API입니다. 요청을 시작하면 개체가 새 스레드를 생성하고 콜백/대리자 메서드를 통해 주 스레드 만 업데이트합니다. 요청이 완료되기 전에 현재 메소드가 가장 많이 반환되므로 결과 문자열은 아직 다운로드되지 않습니다!

  1. 이 (가) 동기 다운로드 방법에 내장 된 사용 : 동 기적으로이 작업을 수행하려면

    , 당신은 두 가지 옵션이 있습니다. 이 부분이 차단되면 사용자가 UI와 상호 작용할 수 없습니다.

  2. C 함수 CFRunLoopRun() 및 CFRunLoopStop()을 사용하여 호출 함수 내에서 실행 루프를 시작하고 다운로드가 완료되거나 실패 할 때까지 기다린 다음 CFRunLoopStop()을 사용하여 호출하는 메서드로 제어를 되돌립니다.
+0

감사합니다. chpwn, 훌륭합니다! 지금은 '동기식 다운로드'방법을 구현했습니다. 아직 작성중인 프로토 타입이기 때문입니다. 다음 주에는 '비동기 루프'방법을 확실히 구현할 것입니다. getContentURL 메서드에서 실행 루프를 시작하면 실제로 다운로드 한 데이터를 receievedString 속성에 저장할 수 있습니까? –

+0

기본적으로, 그 기능/메시지를 먼저 종료하지 않고 콜백을 호출 할 수 있습니다. –

0

대리자 메서드에서 데이터를 반환하려면 코드 블록을 사용하십시오.

Apple's Blocks documentation을 참조하십시오.

+1

OP 질문에 코드가 많이 있습니다. 코드를 사용하고 예제를 보여 주시겠습니까? 메타 [좋은 답변 제공 방법] (http : //meta.stackexchange.질문에 대한 답변을 작성하는 방법) 및 유용한 [Jon Skeet 블로그] (http://msmvps.com/blogs/jon_skeet/archive/2009)를 참조하십시오. /02/17/answering-technical-questions-helpfully.aspx) – Yaroslav