Hello macOS gurus, I am writing an AUv3 plug-in and wanted to add support for additional formats such as CLAP and VST3. These plug-ins must reside in an appropriate folder /Library/Audio/Plug-Ins/
or ~/Library/Audio/Plug-Ins/
. The typical way these are delivered is with old school installers.
I have been experimenting with delivering theses formats in a sandboxed app. I was using the com.apple.security.temporary-exception.files.absolute-path.read-write
entitlement to place a symlink in the system folder that points to my CLAP and VST3 plug-ins in the bundle. Everything was working very nicely until I realize that on my Mac I had changed the permissions on these folders from
to
The problem is that when the folder has the original system permissions, my attempt to place the symlink fails, even with the temporary exception entitlement.
Here's the code I'm using with systemPath = "/Library/Audio/Plug-Ins/VST3/"
static func symlinkToBundle(fileName: String, fileExt: String, from systemPath: String) throws {
guard let bundlePath = Bundle.main.resourcePath?.appending("/\(fileName).\(fileExt)") else {
print("File not in bundle")
}
let fileManager = FileManager.default
do {
try fileManager.createSymbolicLink(atPath: systemPath, withDestinationPath: bundlePath)
} catch {
print(error.localizedDescription)
}
}
So the question is ... Is there a way to reliably place this symlink in /Library/...
from a sandboxed app using the temporary exception entitlements? I understand there will probably be issues with App Review but for now I am just trying to explore my options.
Thanks.
Is there a way to reliably place this symlink in /Library/... from a sandboxed app using the temporary exception entitlements?
Actually the better option here which is also compatible with the App Store is NSWorkspace's "Privileged File Operation" API. That API will only allow your perform very specific operation*, but one of those is "createSymbolicLink".
*For example, you can use this API to replace an existing file, but it cannot be used to create a new one.
It does require an entitlement which you'll need to request, but there are apps on the App Store using this API.
You use this API by:
-Call requestAuthorization, passing in the file operation you want to perform.
-The system will present an authorization dialog on your behalf and return an NSWorkspace.Authorization to your app (assuming the user approves it).
-You pass that authorization into FileManager.init(authorization:) to create a "special" FileManager object.
-You then call the method for the operation you requested using that FileManager and the system does the rest. So, for "createSymbolicLink", you'd call "createSymbolicLink(at:withDestinationURL:)". Note you MUST call that specific method and ONLY that method. Similar method like "createSymbolicLink(atPath..." or "linkItem(at:to:)" will not work and you should expect ANY other FileManager methods to work either.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware