如何从NSURLSessionDataTask获取数据

Cry*_*ios 7 objective-c ios nsurlsession

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

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

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

这是在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];
Run Code Online (Sandbox Code Playgroud)

这是在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;
Run Code Online (Sandbox Code Playgroud)

}

dan*_*anh 14

帖子以异步方式完成,因此您wsClass需要告知来电者完成帖子后的完成情况.一个很好的方法是sendData使用应该在完成时运行的调用者提供的代码块来扩充该方法:

更改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);
        }];
    }
Run Code Online (Sandbox Code Playgroud)

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

// 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"
}];
Run Code Online (Sandbox Code Playgroud)

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