NSWorkspace openURL: fails on file:// URL but not https:// URL

I have a shipping Sandbox'd App that saves a thumbnail of an image if the user add's it to the App. It

also saves the original URL to that image with the thumbnail for reference later on.


If the user then later wants to "look" at the original image, I do:

[[NSWorkspace sharedWorkspace] openURL:photoURL]

which has worked in the past. Now it only half works in that, if the original image

came from an eg: http(s):// URL, the openURL will launch Safari with that URL. But if

the original image came from a file:// URL, it no longer launches eg: Preview or

the default Application for that file type, and instead fails and pops up a message

on my App saying "The application "<MyApp>" does not have permission to open

<imagename>.png".


(I checked and "

URLForApplicationToOpenURL:" returns Preview for

the default Application for the file. I also checked and no "error" messages show up

in the Console)


I don't have, and don't want, access to the original file in my App. I just

want to launch whatever viewer Application the user has configured.


Did something change security wise to make this feature impossible now?

Replies

Have you tried openFile:?

which has worked in the past.

What is “the past” in this context? Is this something broken by macOS 10.14?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

> Have you tried openFile:?


Yes, same result. openFile:[photoURL path] also fails

> What is “the past” in this context? Is this something broken by macOS 10.14?


(Good point). Unfortunately, I don't know exactly :-( The majority of the links are https: and so I test that

and have assumed the entire functionality worked and didn't differentiate URL's. So right now it's 10.13.6

and I know it's worked at somepoint in previous macOS versions going back to 10.9.

I'm going to test 10.14 now ....

Janice

Can you clarify what you mean by "PhotoURL"? If you save a photo to the desktop and use that URL, does it work?


Or are you talking about a URL to a file inside the "Photos" app? Or is this a URL to any file that might be in a location that is now protected with Mojave's "Full Disk Access"?


I see your other reply about 10.13. But I still want you to clarify exactly where these URLs are. There could still be special system behaviour with certain directories. Or perhaps these URLs are in a folder that has the quarantine bit set.

> Can you clarify what you mean by "PhotoURL"? If you save a photo to the desktop and use that URL, does it work?


Yes, that is what I mean and No, it doesn't work.


> Or are you talking about a URL to a file inside the "Photos" app? Or is this a URL to any file that might be in a location that is now protected with Mojave's "Full Disk Access"?


No, not inside the Photos App. It uses Promised/Temporary files so no URL's are used/saved/available. And No not Mojave. Haven't tested that feature yet.

Double-check the permission of the files and containing folders. Try it in a clean install.


I have seen a similar problem trying to open documents. It seems as if Gatekeeper kicks in and prevents opening the document. But I can drag the document to an app and open it.


Do you have any problems opening these documents via a double-click in the Finder? What about opening them with the designated app and a File > Open dialog?


That's all I have. Maybe keep Console running when you try it again. If you can't reproduce it in a pristine environment, it could be just some kind of system cache corruption.

I don't know exactly :-(

Bummer. Let us know how your latest tests work out.

ps I deal with problems like this by maintaining a selection of virtual machines, one for each major macOS release. That way I can quickly go back in time until I see a change in behaviour.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

> Let us know how your latest tests work out.


As expected, the same thing happens with 10.14 as 10.13. But what I did figure out is that, when the photo is first dragged into my Application (and I make the thumbnail), for the entire rest of that session with my App, the "[[NSWorkspace sharedWorkspace] openURL:photoURL]" will work and *will* launch Preview. So access to that file has temporarily been added to my Sandbox when the user add's it. But if I Quit and then restart my App again, the openURL: with the exact same URL will fail as access to that file is no longer part of my Sandbox. (Because I didn't do the security work to have access to it later ....)


Which is really the basis of my question - is this a bug or a security feature? (Again, for file:// URL's only ... http:// URL's launches a browser just fine)


> ps I deal with problems like this by maintaining a selection of virtual machines, one for each major macOS release.


I do have "clone's" on external drives for major releases ....


Janice

> Do you have any problems opening these documents via a double-click in the Finder? What about opening them with the designated app and a File > Open dialog?


No problem - double clicking the file open's Preview just fine.


> That's all I have. Maybe keep Console running when you try it again. If you can't reproduce it in a pristine environment, it could be just some kind of system cache corruption.


I've kept eagle eye's on the Console message and have seen nothing go by that is relevant.


Looks like it is just a security related issue.

You can always create a database of security scoped bookmarks. In recent years I have found blunt force to be one of the more effective strategies for getting things to work on a Mac.


You could try calling the "open" command-line tool via NSTask and see if that behaves any better. eskimo will probably scold me for making such a suggestions. It is easy to be a stickler for using proper APIs and filing enhancement requests when you have access to the source code and don't have to worry about App Review or the sandbox.


I would not recommend using virtual machines for testing. I have found them adequate for Developer ID apps. But the Mac App Store adds something special that VMs can't handle. I haven't been able to reliably use a Mac App Store app with an iTunes sandbox user in a VM.


I wouldn't suggest using "clones" or external drives either. There are some very subtle complications when using modern Apple services like iCloud, iMessage, and Handoff with a clone or even a copied home directory. And there are a whole set of different complications with iCloud and other low-level issues when booting from an external drive or any kind of multi-boot environment. Just buy some cheap Macs, set them up from scratch, and configure user accounts using iCloud only.


And finally, this may have helped if you had known it. There is no such things as major and minor releases anymore. The only difference is how they are marketed. Anything can and will break in any release, no matter how "minor". You have access to all beta builds. Use them. Depending on your app, it can take up to a month or more to get an updated build past App Review. So as soon as you find a problem with 10.14.1 (or any subsequent build), you have to implement a workaround and submit right away.

> You can always create a database of security scoped bookmarks. In recent years I have found blunt force to be one

> of the more effective strategies for getting things to work on a Mac.


Hmmm. That would be unfortunate. I think I would just rather not offer the feature to end users. I can put off the decision for a while yet. Hope to hear from Apple (aka Quinn) as to whether it's a bug or a feature before deciding.


Ping?

Hope to hear from Apple (aka Quinn) as to whether it's a bug or a feature before deciding.

If you want a definitive answer to that you should open a DTS tech support incident and talk to one of my colleagues (partly because I’m on vacation right now, but mostly because the subtleties of the App Sandbox isn’t really my specialism).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

janice wrote:


whether it's a bug or a feature before deciding.

Does that matter? It is observed behaviour. Even if this isn't by design, I doubt that 10.13 is ever going to be updated with a fix. 10.14 might be updated, but it will probably take one or two more minor revisions.


I think there is a distinct possibility that "open" will work. You don't need to do any fancy interaction with it, so it would be easy to code and test. I usually do need some type of fancy interaction, so I don't normally do this, but you might even try the system() call for something this simple.

> Does that matter? It is observed behaviour. Even if this isn't by design, I doubt that 10.13 is ever

> going to be updated with a fix. 10.14 might be updated, but it will probably take one or two more minor revisions.


Yes it does matter. Enquiring minds want to know! But it will also inform future application design decisions. If

this is something that is "not allowed" anymore, then I want to know that so that I can set my expectations appropriately.

But I'm not going to **** a DTS request on it - it's not worth it.


> I think there is a distinct possibility that "open" will work. You don't need to do any fancy interaction with it, so

> it would be easy to code and test. I usually do need some type of fancy interaction, so I don't normally do this,

> but you might even try the system() call for something this simple.


This does not work:

  NSString *toolPath = @"/usr/bin/open";
  NSMutableArray *arguments = [NSMutableArray arrayWithCapacity:1];
  [arguments addObject:@"/Users/xxxxx/Pictures/smartpro.png"];

  NSTask *task = [[NSTask alloc] init];
  [task setLaunchPath:toolPath];
  [task setArguments:arguments];

  [task launch];
  [task waitUntilExit];

  int status = [task terminationStatus];
  NSLog(@"status=%d", status);
  [task release];


Where the "xxxxx" is my username. I get in the XCode debug console:

LSOpenURLsWithRole() failed with error -54 for the file /Users/xxxxx/Pictures/smartpro.png


With -54 as a permission error. So I'm pretty convinced now that this is a Sandbox violation and will be difficult to

workaround if at all and will at least cause me future headaches. Instead I have decided to just open a Finder window

with the file/URL selected. It's actually working, but I still get in the XCode console:


[sandbox] Sandbox extension creation failed: client lacks entitlements? for path: [/Users/xxxxx/Pictures/smartpro.png]
[general] Sandbox extension data required immediately for flavor public.file-url, but failed to obtain.

So even that may cause me future problems and I'll have to keep an eye on it.