13

我以为我已经弄清楚了,但我就是无法让它发挥作用。我有一个在数组中的每个 URL 上调用的方法。此方法有一个图片的 URL,应下载到应用程序支持文件夹中的特定路径以供离线使用。但也许我误解了 AFNetwork 库中的方法。我的方法如下所示:

- (void) downloadImageInBackground:(NSDictionary *)args{

  @autoreleasepool {

    NSString *photourl = [args objectForKey:@"photoUrl"];
    NSString *articleID = [args objectForKey:@"articleID"];
    NSString *guideName = [args objectForKey:@"guideName"];
    NSNumber *totalNumberOfImages = [args objectForKey:@"totalNumberOfImages"];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photourl]];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.inputStream = [NSInputStream inputStreamWithURL:[NSURL URLWithString:photourl]];

    [operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
        DLog(@"PROBLEMS_AF");
    }];
    DLog(@"URL_PHOTOURL: %@", photourl);
    DLog(@"indexSet: %@", operation.hasAcceptableStatusCode); 
    [operation  response];

    NSData *data = [args objectForKey:@"data"];

    NSString *path;
    path = [NSMutableString stringWithFormat:@"%@/Library/Application Support/Guides", NSHomeDirectory()];
    path = [path stringByAppendingPathComponent:guideName];
    NSString *guidePath = path;
    path = [path stringByAppendingPathComponent:photourl];

    if ([[NSFileManager defaultManager] fileExistsAtPath:guidePath]){
        [[NSFileManager defaultManager] createFileAtPath:path
                                                contents:data
                                              attributes:nil];
    }

    DLog(@"path: %@", path);
    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
    [operation start];


    DLog(@"isExecuting: %d",[operation isExecuting]);
    DLog(@"IS_FINISHED: %d",[operation isFinished]);


  }

} 

PhotoURL 是我要下载的图像的直接链接。

由于对所有图像调用此方法,因此多次调用所有日志,并且似乎是正确的。

4

2 回答 2

40

你在这里有几个问题。所以首先,你为什么要使用@autoreleasepool?我认为这里没有必要这样做。另外,你在使用ARC吗?对于我的其余答案,我考虑了这一点。

在 AFNetworking 中有一个名为 的类AFImageRequestOperation,所以这对你来说是个好主意。首先,导入它

#import "AFImageRequestOperation.h"

那么你可以创建一个对象

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photourl]];
AFImageRequestOperation *operation;
operation = [AFImageRequestOperation imageRequestOperationWithRequest:request 
    imageProcessingBlock:nil 
    cacheName:nil 
    success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {

    } 
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
        NSLog(@"%@", [error localizedDescription]);
    }];

现在,在成功块中,您获得了所需的 UIImage。在那里您需要获取文档目录。您的代码将无法在 ios 设备上运行。

// Get dir
NSString *documentsDirectory = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
NSString *pathString = [NSString stringWithFormat:@"%@/%@",documentsDirectory, guideName];

然后你可以使用 NSDataswriteToFile

// Save Image
NSData *imageData = UIImageJPEGRepresentation(image, 90);
[imageData writeToFile:pathString atomically:YES];

最后,您需要开始操作

[operation start];

全部一起:

- (void)downloadImageInBackground:(NSDictionary *)args{

    NSString *guideName = [args objectForKey:@"guideName"];
    NSString *photourl = [args objectForKey:@"photoUrl"];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photourl]];

    AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request 
        imageProcessingBlock:nil 
        cacheName:nil 
        success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {

            // Get dir
            NSString *documentsDirectory = nil;
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            documentsDirectory = [paths objectAtIndex:0];
            NSString *pathString = [NSString stringWithFormat:@"%@/%@",documentsDirectory, guideName];

            // Save Image
            NSData *imageData = UIImageJPEGRepresentation(image, 90);
            [imageData writeToFile:pathString atomically:YES];

        } 
        failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
            NSLog(@"%@", [error localizedDescription]);
        }];

    [operation start];
}
于 2012-06-25T11:03:45.490 回答
5

这里的问题是,操作没有保留。它将立即被释放。

要么让操作成为你的类的属性,要么让操作队列(也是一个属性)为你处理请求(推荐)。在后一种情况下,不要调用[operation start]. 当你使用AFHTTPClient操作队列时也会为你管理。

此外,您应该为请求操作 ( setCompletionBlockWithSuccess:failure:) 注册一个完成回调。

于 2012-06-25T10:38:38.217 回答