安全范围内的书签-书签可解决,但仍无法访问文件 [英] Security Scoped Bookmark - bookmark resolves but still can't access the file

查看:193
本文介绍了安全范围内的书签-书签可解决,但仍无法访问文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在底部添加了其他信息

我有一个基于文档的沙盒应用程序,它将用户选择的QuickTime影片加载到AVPlayer中,并且一切运行正常.

I have a sandboxed, document based application that loads a user selected quicktime movie into an AVPlayer, and everything was working perfectly.

现在,我正在升级代码,以便它将使用Security Scoped书签来获取URL,而不仅仅是存储URL字符串,以便永久存储将允许在重新启动应用程序时加载影片.创建书签后,它将存储在托管对象的Data变量中.

Now I am upgrading the code so that it will use Security Scoped bookmarks to get the URL rather than just storing a URL string so that the persistent store will allow the movie to be loaded upon relaunch of the application. When the bookmark is created it is stored in a Data variable of a managed object.

由于某种原因,这破坏了AVPlayer.虽然我已经根据用户选择的URL创建了书签,并且可以在重新启动应用程序时从书签中解析URL,但是电影无法正确地加载到AVPlayer中,所以我不知道为什么...我已经确认从书签解析的URL确实指向电影文件.

For some reason, this has broken the AVPlayer. While I have created a bookmark from the user selected URL, and can resolving the URL from the bookmark when the application is relaunched, the movie is not getting loaded into the AVPlayer correctly and I can't figure out why... I have confirmed that the URL being resolved from the bookmark does point to the movie file.

我还为项目添加了适当的权利.

I have also added the appropriate entitlements to the project.

这是我的代码:

用户选择要加载的电影并创建书签的功能

 @IBAction func loadMovie(_ sender: Any) {

    let openPanel = NSOpenPanel()
    openPanel.title = "Select Video File To Import"
    openPanel.allowedFileTypes = ["mov", "avi", "mp4"]

    openPanel.begin { (result: NSApplication.ModalResponse) -> Void in
        if result == NSApplication.ModalResponse.OK {

            self.movieURL = openPanel.url
            self.player = AVPlayer.init(url: self.movieURL!)

            self.setupMovie()

            if self.loadedMovieDatabase.count > 0 {
                print("Movie Object Exists. Adding URL String")
                self.loadedMovieDatabase[0].urlString = String(describing: self.movieURL!)
            } else {
                print("No Movie Object Exists Yet.  Creating one and adding URL String")
                let document = NSDocumentController.shared.currentDocument as! NSPersistentDocument
                let myManagedObjectContext = document.managedObjectContext!
                let newMovie = NSEntityDescription.insertNewObject(forEntityName: "Movie", into: myManagedObjectContext) as! MovieMO
                self.loadedMovieDatabase.append(newMovie)
                self.loadedMovieDatabase[0].urlString = String(describing: self.movieURL!)
            }

            // create Security-Scoped bookmark - Added 2/1/18
            do {
                try self.loadedMovieDatabase[0].bookmark = (self.movieURL?.bookmarkData(options: NSURL.BookmarkCreationOptions.withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil))!
            } catch {
                print("Can't create security bookmark!")
            }

        }
    }

}

将书签解析为URL并加载电影的功能

       // initialize AVPlayer with URL stored in coreData movie object if it exists and is a valid path
    if loadedMovieDatabase.count > 0 {
        // initialize with saved movie path if it is valid (from security bookmark data)
        // let myURL = URL(string: loadedMovieDatabase[0].urlString!) <- replaced with new code below
        print("Loading URL from Bookmark")
        var urlResult = false
        var myURL : URL
        do {
            try myURL = URL.init(resolvingBookmarkData: loadedMovieDatabase[0].bookmark, bookmarkDataIsStale: &urlResult)!
            print("URL Loaded from Bookmark")
            print("URL is", myURL)
            let isSecuredURL = myURL.startAccessingSecurityScopedResource()
            print("IsSecured = ", isSecuredURL)
            player = AVPlayer.init(url: myURL)
            print("Setting Up Movie")
            setupMovie()
        } catch {
            // No Data in bookmark so load default ColorBars movie instead
            print("No Security Bookmark Available. Reverting to Default Color Bars")
            let myURL = URL(string: initialMoviePath)
            player = AVPlayer.init(url: myURL!)
            setupMovie()
        }
    } else {
        // load default ColorBars movie instead
        print("Nothing was loaded so just set up a new document.")
        let myURL = URL(string: initialMoviePath)
        player = AVPlayer.init(url: myURL!)
        setupMovie()
    }

我是安全性书签的新手,所以我希望这对以前使用过它们的人来说是显而易见的.

I am new to Security-Scoped Bookmarks, so I'm hoping that this may be obvious to anyone who has worked with them before.

我想知道是否是以下问题:

I'm wondering if it's a problem with:

let isSecuredURL = myURL.startAccessingSecurityScopedResource()

也许我打错了电话吗?有时我发现Apple的文档含糊不清,令人困惑……任何见解都将不胜感激!

Perhaps I'm calling this incorrectly? Sometimes I find Apple's documentation to be vague and confusing... Any insight would be appreciated!

我相信我知道为什么会这样,但是我不确定如何解决...

I believe I know why this is happening, but I'm not sure how to fix it...

myURL.startAccessingSecurityScopedResource()

根据文档总是返回FALSE ...,这意味着它不起作用.另外,当电影文件位于我的桌面上时,解析的URL出现如下(我不知道,这可能是正常的):

always returns FALSE... per the documentation that would mean that it's not working. Additionally, while the movie file is located on my Desktop, the Resolved URL comes up as the following (this may be normal, I don't know.):

file:///Users/me/Library/Containers/myapp/Data/Desktop/sample_on_desktop.mov

file:///Users/me/Library/Containers/myapp/Data/Desktop/sample_on_desktop.mov

苹果文档引用了以下事实:文档范围无法使用系统中的文件(又名"/Library"),但是我的权利设置为使用应用程序范围的书签,并且我的书签是使用nil创建的标记为relativeURL:所以这应该不是问题.

The apple docs make reference to the fact that a Document Scope can not use files in the system (aka "/Library"), but my entitlements are setup to use application-scope bookmarks, and my bookmark was created using the nil flag for relativeURL: so this shouldn't be an issue.

推荐答案

我偶然偶然发现了答案...

I just stumbled upon the answer accidentally...

对于初学者来说,当我解析URL时,我没有使用允许您包含OPTIONS的方法,因此我的URL是在没有安全范围的情况下解析的.我要解析的原始代码是:

For starters, when I was resolving the URL, I was not using the method which allows you to include OPTIONS, so my URL was resolved WITHOUT the security-scope. My original code to resolve was:

try myURL = URL.init(resolvingBookmarkData: loadedMovieDatabase[0].bookmark, bookmarkDataIsStable: &urlResult)!

当我应该在这里使用带有选项的版本时:

When I should have been using the version with options here:

try myURL = URL.init(resolvingBookmarkData: loadedMovieDatabase[0].bookmark, Options: URL.bookmarkResolutionOptions.withSecurityScope, relativeTo: nil, bookmarkDataIsStable: &urlResult)!

基本上,当我应该在列表的更下方查看时,我使用了预测列表中显示的第一个init选项Xcode,其单词为"resolvingBookmarkData:". (这就是我发现错误的方式.)

Basically, I used the first init option Xcode presented in the predictive list with the words "resolvingBookmarkData:" when I should have looked further down the list. (This is how I found my error.)

注意,使用它也很重要...

NOTE also that it's important to use...

URL.bookmarkResolutionOptions.withSecurityScope

不是

URL.bookmarkCreationOptions.withSecurityScope

...当您解析URL或它似乎无法正常工作时.

...when you're resolving your URL or it doesn't appear to work correctly.

因此,我结束了对这个问题的沮丧:)我希望这种解释可以帮助其他面对这个问题的人!

Thus ends my frustration with this problem :) I hope this explanation might help others facing this problem!

这篇关于安全范围内的书签-书签可解决,但仍无法访问文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆