如何从NSURLSessionDataTask获取数据 [英] How to get data to return from NSURLSessionDataTask

查看:74
本文介绍了如何从NSURLSessionDataTask获取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个注册视图控制器,它处理所有用户输入并调用传递给它的另一个类(wsClass)中的函数,该数据作为NSDictionary。

I have a registration view controller which handles all the user input and calls a function in another class (wsClass) passing to it, that data as an NSDictionary.

调用wsClass中的函数并建立连接,并从服务器返回数据并在会话中使用。

The function in wsClass is called and the connection is made and data is returned from the server and available within the session.

我的问题是如何将该数据返回到最初调用该函数的注册视图控制器,它总是空的。

My question is how do I return that data to the registration viewcontroller where the function was originally called, it's always coming up empty.

这是在registrationViewController中的调用:

Here is the call in registrationViewController:

        wsClass *ws = [[wsClass alloc] init];
    NSDictionary *testDict = [[NSDictionary alloc] initWithObjectsAndKeys:username.text,@"username",email.text,@"email",password.text,@"password", nil];
    NSDictionary *respDict = [ws sendData:testDict];

这是在wsClass.m中调用的函数:

Here is the function being called in wsClass.m:

- (NSDictionary *)sendData:(NSDictionary *)sendDict {
NSMutableString *sendStr = [[NSMutableString alloc] init];

[sendDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    [sendStr appendFormat:@"&%@=%@", key, obj];
}];

NSLog(@"sendStr is: %@",sendStr);
NSString *noteDataString = [NSString stringWithFormat:@"%@%@",REQUIRED,sendStr];

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlTest]];
request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPMethod = @"POST";

NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request
                                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                    // The server answers with an error because it doesn't receive the params
                                                    // handle response
                                                    if(error == nil)
                                                    {
                                                        [getReqAlert dismissWithClickedButtonIndex:0 animated:YES];

                                                        NSError *e = nil;
                                                        jsonArray = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableLeaves error: &e];

                                                        if (!jsonArray) {
                                                            NSLog(@"Error parsing JSON: %@", e);
                                                        } else {

                                                            NSLog(@"resp: %@ = %@",[jsonArray objectForKey:@"status"],[jsonArray objectForKey:@"msg"]);
                                                            NSLog(@"Dictionary count: %lu", jsonArray.count);
                                                        }
                                                    }
                                                }];

 [postDataTask resume];

return jsonArray;

}

推荐答案

帖子以异步方式完成,因此你的 wsClass 需要在帖子完成后告诉调用者完成。一个很好的方法是用一个应该在完成时运行的调用者提供的代码块来增加 sendData 方法:

The post completes asynchronously, so your wsClass needs to tell the caller about completion after post is finished. A nice way to do this is to augment the sendData method with a block of code supplied by the caller that should be run upon completion:

更改 sendData:如下所示:

// it doesn't return anything, because all it does is launch the post
// but when the post is done, it invokes completion

- (void)sendData:(NSDictionary *)sendDict completion:(void (^)(NSDictionary *))completion {

    // the stuff you're already doing

        NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request
            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            // the stuff you're already doing
            // now tell the caller that you're done
            completion(jsonArray);
        }];
    }

调用者现在看起来像这样:

The caller now looks like this:

// change the UI to say "I'm busy doing the post"
[ws sendData:testDict completion:^(NSDictionary *responseDict) {
    NSLog(@"this runs later, after the post completes %@", responseDict);
    // change the UI to say "The post is done"
}];

关于这一点的几个注释:(1)我没有添加错误参数给块,你可能应该。检查并调用带有nil和错误的块,或者使用json输出和error = nil。 (2)您的代码假定json结果作为字典解析。在代码中假设它之前,请确保始终为真。 (3)班级名称通常以大写字母开头。

Just a couple of notes about this: (1) I didn't add an error param to the block, you probably should. Check that and invoke the block with either nil and an error, or with the json output and error=nil. (2) Your code assumes that the json result parses as a dictionary. Make sure that's always true before you assume it in code. (3) Class names usually begin with caps.

这篇关于如何从NSURLSessionDataTask获取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆