WKWebKit loading / sandbox woes

Having issue with loading local content in a sandbox sample - AppSandBoxQuickStart; specifically once a file - via open panel or drag-n-drop does nothing, i.e., `AppDelegate.swift OpenURLInNewWindow(:URL,parent:NSWindow?)->Bool`;


if url.isFileURL {
    if appDelegate.isSandboxed() != appDelegate.storeBookmark(url: url) {
        Swift.print("Yoink, unable to sandbox file \(url)")
    }

    let baseURL = url.deletingLastPathComponent()
    if isSandboxed() != storeBookmark(url: baseURL) {
        Swift.print("Yoink, unable to sandbox \(baseURL)")
    }
    webView.loadFileURL(url, allowingReadAccessTo: baseURL)
}
else
{
    webView.load(URLRequest.init(url: url))
}


Three quesitons here

  1. if the accessReadURL is supplied - base URL, is that not requried to be bookmarked as well? It seems to fail cites the enclosing directory is not found. It would seem required for local html files so loading a request is not a solution, nor does it work.
  2. either load function yields no content in the webView indicating a sandbox issue
  3. a file drag-n-drop onto the app's view should also require a bookmark, and its base, but when an alias, I had read that the actual url 'instance' provided should be used, so attempting to resolve the alias would be problematic


Of course if I turn off sandbox all smiles, but then this is a test case for an app submission.

Obviously, if you select an individual file in an NSOpenPanel, you don't have full access to the containing folder.


I don't really understand what you are asking in parts 2) and 3).


There is no problem with web views from the sandbox. But in most cases, web views are opening remote content or bundled content. A sandboxed app will always have problems with any data that could involve an unstructured directory. There is no way to know where or what associated files might need to be read. Your only option here is to select an entire directory.

Thanks for the quick reply; I suspect my storeBookmark() isn't working? I'd appreciate if you could comment specifically but it mimics or identical to other samples I've read.


#2 is related to the #1; my sandbox bookmark function is not working:


  func storeBookmark(url: URL, options: URL.BookmarkCreationOptions = [.withSecurityScope,.securityScopeAllowOnlyReadAccess]) -> Bool
  {
      guard isSandboxed() else { return false }

  //  Peek to see if we've seen this key before
      if let data = bookmarks[url] {
          if self.fetchBookmark((key: url, value: data)) {
              Swift.print ("= \(url.absoluteString)")
              return true
          }
      }
      do
      {
         let data = try url.bookmarkData(options: options, includingResourceValuesForKeys: nil, relativeTo: nil)
         bookmarks[url] = data
         return self.fetchBookmark((key: url, value: data))
      }
      catch let error
      {
         NSApp.presentError(error)
         Swift.print ("Error storing bookmark: \(url)")
         return false
      }
  }

#3, I'm concerned what I get from the pasteboard is currently a string not a URL? so fabricating one I wasn't sure was 'bonafide' as one from open/save? I had read a comment you want to use such dialog urls "as-is". I suspect I need to have such a URL from the pasteboard not my fabrication.


I totally agree with your commmentary re: unstructured directories; I want to localize as much as possible where they're going.


The best I think of is the reason I took to trying to bookmark the enclosing directory. This however throws a file not found dialog on the diretory - as a file (?), so again I suspect my `storeBookmark()` is at fault as I'm suspecting something should be different when the URL is directory.

If all of this is coming from an NSOpenPanel, you don't need to do anything with bookmarks at all. The same is true for drag-n-drop. Just use the URLs that the open panel gives you.


If you want to persist these bookmarks, then you have have to save them and restore them later. However, you can only save and restore something that you have been given. You can't just strip off the last path component.


I don't think you do understand what I'm saying. I'm saying your project is probably not viable. You can open an index.html file in an NSOpenPanel. But if that index.html file references 3 css files, 6 js files, and 114 images, you'll need to display NSOpenPanel 123 separate times to get the other files. Or you can just get the parent directory and use that. However, that can be awkward because end users may not understand about selecting a directory instead of a file.

Ah, yeah, I fully understand what you're saying; btw I'd fixed (not posted yet) my store issue leaving only this "html" issue to deal with; a current nit, IMHO. <SoapBox> in the current implementation of loadFileURL() the accessReadURL should be dealing with this right out of the api; can't otherwise imagine its use, so this is in essence a temporary workaround (I'd be glad to tear out when possible).


Yes, the URLs are coming from open panel or drags; yes they're URL's ready to eat, but as a doc based app whose contents would be sourced by these URLs, how else - other than save/restore would document restoration work? I would rather be cautious than not, but not to the extent of 123 etc dialogs, just a single; if there's content outside of that, that too bad.


So, while chasing down each and every bit from an .html is not workable, I wanted to attempt present 1 and one 1 extra iFF html content is found - uti query for the 'accessReadURL'.


Hopefully this isn't too much of a hassle, but in presenting the 2nd dialog, is there no way to just have the user confirm the base URL via a new open panel - maybe via an acessory panel if I establish a delegate?


if url.isFileURL {
  var baseURL = url

  // make them authorize the entire directory
  if isSandboxed(), url.hasHTMLContent() {
    let openPanel = NSOpenPanel()

    openPanel.message = "Authorize access to " + baseURL.lastPathComponent
    openPanel.prompt = "Authorize"
    openPanel.allowsMultipleSelection = false
    openPanel.canChooseFiles = false
    openPanel.canChooseDirectories = true
    openPanel.canCreateDirectories = false
    openPanel.directoryURL = baseURL.deletingLastPathComponent()

    openPanel.begin() { (result) -> Void in
    if (result == NSApplication.ModalResponse.OK) {
      if let authURL = openPanel.url {
        if self.storeBookmark(url: authURL) {
          baseuRL = authURL
        } else {
          Swift.print("Yoink, unable to sandbox base \(authURL)")
        }
      }
    }
  }
}
///webView.load(URLRequest.init(url: url))
webView.loadFileURL(url, allowingReadAccessTo: baseURL)



I've seen apps request this sort of affirmation and I think if similar re: this folder authenication, that might be the way to go; otherwise these html will have to be rendered assetless.

WKWebKit loading / sandbox woes
 
 
Q