【发布时间】:2026-01-20 01:35:01
【问题描述】:
如何从 OS X 应用程序中的 URL 下载文件?我是一名 Unix C 和 Perl 程序员,刚接触 Objective C。我一直在阅读 URL Loading System Programming Guide,它建议 NSURLSession 用于新的 OS X 应用程序。所以我更喜欢 NSURLSession 或 NSURLSeesionDownloadTask 的解决方案,但我对 NSURLDownload 或其他解决方案持开放态度。
我的第一次尝试是基于找到的示例 here
NSURLSessionDownloadTask *downloadTask =
[[NSURLSession sharedSession]
downloadTaskWithURL:[NSURL URLWithString:pdfFile]
completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
// move tmp file to permanent location
NSLog(@"Done...");
NSLog(@"Location: %@", location);
NSLog(@"Response: %@", response);
NSLog(@"Error %@", error);
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL fileCopied = [fileManager moveItemAtPath:[location path] toPath:[appDir stringByAppendingString:@"/demo.pdf"] error:&error];
NSLog(fileCopied ? @"File Copied OK" : @"ERROR Copying file.");
}];
[downloadTask resume];
NSLog(@"Now we are here");
示例代码(和我的版本)没有单独的委托。完成处理程序是“在线的”。 (不确定这是否是正确的术语)。我假设此代码将在下载任务完成后执行。对吗?
我的第二次尝试是基于 URL 编程指南的“下载文件”部分:
// PDF file Download, try #2
NSError *error = nil;
NSString *appDir = NSHomeDirectory();
NSString *pdfFile = @"https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/AppDistributionGuide.pdf";
// Configure Cache behavior for default session
NSURLSessionConfiguration
*defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSString *cachePath = [NSTemporaryDirectory()
stringByAppendingPathComponent:@"/pdfDownload.cache"];
NSLog(@"Cache path: %@\n", cachePath);
NSURLCache *myCache = [[NSURLCache alloc] initWithMemoryCapacity: 16384
diskCapacity: 268435456 diskPath: cachePath];
defaultConfigObject.URLCache = myCache;
defaultConfigObject.requestCachePolicy = NSURLRequestUseProtocolCachePolicy;
defaultConfigObject.timeoutIntervalForRequest = 100;
defaultConfigObject.timeoutIntervalForResource = 100;
// Create a delegate-Free Session
NSURLSession *delegateFreeSession =
[NSURLSession sessionWithConfiguration: defaultConfigObject
delegate: nil
delegateQueue: [NSOperationQueue mainQueue]];
[[delegateFreeSession downloadTaskWithURL:[NSURL URLWithString:pdfFile] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
// move tmp file to permanent location
NSLog(@"Done...");
NSLog(@"Location: %@", location);
NSLog(@"Response: %@", response);
NSLog(@"Error %@", error);
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL fileCopied = [fileManager moveItemAtPath:[location path] toPath:[appDir stringByAppendingString:@"/demo.pdf"] error:&error];
NSLog(fileCopied ? @"File Copied OK" : @"ERROR Copying file.");
}] resume];
sleep(10);
NSLog(@"After sleep...");
在这两种情况下,代码执行永远不会到达作为completionHandler 一部分的NSLog 语句。我在模拟器中设置了断点,但从未到达那里。如何创建简单的“免费委托”文件下载方法?
由于我正在编写“命令行”OS X 应用程序,因此我没有 UIViewController 或其他现有的委托结构。
关于如何进行的任何建议?我不需要下载进度条等,只需要“通过/失败”状态。
另外,我的示例是针对单个 PDF 文件的。我的应用程序有一系列我想下载的 URL。我不需要并行下载它们。我可以在循环中重复使用单个 NSURLSession 吗?
任何帮助将不胜感激!
【问题讨论】:
-
如果问题是您的请求超时,您可能没有给它足够的时间使其失败并打印错误消息。这取决于您的超时设置(可能是默认值)。
-
@ZevEisenberg:我添加了第二个代码片段,其中包含一些详细配置,包括高超时值。仍然永远不会到达完成处理程序。我认为这应该在模拟器中工作,对吗?
-
什么模拟器?你说这是一个 OS X 应用程序。
-
@ZevEisenberg:Xcode 模拟器。我的目标是 OS X,但目前我仍在模拟器中运行。
-
Xcode 模拟器 = OSX
标签: objective-c xcode macos