Cocoa macOS 10.13:“;不再支持安排NSURLDOWLOAD加载程序。”;

Cocoa macOS 10.13:“;不再支持安排NSURLDOWLOAD加载程序。”;,cocoa,macos-high-sierra,Cocoa,Macos High Sierra,在macOS 10.13中运行我的macOS应用程序时,控制台上会显示: Scheduling the NSURLDownload loader is no longer supported. 这意味着什么?这似乎意味着您刚刚创建了一个不推荐使用的类NSURLDownload的实例 要显示这一点,请在Xcode中创建一个新的Cocoa命令行工具项目,并将main.m中的代码替换为以下代码: #import <Foundation/Foundation.h> int main(in

在macOS 10.13中运行我的macOS应用程序时,控制台上会显示:

Scheduling the NSURLDownload loader is no longer supported.
这意味着什么?

这似乎意味着您刚刚创建了一个不推荐使用的类NSURLDownload的实例

要显示这一点,请在Xcode中创建一个新的Cocoa命令行工具项目,并将main.m中的代码替换为以下代码:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSURL* url = [[NSURL alloc] initWithString:@"https://example.com"];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url                                                                        
                                                               cachePolicy:NSURLRequestReloadIgnoringCacheData
                                                           timeoutInterval:30.0];
        NSLog(@"Will print strange sentence to console") ;
        [[NSURLDownload alloc] initWithRequest:request
                                      delegate:nil];
        NSLog(@"Did print strange sentence to console") ;
    }
    return 0;
}
NSURLSessionDownloadTask *downloadTask = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL *location, __unused NSURLResponse *response, NSError *error) {

    if (location) {
        NSString *destinationFilename = NSTemporaryDirectory();
        if (destinationFilename) {
            // The file will not persist if not moved, Sparkle will remove it later. 
            destinationFilename = [destinationFilename stringByAppendingPathComponent:@"Appcast.xml"];

            NSFileManager *fileManager = [NSFileManager defaultManager];
            NSError *anError = nil;
            NSString *fromPath = [location path];
            if ([fileManager fileExistsAtPath:destinationFilename])
                [fileManager removeItemAtPath:destinationFilename error:&anError];
            BOOL fileCopied = [fileManager moveItemAtPath:fromPath toPath:destinationFilename error:&anError];
            if (fileCopied == NO) {
                [self reportError:anError];
            } else {
                self.downloadFilename = destinationFilename;

                dispatch_async(dispatch_get_main_queue(), ^{
                    [self downloadDidFinish:[[NSURLDownload alloc] init]];
                });
            }
        }
    } else {
            [self reportError:error];
    }
 }];

[downloadTask resume];

我认为“修复”是用NSURLSession替换不推荐的NSURLDownload。

Sparkle更新程序似乎是我发现的实例中的罪魁祸首。我想Sparkle开发团队会关注它,希望我们在Sparkle更新后不再看到该消息。

您可以在Sparkle的源代码中直接更正它。更新第82行的SUAppcast.m文件,将NSURLDownload替换为以下内容:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSURL* url = [[NSURL alloc] initWithString:@"https://example.com"];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url                                                                        
                                                               cachePolicy:NSURLRequestReloadIgnoringCacheData
                                                           timeoutInterval:30.0];
        NSLog(@"Will print strange sentence to console") ;
        [[NSURLDownload alloc] initWithRequest:request
                                      delegate:nil];
        NSLog(@"Did print strange sentence to console") ;
    }
    return 0;
}
NSURLSessionDownloadTask *downloadTask = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL *location, __unused NSURLResponse *response, NSError *error) {

    if (location) {
        NSString *destinationFilename = NSTemporaryDirectory();
        if (destinationFilename) {
            // The file will not persist if not moved, Sparkle will remove it later. 
            destinationFilename = [destinationFilename stringByAppendingPathComponent:@"Appcast.xml"];

            NSFileManager *fileManager = [NSFileManager defaultManager];
            NSError *anError = nil;
            NSString *fromPath = [location path];
            if ([fileManager fileExistsAtPath:destinationFilename])
                [fileManager removeItemAtPath:destinationFilename error:&anError];
            BOOL fileCopied = [fileManager moveItemAtPath:fromPath toPath:destinationFilename error:&anError];
            if (fileCopied == NO) {
                [self reportError:anError];
            } else {
                self.downloadFilename = destinationFilename;

                dispatch_async(dispatch_get_main_queue(), ^{
                    [self downloadDidFinish:[[NSURLDownload alloc] init]];
                });
            }
        }
    } else {
            [self reportError:error];
    }
 }];

[downloadTask resume];

如果有人有火花代码分叉,请使用我的答案的改进版本,并做更新推送请求。我的代码允许在不更改其他Sparkle方法的情况下直接替换,但最好清理旧的NSDownloadURL委托方法