Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code to check if an external app exists without breaking the sandbox

I'm making an app and I would like to check if my computer has already installed an app (Example.app, com.example.test) and be able to send the app to the Mac App Store.

I tried several things, like:

NSString *script = @"try\r tell application \"Finder\" to get application file id \"com.example.test\"\r set appExists to true\r on error\r set appExists to false\r end try";
NSAppleEventDescriptor *result = [self executeScript:script];
return [result booleanValue];

This works perfectly, but I've been reading that Apple doesn't allow temporary exceptions for Finder in the entitlements file in order to keep the app secure.

I also tried something similar but avoiding the use of Finder:

NSString *script = @"set appID to id of application \"Example\"\r set msg to exists application id appID\r tell application \"Example\" to quit\r return msg";
NSAppleEventDescriptor *result = [self executeScript:script];
return [result booleanValue];

This works only if the user has the app, if not, it will prompt a dialog asking for the app location. (and shows the Example icon in the dock for a few milliseconds)

I also been trying some more hacky solutions like:

NSTask *task = [NSTask new];
[task setLaunchPath:@"/bin/bash"];
[task setArguments:@[@"if ls /Applications/Example.app >/dev/null 2>&1; then echo FOUND; else echo NOT FOUND; fi"]];
[task launch];
[task waitUntilExit];

int status = [task terminationStatus];

if (status == 0)
    NSLog(@"Task succeeded.");
else
    NSLog(@"Task failed.");

But the task always fails, I think command line stuff will never work (if so, nonsense sandboxing).

I've been thinking to put a button (checkbox), that prompts a dialog in order to select the path of the App, and check if the app name is equal to Example, if it is, check the checkbox, and uncheck if it's not. But I don't know how to prompt that dialog. (And I would like to avoid this solution if it's possible)

My questions are:

  • Is it possible to know if the app exists (without open it) following the rules of sandboxing?
  • Could I set Finder as a temporary exception and Apple will approve it? (Explaining what's the intention)

Thanks

like image 942
Javier Querol Avatar asked Jan 10 '23 00:01

Javier Querol


1 Answers

Have you tried the following using NSWorkspace?:

NSURL *appURL = [[NSWorkspace sharedWorkspace] 
               URLForApplicationWithBundleIdentifier:@"com.example.test"];

If the result is nil, you can consider that as Launch Services not "knowing about" the application, wherever it might be located, otherwise it will return the NSURL. (Launch Services, part of the CoreServices umbrella framework, is the framework that handles dealing with applications and document bindings). Using Launch Services is usually a better approach than checking at a specific path, since app bundles can be moved around the file system but still be present.

The AppleScript code you posted is probably about the equivalent of having the Finder call the code shown above: it's simply calling into Launch Services to find an app with that bundle identifier.

like image 159
NSGod Avatar answered Jan 23 '23 21:01

NSGod