Not authorised to send Apple Events to Finder from helper bundle - macos

I'm having issues with executing AppleScript from the application helper bundle, which is contained in my main application bundle.
I have a simple helper application bundle which only loads my script located in helpers' bundle Resources using NSAppleScript API and executes it. Script is really simple, it basically just deletes some other application bundle. I've tested the script as standalone and everything works fine. When I run the helper bundle everything falls apart. I'm getting -1743 error (Not authorised to send Apple Events to Finder). My helper bundle is not sandboxed, has enabled apple events in the entitlements file and I've added NSAppleEventsUsageDescription key to the plist. If I run this from Xcode it works, same if I execute the binary contained in the bundle from command line.
Any ideas what might be causing the issue?

I've managed to solve the problem by adding NSAppleEventsUsageDescription key to all Info.plist files up the bundle hierarchy.

Related

Associate App with Messages Extension

I created a Messages Extension in Xcode 8 using the appropriate template, that seems to be working fine and when I run the extension, it's installed in the Messages app and I can use it without any issues.
My problem is that I wanted to create an actual app to be associated with this extension (so that the user would be able to search the extension through the Messages Store or install the actual app through the App Store). I gave it a matching bundle identifier (my extension is com.XXX.testmessage.MessagesExtension, so for the app I set com.XXX.testmessage), but when I run the app, it doesn't install the extension.
Is it possible to do that? And if so, what am I missing?
In XCode8, open your existing app. Then you need to add a new target to your app (File->New->Target->iOS->Sticker Pack Extension (or an iMessage Extension if you want a custom messages experience)). It will then create a folder visible in Project Navigator. The name of the folder depends on the name you gave to the extension. In that folder you will find a Stickers.xcassets where you can drop your stickers.

Create installer that runs application on login

I have spent more time on this task than I did actually creating the application.
I want to create an installer for my app that will:
Install the app into /Applications
Make the application launch on boot (it's just a menu bar status based app)
Number 1 is easy but I can get absolutely nowhere with getting #2 to work. I know I need to setup a postscript install somewhere I don't know how to make the script (I believe I need to put it in loginitems) and how to make it initialize as part of the package. My understandign from research is I need to look into making a postflight script but there is nothing at all in Package Manager for that.
Can someone please point me to something that works in 10.6+?
I've tried the script here in Add app to OSX "Login Items" during a Package Maker installer postflight script but it doesn't really explain where/how to actually add the script.
Launch at login can be a piece of cake or an absolute nightmare depending on wether or not your app is sandboxed. If it isn't sandboxed, then you can use LSSharedFileList to modify the login items preference pane: https://github.com/Mozketo/LaunchAtLoginController
If it is sandboxed then you're going to need to create a helper app: http://blog.timschroeder.net/2012/07/03/the-launch-at-login-sandbox-project/
The above tutorial didn't work for me on yosemite, I had to follow apple's sample code: https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLoginItems.html#//apple_ref/doc/uid/10000172i-SW5-SW1
As for the installer, check this answer here: https://stackoverflow.com/a/11487658/1320911

Set environment variable for the process before startup

I have the following situation:
I have Mac OS bundle with application which uses some 3rd party dynamic libraries and those libraries depend on some environment variable, let's name it ENV_VAR. I want to set ENV_VAR to some value for my application only because if I set it for the whole system it may breaks some other apps. And it should work transparently to the user i.e. he just run my app from the Application folder by double clicking it. How can I achieve it?
NOTE: dynamic libraries are loaded before main functions starts hence setting this variable in the main doesn't help.
You can add a key "LSEnvironment" to your app bundle's Info.plist. The value can be a dictionary with strings for keys and values and those key-value pairs will be added to the environment when your app is launched by Launch Services (e.g. from the Finder or Dock but not from the Terminal).
<key>LSEnvironment</key>
<dict>
<key>ENV_VAR</key>
<string>value</string>
</dict>
However, in my testing (on Snow Leopard), it was a bit flaky to test, at least when editing the Info.plist of an existing app. Basically, Launch Services caches this part of the app's Info.plist when it first encounters the app and won't necessarily recognize changes on disk. You can sometimes prompt it to reread the Info.plist by, for example, duplicating the app bundle or temporarily moving it to a different folder. Of course, the overkill solution would be to use lsregister to flush and rebuild the cache:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -seed
This caching issue won't affect your end users, just you as you tweak the Info.plist. Also, it shouldn't affect you if you make the change in your source Info.plist and then build the app using Xcode.
I am not sure if the following works because I don't have such an app to try. The idea is to set the environment variable from the terminal, then call your application:
ENV_VAR=something open -a YourApplication

Launch Service register application bundle

I have some internal application bundles inside my main application bundle (in Resources). After installing (with Installer), my application is placed in /Applications, but I can't find my "internal" application by their bundle ids.
If I manually go to the /Applications, select my application and navigate to its content in Finder, my "internal" application became visible.
I know that lsregister is responsible to register application bundles, I have this script in my postflight in pkg:
SREGISTER="/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister"
$LSREGISTER "/Applications/MY.app/Contents/Resources/MyMini.app"
But I need administration privileges in my installer, that's why this command is executed by root and does no effect to current user.
Is there any solution for this problem?
Thanks!
You could register your helper apps the first time your main app runs, rather than during installation. You'll need to find them by name and location rather than bundle ID. And instead of using the lsregister tool, you can use the LSRegisterURL function. Remember that an NSURL* can be cast to a CFURLRef by toll-free bridging.
It seems that there is no solution for this. Because I need to run the lsreginster for every user of the system, and newly created users after the installation will not see this helpers app.
The only way is put this application outside the main bundle (in subdirectory of the /Applications for example)

Remove Sandboxing

I have another question dealing with app sandboxing. So I need access to the users' home directory and at the same time the app should be able to shut down the Mac. This requires to not using sandboxing.
My problem is that I don't know how to remove sandboxing and being able to submit the app to the Mac App Store. I think that the archives are sandboxed because I had turned it on once..
How to remove sandboxing from the archives properly?
Thanks for your help!
On Xcode 11, you can turn off Sandboxing by removing it from the Signing & Capabilities tab:
If I understand what you are asking correctly, you'll need to remove the entitlements.plist from your project and make sure that the Summary view of your target in Xcode has sandboxing turned off:
As Derek Wade pointed out, you can make an App like GarageBand X (which behaves obnoxiously with third party plugins like Amplitube due to Sandboxing) NOT run in a sandbox by editing the binary itself with a HEX editor like HexFiend. Look for:
<key>com.apple.security.app-sandbox</key>
Immediately following that bit you'll see the true tag, which as suggested I switched to 'fals' (no extra bytes) and now GarageBand will happily interact with third party VST plugins. Huzzah.
I found if you go into the .app package, under Contents/MacOS, there should be a binary file that matches the name of your app. Copy that file to your desktop. Edit the desktop copy of the file with TextEdit. You should find within the file, the text representation (xml) of the Entitlements for the app. Find the Sandbox entitlement flag (usually set to <true/>) and change it to <false/>. You will have to unlock the file when editing. Save the file (located on the desktop). Rename the original file in the .app package (i.e. append .old to the filename). Copy the desktop file back to the .app Package location (you may have to authorize it). This should remove the sandboxing.
You cannot remove Sandbox if the user ran you application via Sandbox.
That's the whole point - don't you think ?

Resources