ios 从 NSURLResponse 完成块中获取数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12352901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:02:41  来源:igfitidea点击:

Getting data out of the NSURLResponse completion block

objective-ciosnsurlconnectionobjective-c-blocks

提问by brainray

It looks like I didn't get the concept of blocks completely yet...

看起来我还没有完全理解块的概念......

In my code I have to get out the JSON data from the asychronous blockto be returned to from the 'outer' method. I googled and found that if defining a variable with __block, the v?i?s?i?b?i?l?i?t?y? _mutability_ ofthat variable is extended to the block.

在我的代码中,我必须asychronous block从 ' outer' 方法中获取要返回的 JSON 数据。我用谷歌搜索,发现如果定义 a variable with __block,则 v?i?s?i?b?i?l?i?t?y? _mutability_ of该变量扩展到block.

But for some reason returned json object is nil.I wonder why?

但是由于某种原因返回的 json 对象为零。我想知道为什么?

- (NSMutableDictionary *)executeRequestUrlString:(NSString *)urlString
{
__block NSMutableDictionary *json = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setHTTPShouldHandleCookies:YES];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];

NSString *cookieString = [self.userDefaults objectForKey:SAVED_COOKIE];

[request addValue:cookieString forHTTPHeaderField:@"Cookie"];

[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue currentQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
                       {

                           NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);

                           NSError *error1;
                           NSMutableDictionary * innerJson = [NSJSONSerialization
                                   JSONObjectWithData:data
                                              options:kNilOptions
                                                error:&error1];
                           json = innerJson;

                       }];

    return json;
}

回答by dasblinkenlight

First, to answer your question:

首先,回答你的问题:

But for some reason returned json object is nil. I wonder why?

但由于某种原因返回的 json 对象是nil. 我想知道为什么?

The variable that you are returning has not been set at the time when you return it. You cannot harvest the results immediately after the sendAsynchronousRequest:queue:completionHandler:method has returned: the call has to finish the roundtrip before calling back your block and setting jsonvariable.

您返回的变量在您返回时尚未设置。您不能在sendAsynchronousRequest:queue:completionHandler:方法返回后立即获取结果:调用必须在回调块和设置json变量之前完成往返。

Now a quick note on what to do about it: your method is attempting to convert an asynchronous call into a synchronous one. Try to keep it asynchronous if you can. Rather than expecting a method that returns a NSMutableDictionary*, make a method that takes a block of its own, and pass the dictionary to that block when the sendAsynchronousRequest:method completes:

现在快速说明如何处理它:您的方法正在尝试将异步调用转换为同步调用。如果可以,尽量保持异步。与其期待一个返回 a 的方法,不如NSMutableDictionary*创建一个接受自己的块的方法,并在该sendAsynchronousRequest:方法完成时将字典传递给该块:

- (void)executeRequestUrlString:(NSString *)urlString withBlock:(void (^)(NSDictionary *jsonData))block {
    // Prepare for the call
    ...
    // Make the call
    [NSURLConnection sendAsynchronousRequest:request
                                    queue:[NSOperationQueue currentQueue]
                        completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);
        NSError *error1;
        NSMutableDictionary * innerJson = [NSJSONSerialization
            JSONObjectWithData:data options:kNilOptions error:&error1
        ];
        block(innerJson); // Call back the block passed into your method
        }];

}

回答by Rob Napier

When you call sendAsynchronousRequest:queue:completionHandler:, you've requested an asynchronousrequest. So it queues the request and the block and returns immediately. At some point in the future the request is made, and some point after that the completion block is run. But by that time, return jsonhas long since run.

当您调用 时sendAsynchronousRequest:queue:completionHandler:,您已经请求了一个异步请求。因此它将请求和块排队并立即返回。在未来的某个时间点发出请求,之后的某个时间点运行完成块。但到了那个时候,return json早就跑了。

If you want to be able to return the data synchronously, then you must make a synchronous request. That will hang this thread until it completes, so it must not be the main thread.

如果希望能够同步返回数据,那么必须进行同步请求。这将挂起这个线程直到它完成,所以它不能是主线程。

回答by Manish Verma

Check the string when converting data coming from server using below code:

使用以下代码转换来自服务器的数据时检查字符串:

 NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);

if the string is in a proper JSON format, ONLY then your JSON object will be correct.

如果字符串采用正确的 JSON 格式,那么您的 JSON 对象才会正确。

Hope this hepls!!

希望这有帮助!!