I am trying to configure a custom scheme handler on macos from the command line to propose a reproducible procedure for other mac users.
I am open to any alternative way but here is an equivalent manual procedure which works for me:
- open "script editor" application
- Paste following code:
on open location this_URL
tell application "Terminal"
activate
do script "/tmp/my-custom-handler.sh '" & this_URL & "' ; exit"
end tell
end open location
- File > Save with
Save as: my-custom-handlerandFormat: Application
This will create a working my-custom-handler.app already usable by:
open -a my-custom-handler.app my-custom-handler://anexample?of=uri&with=parameter
We must notice that this application has a my-custom-handler.app/Contents/Info.plist file with CFBundleIdentifier set to com.apple.ScriptEditor.id.my-custom-handler.
- Now the last piece is to associate the desired scheme to this application identifier to avoid having to specify the
-aparameter toopencommand and let it automatically use the right application itself.
It is possible with the following command:
plutil -insert "LSHandlers.0" -json '{"LSHandlerPreferredVersions":{"LSHandlerRoleAll":"-"},"LSHandlerRoleAll":"com.apple.ScriptEditor.id.my-custom-handler","LSHandlerURLScheme":"my-custom-handler"}' ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
Notice it requires the application identifier ID
Now using simple following command works perfectly:
open my-custom-handler://anexample?of=uri&with=parameter
Ok cool now I want an automatic / command line way to do the same.
As you can see I already have the scheme association part using plutil.
So what I miss is an equivalent to Script Editor application save operation as Application from the command line.
Here is what I tested where my-custom-handler.applescript is a plain text file containing the program pasted to Script Editor in the manual procedure above:
osacompile -o my-custom-handler.app my-custom-handler.applescript
It works, I can again use:
open -a my-custom-handler.app my-custom-handler://anexample?of=uri&with=parameter
Notice it will ask for permission the first time it run as following:
But it works fine, the problem here is that application created from osacompile command does not have CFBundleIdentifier so it is basically impossible to set the association with our custom scheme using plutil as before ...
OK, not big a deal, I will simply edit the Info.plist file of my new application, it will be easy to automate with a command like sed to append:
<key>CFBundleIdentifier</key>
<string>org.toto.my-custom-handler</string>
Now I can use this identifier to associate my scheme using command:
plutil -insert "LSHandlers.0" -json '{"LSHandlerPreferredVersions":{"LSHandlerRoleAll":"-"},"LSHandlerRoleAll":"org.toto.my-custom-handler","LSHandlerURLScheme":"my-custom-handler"}' ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
But ... sadly as soon as I edit the Info.plist of my application, it does not work anymore at run, I see it try to open the application by nothing happen.
So in short term:
- I have a way to automate application creation using
osacompilebut it does not configure an identifier required for scheme association. - I have a way to automate scheme association but it requires an application with a proper identifier configured
- I cannot edit an application after its creation by either Script Editor or
osacompilebecause it breaks the application
I am sure my edit of the Info.pdlist is technically correct but I think that any change on the application involves security implication which make the application "broken". In fact the application probably still works but it does not ask to the user the confirmation to add the permission in System Settings > Privacy.
so I am stuck for now and one of the following could unlock the situation:
- tell to
osacompileto append an identifier (I did not see this ability in the manual..) - find a way to edit an existing app without to break it (probably because of security considerations)
- associate a scheme to an application without identifier (I don't think it is possible)
Sorry for the long description but here is all my knowledge, I confess I never used macos before yesterday so maybe I don't go in the right way, any advice is good to take, thank you.
EDIT: I am on MacOs Big Sure.
EDIT2: if we forget the "scheme" part and simplify the applescript to remove the event part like:
tell application "Terminal"
activate
do script "/tmp/my-custom-handler.sh '" & this_URL & "' ; exit"
end tell
I got a similar behavior:
- it works until I don't edit anything it the .app
- it does not work anymore when I edit the .app (to add the bundle identifier for example)
But this time, instead of a silence "nothing" at execution I got the error:
Not authorized to send Apple events to System Events
So my guess about a security protection which prevent edit of app files seems at least partially correct. hope it can help some macos experts :)
