Mac OS应用程序中用户所选文件夹的读写权限?

Sid*_*tre 2 macos cocoa swift

我正在开发MAC OS应用程序,它具有代表您创建文件的功能.第一个用户选择用于存储文件的文件夹(在应用程序启动时一次),然后用户可以使用苹果脚本选择要在所选文件夹上创建的文件的类型和名称(在应用程序启动时选择的文件夹).我可以创建文件,当我temporary-exception在权利文件中添加以下但它无法应用苹果审核团队但在沙盒中工作.

准则2.4.5(i) - 绩效我们已确定为此应用程序请求的一个或多个临时权利例外不合适且不会被授予:

com.apple.security.temporary-exception.files.home-relative-path.read-write
/FolderName/
Run Code Online (Sandbox Code Playgroud)

我发现 :

启用App Sandbox - 允许应用编写可执行文件.

启用用户选择的文件访问 - Xcode在目标编辑器的"摘要"选项卡中提供了一个弹出菜单,其中包含对用户明确选择的文件和文件夹进行只读或读/写访问的选项.当您启用用户选择的文件访问权限时,您可以以编程方式访问用户使用NSOpenPanel对象打开的文件和文件夹,以及用户使用对象保存的文件NSSavePanel.

使用以下代码创建文件:

let str = "Super long string here"
let filename = getDocumentsDirectory().appendingPathComponent("/xyz/output.txt")

do {
    try str.write(to: filename, atomically: true, encoding: String.Encoding.utf8)
} catch {
    // failed to write file – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding
}
Run Code Online (Sandbox Code Playgroud)

还尝试com.apple.security.files.user-selected.read-write在NSOpenPanel对象中添加授权文件:

<key>com.apple.security.files.user-selected.read-write</key>
<true/>
Run Code Online (Sandbox Code Playgroud)

有没有办法通过苹果审查小组批准Mac App对用户选择的文件夹具有读写权限?

Sid*_*tre 7

这是我的答案如何在Mac OS应用程序中实现并持久保存用户所选文件夹的读写权限?

GitHub示例项目链接

第一:

在权利文件中添加user-selectedbookmarks.app权限:

<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
Run Code Online (Sandbox Code Playgroud)

然后我为存储,加载...等书签应用程序所需的所有书签相关功能创建了类.

import Foundation
import Cocoa

var bookmarks = [URL: Data]()

func openFolderSelection() -> URL?
{
    let openPanel = NSOpenPanel()
    openPanel.allowsMultipleSelection = false
    openPanel.canChooseDirectories = true
    openPanel.canCreateDirectories = true
    openPanel.canChooseFiles = false
    openPanel.begin
        { (result) -> Void in
            if result.rawValue == NSApplication.ModalResponse.OK.rawValue
            {
                let url = openPanel.url
                storeFolderInBookmark(url: url!)
            }
    }
    return openPanel.url
}

func saveBookmarksData()
{
    let path = getBookmarkPath()
    NSKeyedArchiver.archiveRootObject(bookmarks, toFile: path)
}

func storeFolderInBookmark(url: URL)
{
    do
    {
        let data = try url.bookmarkData(options: NSURL.BookmarkCreationOptions.withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
        bookmarks[url] = data
    }
    catch
    {
        Swift.print ("Error storing bookmarks")
    }

}

func getBookmarkPath() -> String
{
    var url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
    url = url.appendingPathComponent("Bookmarks.dict")
    return url.path
}

func loadBookmarks()
{
    let path = getBookmarkPath()
    bookmarks = NSKeyedUnarchiver.unarchiveObject(withFile: path) as! [URL: Data]
    for bookmark in bookmarks
    {
        restoreBookmark(bookmark)
    }
}



func restoreBookmark(_ bookmark: (key: URL, value: Data))
{
    let restoredUrl: URL?
    var isStale = false

    Swift.print ("Restoring \(bookmark.key)")
    do
    {
        restoredUrl = try URL.init(resolvingBookmarkData: bookmark.value, options: NSURL.BookmarkResolutionOptions.withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
    }
    catch
    {
        Swift.print ("Error restoring bookmarks")
        restoredUrl = nil
    }

    if let url = restoredUrl
    {
        if isStale
        {
            Swift.print ("URL is stale")
        }
        else
        {
            if !url.startAccessingSecurityScopedResource()
            {
                Swift.print ("Couldn't access: \(url.path)")
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后使用打开文件夹选择,NSOpenPanel以便用户可以选择允许您访问的文件夹.在NSOpenPanel必须存储为一个书签,保存到磁盘.然后,您的应用将具有与用户选择文件夹时相同的访问级别.

打开NSOpenPanel:

let selectedURL = openFolderSelection()
saveBookmarksData()
Run Code Online (Sandbox Code Playgroud)

并在应用关闭后加载现有书签:

loadBookmarks()
Run Code Online (Sandbox Code Playgroud)

而已.我希望它会帮助某人.


小智 6

权限文件中的添加user-selectedbookmarks.app权限:

<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
Run Code Online (Sandbox Code Playgroud)

然后使用打开文件夹选择,NSOpenPanel以便用户可以选择要访问的文件夹。在NSOpenPanel必须存储为一个书签,保存到磁盘。然后,您的应用程序将具有与用户选择文件夹时相同的访问级别。