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

发布于 2024-08-21 15:20:53 字数 3079 浏览 2 评论 0原文

我已经回顾了类似的 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;

我在通讯类中有以下方法:

-(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 );
}

我已按照以下方式在通讯类中创建了所需的委托:

-(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 成功输出 receiveString 字符串。

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

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

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

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

I have reviewed similar stackoverflow questions/answers to this but I am still stumped.

I'm a beginner and I'm really struggling with this. With the iPhone, I can download XML from a URL but I cannot store the result string in a NSString variable and see it from the calling function.

I have the following declarations in a custom made class:

@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;

I have the following method in the comms class:

-(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 );
}

I have created the required delegates in the comms class as per the following:

-(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];
}

I can successfully output the receivedString string using NSLog in the connectionDidFinishLoading delegate.

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

However, when I output the receivedString string in the getContentURL it's null (and hence is also null from the ViewController.m class which I call the comms class from).

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

Any ideas on how I can see the value of receivedString in getContentURL and from the ViewController.m class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吝吻 2024-08-28 15:20:53

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

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

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

NSURLConnection is an asynchronous API. When you start the request, the object will spawn a new thread, and only update your main one via the callback/delegate methods. Your current method will return most likely before the request is finished, and so the string of the result will not have downloaded yet!

If you want to do this synchronously, you will have two options:

  1. Use the built in synchronous download method. Note that as this blocks, it will not allow the user to interact with the UI.
  2. Use the C functions CFRunLoopRun() and CFRunLoopStop() to start the run loop inside your calling function, wait until the download is complete or failed, then return control back to the calling method with CFRunLoopStop().
ぇ气 2024-08-28 15:20:53

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

请参阅 Apple 的 Blocks 文档

To return data from the delegates method, please use Code Block.

See Apple's Blocks documentation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文