使用sendAsynchronousRequest:queue:completionHandler:用于URL请求

时间:2014-08-21 09:05:12

标签: ios objective-c nsurlconnection objective-c-blocks

我正在处理另一位开发者创建的iOS应用的更新。他正在使用ASIHTTPRequest来处理http请求。但是,应用程序的版本我必须处理崩溃。由于ASIHTTPRequest不再更新,我当时认为我应该转而使用AFNetworking,但这对我来说太复杂了。

所以最后我想我可以自己使用NSURLConnection。

以下是我尝试替换的原始代码:

-(NSArray*)readUTF16LEFeed:(NSURL*) urlToRead{
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:urlToRead];
    [request startSynchronous];
    NSError *error = [request error];
    if (!error) {
        lastModified = [NSDate date];
        NSData *response = [request responseData];//UTF-16LE
        NSString* responseString = [[NSString alloc] initWithData:response encoding:NSUTF16LittleEndianStringEncoding];
        DLog(@"string is: %@",responseString);
        responseString = [responseString stringByReplacingOccurrencesOfString:@"ISO-8859-1" withString:@"UTF16-LE"];
        NSData* data = [responseString dataUsingEncoding:NSUTF16LittleEndianStringEncoding];
        return [self parseNamesFromXML:data];
    }
    return nil;
}

以下是我尝试使用的内容:

-(NSArray*)readUTF16LEFeed:(NSURL*) urlToRead{

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

                               if ([data length] >0 && error == nil)
                               {
                                   // DO YOUR WORK HERE
                                   lastModified = [NSDate date];

                                   //   NSData *response = [request responseData];//UTF-16LE
                                   NSString* responseString = [[NSString alloc] initWithData:data encoding: NSUTF16LittleEndianStringEncoding];
                                   DLog(@"string is: %@",responseString);
                                   responseString = [responseString stringByReplacingOccurrencesOfString:@"ISO-8859-1" withString:@"UTF16-LE"];
                                   NSData* data = [responseString dataUsingEncoding:NSUTF16LittleEndianStringEncoding];
                                   return [self parseNamesFromXML:data];
                               }

                               else if ([data length] == 0 && error == nil)
                               {
                                   NSLog(@"Nothing was downloaded.");
                               }
                               else if (error != nil){
                                   NSLog(@"Error = %@", error);
                               }
                           }];
    return nil;
}

但是,我收到错误"不兼容的块指针类型将NSArray发送到void类型的参数。而且"控制可能会到达非空白块的末尾。"

我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分:1)

使方法的返回类型为void。不要退货。只需调用[self parseNamesFromXML:data];方法。

-(void)readUTF16LEFeed:(NSURL*) urlToRead{


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

                       if ([data length] >0 && error == nil)
                       {

                           // DO YOUR WORK HERE
                           lastModified = [NSDate date];

                      //   NSData *response = [request responseData];//UTF-16LE
                           NSString* responseString = [[NSString alloc] initWithData:data encoding: NSUTF16LittleEndianStringEncoding];
                           DLog(@"string is: %@",responseString);
                           responseString = [responseString stringByReplacingOccurrencesOfString:@"ISO-8859-1" withString:@"UTF16-LE"];
                           NSData* data = [responseString dataUsingEncoding:NSUTF16LittleEndianStringEncoding];
                           [self parseNamesFromXML:data];
                       }


                       else if ([data length] == 0 && error == nil)
                       {
                           NSLog(@"Nothing was downloaded.");
                       }
                       else if (error != nil){
                           NSLog(@"Error = %@", error);
                       }

                   }];
}

parseNamesFromXML方法中,处理结果并将结果数组分配给属性。您可以随时随地访问它。

-(void) parseNamesFromXML:(NSData *)xmlData
{     
    NSError *error;          
    //DLog(@"data is %@", [[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding ]);     

    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData                                                            options:0 error:&error];          

    if (doc)
    {         
        self.dataArray = [self parseXmlDoc:doc]; 
    }              
}

答案 1 :(得分:0)

异步调用完成块,因此当代码到达return [self parseNamesFromXML:data];时,方法范围已经完成(意味着方法返回为零。

请尝试使用[NSURLConnection sendSynchronousRequest:returningResponse:error:],因为原始代码也是同步的。

编辑: 正如JulianKról所建议的,如果你在一个区块内返回一些内容,它将被计为该区块的返回值,而不是原始方法的返回值。但由于该块没有返回值,因此您将收到编译器错误。