I thought I had it figured out but I just can't get it to work. I have a method that is called on every URL in an array. This method have a URL of a picture that should be downloaded in specific path in a Application Support folder for offline use. But maybe I'm misinterpreting the methods in the AFNetwork library. My method looks like this:
我以为我已经弄清楚但是我无法让它发挥作用。我有一个在数组中的每个URL上调用的方法。此方法具有应在Application Support文件夹中的特定路径中下载以供脱机使用的图片的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 is the direct link to the image that I want to download.
PhotoURL是我想要下载的图像的直接链接。
Since this method is called for all the images, all logs is called several times, and seems to be correct.
由于为所有图像调用此方法,因此所有日志都会被调用多次,并且似乎是正确的。
2 个解决方案
#1
40
You have a few problems here. so first, why are you using @autoreleasepool
? i think there is no need for this here. also, are you using ARC? i consider this, for the rest of my answer.
你在这里遇到一些问题。首先,你为什么要使用@autoreleasepool?我认为这里没有必要。还有,你在使用ARC吗?我认为这是我的其余部分。
in AFNetworking there is a class called AFImageRequestOperation
, so this would be a good idea for you to use. first, import it
在AFNetworking中有一个名为AFImageRequestOperation的类,所以这对你来说是一个好主意。首先,导入它
#import "AFImageRequestOperation.h"
then you could create an object
然后你可以创建一个对象
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]);
}];
now, in the success block, you got the UIImage you need. there you need to get the documents directory. your code will not work on an ios device.
现在,在成功模块中,您获得了所需的UIImage。你需要获取文件目录。您的代码将无法在ios设备上运行。
// Get dir
NSString *documentsDirectory = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
NSString *pathString = [NSString stringWithFormat:@"%@/%@",documentsDirectory, guideName];
and then you could use NSDatas writeToFile
然后你可以使用NSDatas writeToFile
// Save Image
NSData *imageData = UIImageJPEGRepresentation(image, 90);
[imageData writeToFile:pathString atomically:YES];
at last, you need to start the operation
最后,你需要开始操作
[operation start];
all together:
全部一起:
- (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];
}
#2
5
The problem here is, the operation is not retained. It will be deallocated immediately.
这里的问题是,不保留操作。它将立即解除分配。
Either make the operation a property of your class or let a operation queue (also a property) handle the request for you (recommended). In the latter case don't call [operation start]
. When you use AFHTTPClient
the operation queue will also be managed for you.
将操作作为类的属性或让操作队列(也是属性)处理请求(推荐)。在后一种情况下,不要调用[operation start]。使用AFHTTPClient时,还将为您管理操作队列。
Also you should register a completion callback for the request operation (setCompletionBlockWithSuccess:failure:
).
您还应该为请求操作注册完成回调(setCompletionBlockWithSuccess:failure :)。
#1
40
You have a few problems here. so first, why are you using @autoreleasepool
? i think there is no need for this here. also, are you using ARC? i consider this, for the rest of my answer.
你在这里遇到一些问题。首先,你为什么要使用@autoreleasepool?我认为这里没有必要。还有,你在使用ARC吗?我认为这是我的其余部分。
in AFNetworking there is a class called AFImageRequestOperation
, so this would be a good idea for you to use. first, import it
在AFNetworking中有一个名为AFImageRequestOperation的类,所以这对你来说是一个好主意。首先,导入它
#import "AFImageRequestOperation.h"
then you could create an object
然后你可以创建一个对象
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]);
}];
now, in the success block, you got the UIImage you need. there you need to get the documents directory. your code will not work on an ios device.
现在,在成功模块中,您获得了所需的UIImage。你需要获取文件目录。您的代码将无法在ios设备上运行。
// Get dir
NSString *documentsDirectory = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
NSString *pathString = [NSString stringWithFormat:@"%@/%@",documentsDirectory, guideName];
and then you could use NSDatas writeToFile
然后你可以使用NSDatas writeToFile
// Save Image
NSData *imageData = UIImageJPEGRepresentation(image, 90);
[imageData writeToFile:pathString atomically:YES];
at last, you need to start the operation
最后,你需要开始操作
[operation start];
all together:
全部一起:
- (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];
}
#2
5
The problem here is, the operation is not retained. It will be deallocated immediately.
这里的问题是,不保留操作。它将立即解除分配。
Either make the operation a property of your class or let a operation queue (also a property) handle the request for you (recommended). In the latter case don't call [operation start]
. When you use AFHTTPClient
the operation queue will also be managed for you.
将操作作为类的属性或让操作队列(也是属性)处理请求(推荐)。在后一种情况下,不要调用[operation start]。使用AFHTTPClient时,还将为您管理操作队列。
Also you should register a completion callback for the request operation (setCompletionBlockWithSuccess:failure:
).
您还应该为请求操作注册完成回调(setCompletionBlockWithSuccess:failure :)。