gpt4 book ai didi

macos - 应用程序扩展中的安全范围书签

转载 作者:行者123 更新时间:2023-12-03 16:19:28 29 4
gpt4 key购买 nike

我正在创建一个 TodayWidget 应用程序扩展,它显示有关用户在应用程序目录之外选择的文件夹的信息。

在我的主应用程序中,我可以通过 NSOpenPanel 使用 powerbox 来选择文件夹。然后,我可以将安全范围的书签保存到可通过 TodayWidget 访问的应用程序组容器的用户默认值。

TodayWidget 可以读入书签数据,但是当它调用 URLByResolvingBookmarkData 时,会出错:

无法打开该文件,因为它的格式不正确。

我的主应用程序和 TodayWidget 都具有以下权利:

  • com.apple.security.files.bookmarks.app-scope
  • com.apple.security.files.user-selected.read-only

根据 Apple 的文档,只有创建安全范围书签的应用程序才能使用它。我想这意味着不允许嵌入应用程序?

我已经考虑过使用 XPC,但这并不能真正解决问题,因为 XPC 也不能使用安全范围的书签,只能使用普通书签。一旦计算机重新启动,XPC 进程将失去对目录的访问权限。

我真正需要的是一种让 XPC 进程获得对用户指定目录的读取访问权限的方法。有没有办法不必每次重新启动计算机都重新启动我的主应用程序?

最佳答案

您可能已经解决了这个问题或继续前进。但对于所有正在尝试类似事情的人,我会将其留在这里给他们。为了在不同的应用程序中访问安全范围的书签,必须将它们作为 NSData 传输并在其他应用程序中重新解析。

在我的例子中,我在主应用程序中显示一个打开的对话框,然后将范围书签保存到共享的 NSUserDefaults 套件中。其他应用程序也是该套件的一部分,然后访问 NSData 的容器并将它们解析为可用的 NSURL

以下是相关代码:

//Inside my main application's open function 
... get url from NSOpenPanel
BookmarkUtils.saveURLForOtherApplications(openPanel.URL!)


//Inside BookmarkUtils.swift
static func saveURLForOtherApplications(url:NSURL)->Bool{
let defaults = NSUserDefaults(suiteName: <#Suite-Name#>)!
//I store them as a dictionary of path->encoded URL
let sandboxedBookmarks:NSMutableDictionary
if let prevBookmarks = defaults.objectForKey(kSandboxKey) as? NSDictionary{
sandboxedBookmarks = NSMutableDictionary(dictionary:prevBookmarks)
}
else{
sandboxedBookmarks = NSMutableDictionary()
}
if let shareData = BookmarkUtils.transportDataForSecureFileURL(url){
sandboxedBookmarks.setObject(shareData, forKey:url.path!)
defaults.setObject(sandboxedBookmarks, forKey:kSandboxKey)
defaults.synchronize()
return true
}
else{
println("Failed to save URL Data");
return false
}
}

static func transportDataForSecureFileURL(fileURL:NSURL)->NSData?{
// use normal bookmark for encoding security-scoped URLs for transport between applications
var error:NSError? = nil
if let data = fileURL.bookmarkDataWithOptions(NSURLBookmarkCreationOptions.allZeros, includingResourceValuesForKeys:nil, relativeToURL:nil, error:&error){
return data;
}
else{
println("Error creating transport data!\(error)")
return nil
}
}

然后在我的扩展中(在我的例子中是“今日 View ”)我做了这样的事情......

class TodayViewController: ...
...
override func viewDidLoad() {
super.viewDidLoad()

var status = [MyCoolObjects]()
for url in BookmarkUtils.sharedURLSFromApp(){
BookmarkUtils.startAccessingSecureFileURL(url)
status.append(statusOfURL(url))
BookmarkUtils.stopAccessingSecureFileURL(url)
}

self.listViewController.contents = status
}

相关书签看起来像:

static func sharedURLSFromApp()->[NSURL]{
var urls = [NSURL]()
if let defaults = NSUserDefaults(suiteName: <#Suite-Name#>){
if let prevBookmarks = defaults.objectForKey(kSandboxKey) as? NSDictionary{
for key in prevBookmarks.allKeys{
if let transportData = prevBookmarks[key as! NSString] as? NSData{
if let url = secureFileURLFromTransportData(transportData){
urls.append(url)
}
}
}
}
}
return urls
}



static func secureFileURLFromTransportData(data:NSData)->NSURL?{
// use normal bookmark for decoding security-scoped URLs received from another application
var bookmarkIsStale:ObjCBool = false;
var error:NSError? = nil;
if let fileURL = NSURL(byResolvingBookmarkData: data, options: NSURLBookmarkResolutionOptions.WithoutUI, relativeToURL: nil, bookmarkDataIsStale: &bookmarkIsStale, error: &error){
return fileURL
}
else if(bookmarkIsStale){
println("Bookmark was stale....")
}
else if let resolveError = error{
println("Error resolving from transport data:\(resolveError)")
}
return nil
}

这个解决方案适合我。一旦您解析了共享 URL,您就可以为该应用程序创建一个书签,并在需要时保存它以供以后使用。可能有更好的方法,希望 Apple 能够解决这个问题,因为目前与扩展程序共享权限很痛苦。

关于macos - 应用程序扩展中的安全范围书签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28998935/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com