如何将下载的文件(音频、文档)自动保存到 mac os x 沙盒应用程序中用户的下载文件夹?

How to save downloaded files(audio, doc) automatically to user's Downloads folder in mac os x sandboxed application?

在我的 Mac OS X 应用程序中,我试图将下载的文件保存到应用程序的目录(即 HomeDirectory()/Documents),但 App Store 拒绝了我的应用程序,说您下载的文件不可访问轻松地向用户提供(即无需打开应用程序)。然后我尝试通过在权利中添加 Read/Write 权限将下载的文件写入 ~/Downloads 文件夹,但 App Store 再次拒绝该应用程序说

Your application accesses the following location(s):

~/Download

The majority of developers encountering this issue are opening files in Read/Write mode instead of Read-Only mode, in which case it should be changed to Read-Only.

Other common reasons for this issue include:

  • creating or writing files in the above location(s), which are not valid locations for files to be written as stated in documentation.

  • writing to the above location(s) without using a valid app-id as a container for the written files.

现在的问题是 App Store 既不允许我将文件保存在应用程序的目录中,也不允许我将文件保存在系统的文件夹中(即下载)。我也不想每次都使用 NSSavePanel。我想静默下载文件。我应该在哪里保存我的文件?

在安全范围书签、用户selected 读写权限和 NSOpenPanel 的帮助下,我能够read/write 到用户 selected 文件夹。

以下是我遵循的步骤,

  1. 已添加

    <key>com.apple.security.app-sandbox</key>
    <true/>
    
    <key>com.apple.security.files.bookmarks.app-scope</key>
    <true/>
    
    <key>com.apple.security.files.user-selected.read-write</key>
    <true/>
    

    在权利文件中。

  2. 要求用户使用 NSOpenPanel select(或创建并 select)我的应用程序想要访问的所需文件夹(read/write)。

  3. 当用户 selects 文件夹时,我使用 NSURLBookmarkCreationWithSecurityScope 在 NSUserDefaults 中创建了 selected 文件夹路径的书签作为书签路径。

    NSOpenPanel *openDlg = [NSOpenPanel openPanel];
    
    [openDlg setCanChooseDirectories:YES];
    
    [openDlg setCanCreateDirectories:YES];
    
    [openDlg setAllowsMultipleSelection:FALSE];
    
    [openDlg setPrompt:@"Select"];
    
    if ( [openDlg runModal] == NSModalResponseOK )
    {
    
        NSURL *url = openDlg.URL;
    
        NSError *error = nil;
    
        NSData *bookmark = [url 
                      bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                      includingResourceValuesForKeys:nil
                                  relativeToURL:nil
                                          error:&error];
    
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    
        [userDefaults setObject:bookmark forKey:@"DOWNLOAD_FOLDER_BOOKMARK_PATH"];
    
        [userDefaults synchronize];
    
    }
    
  4. 在 NSUserDefaults 中保存了已添加书签的路径后,您可以稍后使用 NSURLBookmarkResolutionWithSecurityScope 访问已保存的路径。

     NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    
     NSData * bookmarkedPathData = [userDefaults objectForKey:@"DOWNLOAD_FOLDER_BOOKMARK_PATH"];
    
     NSURL* urlFromBookmark = [NSURL URLByResolvingBookmarkData:bookmarkedPathData 
     options:NSURLBookmarkResolutionWithSecurityScope
                                                     relativeToURL:nil
                                               bookmarkDataIsStale:nil
                                                             error:&error];
    
  5. 一旦你得到保存的书签 URL 你就可以使用那个 URL 来执行读写操作。在 reading/writing from/to 和 URL 之前,请使用 [urlFromBookmark startAccessingSecurityScopedResource]; 启动范围。完成 read/write 操作后,使用 [saveFolder stopAccessingSecurityScopedResource];

  6. 停止作用域

注意:我曾尝试直接写入文档、下载、桌面而不在这些目录中创建文件夹,但 Apple 拒绝了该应用程序,说

Your application access the following locations 'Downloads'.

然后我没有直接写入这些目录(Documents、Downloads、Desktop),而是要求用户 select(创建 & select)一个文件夹,然后执行 read/write 使用 Security-Scope-Bookmark 对用户 selected 文件夹的操作。

希望这对某人有所帮助。