如何从互联网下载文件并保存在iPhone上的“文档”?

问题描述:

我的远程服务器上有一个文件夹,其中包含几个.png文件。我想从我的应用程序下载这些,并将它们存储在应用程序的文档文件夹中。如何做到这一点?

I have a folder on my remote server that has a few .png files in it. I want to download these from within my app and store them in the apps 'Documents' folder. How can I do this?

简单的方法是使用NSData的方便方法 initWithContentOfURL: code>和 writeToFile:atomically:分别获取数据并写出来。请记住,这是同步的,将阻止您执行的任何线程,直到获取和写入完成。

The easy way is to use NSData's convenience methods initWithContentOfURL: and writeToFile:atomically: to get the data and write it out, respectively. Keep in mind this is synchronous and will block whatever thread you execute it on until the fetch and write are complete.

例如:

// Create and escape the URL for the fetch
NSString *URLString = @"http://example.com/example.png";
NSURL *URL = [NSURL URLWithString:
              [URLString stringByAddingPercentEscapesUsingEncoding:
                          NSASCIIStringEncoding]];

// Do the fetch - blocks!
NSData *imageData = [NSData dataWithContentsOfURL:URL];
if(imageData == nil) {
    // Error - handle appropriately
}

// Do the write
NSString *filePath = [[self documentsDirectory] 
                      stringByAppendingPathComponent:@"image.png"];
[imageData writeToFile:filePath atomically:YES];

documentsDirectory 方法无耻地从这个问题

- (NSString *)documentsDirectory {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask, YES);
    return [paths objectAtIndex:0];
}

但是,除非您打算自己进行线程,否则这会在文件下载时停止UI活动。您可能想要查看NSURLConnection及其代理 - 它会在后台下载并通知代理关于异步下载的数据,因此您可以构建一个NSMutableData的实例,然后在连接完成时将其写入。您的委托可能包含以下方法:

However, unless you intend to thread it yourself this will stop UI activity while the file downloads. You may instead want to look into NSURLConnection and its delegate - it downloads in the background and notifies a delegate about data downloaded asynchronously, so you can build up an instance of NSMutableData then just write it out when the connection's done. Your delegate might contain methods like:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Append the data to some preexisting @property NSMutableData *dataAccumulator;
    [self.dataAccumulator appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // Do the write
    NSString *filePath = [[self documentsDirectory] 
                          stringByAppendingPathComponent:@"image.png"];
    [imageData writeToFile:filePath atomically:YES];
}

小细节,如声明 dataAccumulator 和处理错误,留给读者:)

The little details, like declaring the dataAccumulator and handling errors, are left to the reader :)

重要文件:

  • NSData
  • NSURLConnection