2012-06-25 35 views
12

Tôi nghĩ tôi đã tìm ra nhưng tôi không thể làm việc đó được. Tôi có một phương thức được gọi trên mọi URL trong một mảng. Phương pháp này có URL của ảnh cần được tải xuống trong đường dẫn cụ thể trong thư mục Hỗ trợ ứng dụng để sử dụng ngoại tuyến. Nhưng có lẽ tôi hiểu sai các phương pháp trong thư viện AFNetwork. Phương pháp của tôi trông giống như sau:Tải xuống tệp/hình ảnh với AFNetworking trong iOS?

- (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 là liên kết trực tiếp đến hình ảnh mà tôi muốn tải xuống.

Vì phương pháp này được gọi cho tất cả hình ảnh, tất cả nhật ký được gọi nhiều lần và có vẻ đúng.

Trả lời

39

Bạn có một vài vấn đề ở đây. đầu tiên, tại sao bạn sử dụng @autoreleasepool? tôi nghĩ rằng không cần thiết cho điều này ở đây. ngoài ra, bạn có đang sử dụng ARC không? tôi xem xét điều này, cho phần còn lại của câu trả lời của tôi.

trong AFNetworking có một lớp được gọi là AFImageRequestOperation, vì vậy, đây là ý tưởng hay để bạn sử dụng. đầu tiên, nhập nó

#import "AFImageRequestOperation.h" 

sau đó bạn có thể tạo ra một đối tượng

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]); 
    }]; 

bây giờ, trong khối thành công, bạn có UIImage bạn cần. ở đó bạn cần có thư mục tài liệu. mã của bạn sẽ không hoạt động trên thiết bị ios.

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

và sau đó bạn có thể sử dụng NSDatas writeToFile

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

Cuối cùng, bạn cần phải bắt đầu các hoạt động

[operation start]; 

tất cả cùng nhau:

- (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]; 
} 
+0

Bạn đã chỉ cho tôi thẳng . Đã có một số nghi ngờ về những gì tôi đã làm, cảm ơn bạn rất nhiều. –

+2

bổ sung: nếu bạn có nhiều yêu cầu cùng một lúc, hãy xem xét sử dụng 'NSOperationQueue' (tất cả các Lớp AFRequestOperation đều tuân thủ mã hóa) và để hàng đợi xử lý các hoạt động. điều này có thể có ích và sẽ không kích hoạt 100 yêu cầu cùng một lúc. – choise

+0

Có bao nhiêu yêu cầu mà một ứng dụng thường có thể xử lý mà không cần triển khai NSOperationQueue ?, nó sẽ không bao giờ có nhiều hơn 50 yêu cầu, là đủ để nó thực hiện? –

5

Vấn đề ở đây là, thao tác không được giữ lại. Nó sẽ được deallocated ngay lập tức.

Hoặc là biến hoạt động thành thuộc tính của lớp học hoặc để hàng đợi hoạt động (cũng là thuộc tính) xử lý yêu cầu cho bạn (được khuyến nghị). Trong trường hợp sau không gọi [operation start]. Khi bạn sử dụng AFHTTPClient hàng đợi hoạt động cũng sẽ được quản lý cho bạn.

Ngoài ra, bạn nên đăng ký gọi lại hoàn tất cho hoạt động yêu cầu (setCompletionBlockWithSuccess:failure:).

Các vấn đề liên quan