iPhone NSURLConnection:connectionDidFinishLoading - 如何将字符串返回给调用方法

时间:2010-02-12 03:40:44

标签: iphone string methods return nsurlconnection

我已经审查了类似的stackoverflow问题/答案,但我仍然感到难过。

我是初学者,我真的很挣扎。使用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];
}

我可以在connectionDidFinishLoading委托中使用NSLog成功输出receivedString字符串。

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

但是,当我在getContentURL中输出receivedString字符串时,它是null(因此我从ViewController.m类中调用comms类来为null)。

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

有关如何在getContentURL和ViewController.m类中查看receiveString值的任何想法?

2 个答案:

答案 0 :(得分:4)

NSURLConnection是一个异步API。当您启动请求时,该对象将生成一个新线程,并且只通过回调/委托方法更新您的主线程。您的当前方法最有可能在请求完成之前返回,因此结果的字符串还没有下载!

如果您想同步执行此操作,您将有两个选择:

  1. 使用内置的同步下载方法。请注意,由于此阻止,它将不允许用户与UI进行交互。
  2. 使用C函数CFRunLoopRun()和CFRunLoopStop()启动调用函数内的运行循环,等待下载完成或失败,然后使用CFRunLoopStop()将控制权返回给调用方法。

答案 1 :(得分:0)

要从委托方法返回数据,请使用代码块。

请参阅Apple's Blocks documentation