Web服务完成后的完成块?

时间:2016-03-01 16:46:04

标签: ios objective-c rest

我在名为WebServices的类中实现了RESTful API。我从我的应用程序中的其他类调用此类中的方法,并希望在成功完成Web服务后执行操作。我有一个完成块作为我的方法标题的一部分,但我不确定我是否正确使用它们,因为应用程序似乎永远不会到达方法调用的完成部分。这就是我调用方法的方法:

  [services callUnregisterForPushNotifications:savedAccessToken pushToken:savedPushToken completionBlock:^(NSMutableArray *resultsArray) {

        NSLog(@">>> COMPLETE! <<<");

        [self.loadingView removeFromSuperview];
    }];

我调用的方法如下:

- (void)callUnregisterForPushNotifications:(NSString *)accessToken
                               pushToken:(NSString *)pushToken
                         completionBlock:(void (^)(NSMutableArray *resultsArray))completion{

    NSLog(@"UNREGISTER FOR PUSH CALLED!");

    NSLog(@"PUSH TOKEN %@", pushToken);

    NSString *appendUrl = @"alerts/unregisterpush/";

    NSLog(@"APPEND URL %@",appendUrl);

    NSURL *unregisterUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", BaseURLString, appendUrl]];
    NSLog(@"UNREGISTER URL: %@",unregisterUrl);

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:unregisterUrl
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                       timeoutInterval:30.0];

    [request setHTTPMethod:@"PUT"];

    NSString *appendToken = [NSString stringWithFormat:@"Bearer %@", accessToken];
    NSLog(@"TOKEN: %@",appendToken);

    [request addValue:appendToken forHTTPHeaderField:@"Authorization"];
    [request addValue:@"application/json, text/plain, */*" forHTTPHeaderField:@"Accept"];
    [request addValue:@"application/json;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];


    NSString *postString = [NSString stringWithFormat:@"{\"Guid\":\"%@\"}",pushToken];
    NSLog(@"POST STRING: %@",postString);
    [request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

    NSLog(@"REQUEST %@",request);

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

                                                              NSLog(@"UNREGISTER PUSH NOTIFICATIONS RESPONSE: %@", response);
                                                              NSLog(@"UNREGISTER PUSH NOTIFICATIONS ERROR: %@", error);
                                                              NSLog(@"UNREGISTER PUSH NOTIFICATIONS DATA: %@", data);

                               NSData *_data = data;// ... whatever
                               NSMutableString *_string = [NSMutableString stringWithString:@""];
                               for (int i = 0; i < _data.length; i++) {
                                   unsigned char _byte;
                                   [_data getBytes:&_byte range:NSMakeRange(i, 1)];
                                   if (_byte >= 32 && _byte < 127) {
                                       [_string appendFormat:@"%c", _byte];
                                   } else {
                                       [_string appendFormat:@"[%d]", _byte];
                                   }
                               }
                               NSLog(@"UNREGISTER PUSH RESPONSE: %@", _string);

                               id obj= [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
                               if (!obj) {
                                    //NSLog(@"REGISTER PUSH NOTIFICATIONS ERROR: %@", error);

                               } else {
                                    //NSLog(@"REGISTER PUSH NOTIFICATIONS DATA: %@", obj);

                                   //self.accessToken = [obj valueForKey:@"access_token"];
                                   //NSLog(@"ACCESS TOKEN: %@",self.accessToken);
                               }

                           }];
}

任何建议/意见都将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:3)

在你的else块中你应该像这样调用完成处理程序:

// [code omitted for brevity]

                       NSLog(@"UNREGISTER PUSH RESPONSE: %@", _string);

                       id obj= [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
                       if (!obj) {
                            //NSLog(@"REGISTER PUSH NOTIFICATIONS ERROR: %@", error);

                       } else {
                            completionHandler(resultsArray); // add this line to actually call the completion block passed in
                            //NSLog(@"REGISTER PUSH NOTIFICATIONS DATA: %@", obj);

                           //self.accessToken = [obj valueForKey:@"access_token"];
                           //NSLog(@"ACCESS TOKEN: %@",self.accessToken);
                       }


                   }];

还要确保传入实际数组而不是传递的resultsArray参数。

你基本上做的是传递一个函数(或者#34; block&#34;),它不知道何时执行(你必须在任何异步任务完成后自己完成)。所以你从调用方法传递了块:

[services callUnregisterForPushNotifications:savedAccessToken pushToken:savedPushToken completionBlock:^(NSMutableArray *resultsArray) {

        NSLog(@">>> COMPLETE! <<<");

        [self.loadingView removeFromSuperview];
    }];

花括号中包含的代码块被传递给函数callUnregisterForPushNotifications:pushToken:completionHandler:并分配给completionHandler参数,该参数现在包含您在最初调用方法时传入的代码块。接收completionHandler块的方法负责在异步任务(网络请求)完成后调用它(正如您在我发布的第一个片段中看到的那样)。

completionHandler(resultsArray);

这样,一旦你的请求完成(else块),你就可以执行传入的完成块。这实际上意味着&#34;执行我之前传递的代码块因为现在我们有来自网络运营的数据。&#34;