如何使用AFNetworking下载文件并将其保存到文档目录?

iam*_*mug 50 iphone ios afnetworking

我正在使用AFNetworking库.我无法弄清楚如何下载文件并将其保存到文档目录.

mat*_*ttt 138

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"..."]];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"filename"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Successfully downloaded file to %@", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

[operation start];
Run Code Online (Sandbox Code Playgroud)

  • 请注意,上述代码将从服务器下载任何响应到输出流,因此如果服务器以状态代码404响应,404页面将保存到指定的路径.您必须检查operation.response.statusCode的成功块. (19认同)
  • 您甚至可以添加进度块://设置上传块以返回文件上传进度[操作setDownloadProgressBlock:^(NSInteger bytesWritten,long long totalBytesWritten,long long totalBytesExpectedToRead){float progress = totalBytesWritten /(float)totalBytesExpectedToRead; NSLog(@"下载百分比:%f %%",进度*100); }]; (10认同)
  • 而不是手动检查状态代码,只需使用`operation.hasAcceptableStatusCode` (6认同)

swi*_*ams 31

我要退出@mattt的回答并发布AFNetworking 2.0的版本AFHTTPRequestOperationManager.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"filename"];

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *op = [manager GET:@"http://example.com/file/to/download" 
                               parameters:nil
    success:^(AFHTTPRequestOperation *operation, id responseObject) {
         NSLog(@"successful download to %@", path);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
         NSLog(@"Error: %@", error);
    }];
op.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
Run Code Online (Sandbox Code Playgroud)

  • @swilliams [AFHTTPRequestOperationManager manager]将使用默认的AFJSONResponseSerializer创建新的管理器对象,你想要吗?我认为最好创建AFNoneResponseSerialize以保持文件不变 (2认同)

onm*_*133 5

我在谈论AFNetworking 2.0

[AFHTTPRequestOperationManager manager]使用默认的AFJSONResponseSerializer创建管理器对象,并执行内容类型限制.看看这个

- (BOOL)validateResponse:(NSHTTPURLResponse *)response
                    data:(NSData *)data
                   error:(NSError * __autoreleasing *)error
Run Code Online (Sandbox Code Playgroud)

所以我们需要创建一个无响应的序列化器并AFHTTPRequestOperationManager正常使用.

这是AFNoneResponseSerializer

@interface AFNoneResponseSerializer : AFHTTPResponseSerializer

+ (instancetype)serializer;

@end

@implementation AFNoneResponseSerializer

#pragma mark - Initialization
+ (instancetype)serializer
{
    return [[self alloc] init];
}

- (instancetype)init
{
    self = [super init];

    return self;
}

#pragma mark - AFURLResponseSerializer
- (id)responseObjectForResponse:(NSURLResponse *)response
                           data:(NSData *)data
                          error:(NSError *__autoreleasing *)error

{
    return data;
}

@end
Run Code Online (Sandbox Code Playgroud)

用法

self.manager = [AFHTTPRequestOperationManager manager];
self.manager.responseSerializer = [AFNoneResponseSerializer serializer];

[self.manager GET:@"https://sites.google.com/site/iphonesdktutorials/xml/Books.xml"
           parameters:parameters
              success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        if (success) {
            success(responseObject);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if (failure) {
            failure(error);
        }
    }];
Run Code Online (Sandbox Code Playgroud)

这样我们就可以在没有任何序列化的情况下获得整个文件