NSURLConnection下载多个图像 [英] NSURLConnection Download multiple images

查看:104
本文介绍了NSURLConnection下载多个图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从存储在XML Feed中的网址下载多个图片。从XML获取图像网址正常工作。但是,NSURLConnection正在创建空文件,但是如NSLog中所述接收数据。在 connectionDidFinishLoading:(NSURLConnection *)连接,接收数据和正确的字节,问题是如何使receiveData写入正确的文件。

I am trying to download multiple images from a URL stored in an XML feed. Getting the image urls from the XML is working correctly. However, the NSURLConnection is creating empty files, but the data is received as noted in NSLog. In connectionDidFinishLoading:(NSURLConnection *)connection, the data and correct bytes are received, the problem is how do I make the receivedData write to the correct file.

-(void)parsingComplete:(XMLDataSource*)theParser 
{
    /*  iterate through the Categories and create the 
        sub-directory if it does not exist  
     */
    for (int i = 0; i < [categories count]; i++) {
        NSString *cat      = [NSString stringWithFormat:@"%@/%@",BASE_DIR,[[categories objectAtIndex:i] objectForKey:@"name"]];
        NSString *catName  = [[categories objectAtIndex:i] objectForKey:@"name"];
        NSArray  *catArray = [[categories objectAtIndex:i] objectForKey:@"images"];

        /*  create the sub-direcotry naming it the #category# key  */
        if (![FILEMANAGER fileExistsAtPath:cat]) {
            [FILEMANAGER createDirectoryAtPath:cat withIntermediateDirectories:NO attributes:nil error:nil];
        }

        //NSLog(@"\n\nCategory: %@",cat);
        for (int x = 0; x < [catArray count]; x++) {
            //NSLog(@"Image: %@",[[catArray objectAtIndex:x] objectForKey:@"imageUrl"]);   
            /*  download each file to the corresponding category sub-directory  */
            fileOut = [NSString stringWithFormat:@"%@/%@_0%i.jpg",cat,catName,x];

            NSURLRequest *imageRequest = 
            [NSURLRequest requestWithURL:[NSURL URLWithString:[[catArray objectAtIndex:x] objectForKey:@"imageUrl"]]
                             cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
            NSURLConnection *imageConnection = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self];

            int counter = 0;
            //BOOL result = NO;
            if(imageConnection)
            {
                NSLog(@"Counter: %i",counter++);
                receivedData = [[NSMutableData data] retain];
                /*result = */[receivedData writeToFile:fileOut atomically:YES];
            }
            /*
                if (!result) NSLog(@"Failed"); else NSLog(@"Successful");
             */
        }
    }
}

#pragma mark NSURLConenction

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response  {  
    [receivedData setLength:0];  
} 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data  {  
    [receivedData appendData:data];
}  
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    // release the connection, and the data object
    [connection release];
    // receivedData is declared as a method instance elsewhere
    [receivedData release];
    // inform the user
    NSLog(@"Connection failed! Error - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection  
{  
    // do something with the data  
    // receivedData is declared as a method instance elsewhere  
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);  
    NSString *aStr = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];  
    // release the connection, and the data object  
    //[receivedData release];  
} 


推荐答案

连接告诉你它已经完成,然后才能写入数据。连接在另一个线程上处理;如果你尝试在你正在做的时候立即访问原始线程上的数据,它将不会有任何东西。

You have to wait until the connection tells you it has finished before you can write the data. The connection is handled on another thread; if you try to access the data immediately on the original thread as you're doing, there won't be anything in it.

你应该移动 writeToFile:调用 connectionDidFinishLoading:结尾,或者从另一个方法调用。这是第一点,你知道数据已经收集。

You should move the writeToFile: call to the end of connectionDidFinishLoading:, or to another method that you call from there. That's the first point where you know that the data has all been collected.

我还建议在 didRecieveResponse: NSMutableData $ c>,让你知道它是在正确的时间可用。这将更可读/可理解。您可以将委托方法想象为一个集合的范围 - 数据只在它们内部使用,因此它应该在其中一个内部创建。

I'd also suggest creating the NSMutableData instance in didRecieveResponse:, so that you know that it is available at the correct time. That will be more readable/understandable. You can think of the delegate methods as a collective "scope" -- the data is only used inside of them, so it should be created inside of one of them.

回复您的评论:

一种可能,因为你有这么多需要做的这一个下载,似乎没有触摸的GUI,是在后台线程上运行整个 parsingComplete:方法,并使用 + [NSURLConnection sendSynchronousRequest:returningResponse:error:] 。这样,你的代码就会一直等到数据返回,并且在 sendSynchronous ... 调用返回后立即写入。

One possibility, since you have so much that needs to be done around this one download, and don't seem to be touching the GUI, is to run the whole parsingComplete: method on a background thread, and using +[NSURLConnection sendSynchronousRequest:returningResponse:error:]. This way your code will just wait until the data comes back, in one piece, and you can write it immediately after the sendSynchronous... call returns.

NSError * err;
NSURLResponse * response;
NSData * receivedData = [NSURLConnection sendSynchronousRequest:imageRequest
                                              returningResponse:&response
                                                          error:&err];
if( !receivedData ){
    /* Handle error */
}
/* Check response */

BOOL result = [receivedData writeToFile:fileOut atomically:YES];
/* check result, etc. */

这篇关于NSURLConnection下载多个图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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