I need to access sidecar XMP files in a document-based photo editor application.
The image files are the documents, and I need to access the sidecar XMP file when the user open and save an image document.
Is it possible to access sidecar files (such as XMP) in a sandboxed document-based application?
I understand that it's not possible by default, but what is the minimal temporary security exception that is needed to allow that?
Is there a workaround for this without using temporary exception?
Note that it's impossible to guarantee the the image files document-scoped bookmarks to the side-cars (as they might created by other apps on different platforms), so this solution won't work.
While this question is old I thought I would share my solution. You can add an entry to your CFBundleDocumentTypes section in your apps info.plist with the NSIsRelatedItemType set to true. Then your sandboxed app will be able to open any file the user gives permission to with the same name but has the extensions that you list. Here is an example for an xmp sidecar file:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>xmp</string>
</array>
<key>CFBundleTypeName</key>
<string>XMP sidecar</string>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>NSIsRelatedItemType</key>
<true/>
</dict>
</array>
Related
Can I use Applescript to find the current iTunes media location and other iTunes options.There doesnt seem to be such options when I read the iTunes Applescript Dictionary within Script Editor but surely there is a way to do it.
I read in the past that something is stored in com.itunes.plist but its not plaintext and my plist file did not change when I created a new libary so Im not convinced it is still used, or if it is kept up to date.
Yes, #PaulTaylor, you can get the media folder location of the current user in AppleScript using the Apple-provided iTunesLibrary framework. (documentation at iTunesLibrary at Apple)
Here's a working AppleScript to do it:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "iTunesLibrary"
set lib to current application's ITLibrary's libraryWithAPIVersion:"1.0" |error|:(missing value)
set mediaFolderPath to POSIX path of (lib's mediaFolderLocation as alias)
--> "/Volumes/LaCie 6/iTunes Library/"
The media location is not saved in the global iTunes preference file. Because you can have multiple libraries, and each library defines its own media location, this is actually saved in the the library preferences. The default library is located at ~/Music/iTunes/iTunes Library.itl. I'm not sure what kind of file this is. It does not seem to be a plist/xml file, nor an sqlite file. It seems to just be a proprietary binary file.
Inside the same folder, I also found iTunes Music Library.xml (after some testing around, that file is now missing, so YMMV for the rest of this explanation). Here is a truncated example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Major Version</key><integer>1</integer>
<key>Minor Version</key><integer>1</integer>
<key>Application Version</key><string>12.3.3.17</string>
<key>Date</key><date>2016-04-14T19:35:27Z</date>
<key>Features</key><integer>5</integer>
<key>Show Content Ratings</key><true/>
<key>Library Persistent ID</key><string>1AEAB6C2057C2167</string>
<key>Tracks</key>
<dict>
</dict>
<key>Playlists</key>
<array>
</array>
<key>Music Folder</key><string>file:///Users/<username>/Music/iTunes/iTunes%20Media/</string>
</dict>
</plist>
Note the key Music Folder. This is the setting you are looking for to find the library's media location. There are also some library settings, such as a list of playlists and track information.
I've just discovered textmate and I love it. I would love to use it as a way of storing my own snippets. I know how to do this in textmate but as I want to add loads of snippets I don't want them to become disorganised. I would like to add them into organised subfolders under the relevant bundle. eg under the shell script bundle I would like to add a folder that keeps all my networking snippets together. I cant find anywhere how to do this but I know it can be done as some bundles are organised like this.....Help
I managed to figure this out with a lot of trial and error and starting with this Superuser answer.
The only way to do it in TextMate 2.0 is to manually edit the info.plist file for your bundle. I suggest doing this on an exported copy of the bundle and reloading it into textmate. To export a bundle right click on the bundle in bundle editor and click Export Bundle....
Start by adding a mainMenu section at the top level of the plist file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
<key>mainMenu</key>
<dict>
</dict>
</dict>
</plist>
From what I can tell, the mainMenu dict supports 3 keys: excludedItems, items, and submenus. The excludedItems and items are arrays containing a list of UUIDs of either bundle items (snippets, commands, etc.) or submenus. You can get the UUID of a command or snippet by opening it in textmate and finding the uuid key; it'll look like:
<key>uuid</key>
<string>0A2DB1AC-3049-4BD5-8931-641E716990F9</string>
Once you have the UUIDs of your items you can list them in items to populate the bundle menu in the order you wish, e.g.:
<key>items</key>
<array>
<string>409b0e74-9ab5-4d35-b957-9ddf23a71c0c</string>
<string>------------------------------------</string>
<string>d2c991dc-a00e-4247-8479-f2d29f387319</string>
</array>
If you use a series of - characters in lieu of a UUID, it will create a separator in the menu. Likewise, if there are snippets you don't want to display in the bundle's menu you can add them to excludedItems.
To create submenus you have to define them inside submenus, like so:
<key>submenus</key>
<dict>
<key>71BE58B2-E486-4B21-93F1-C208D4914099</key>
<dict>
<key>items</key>
<array>
<string>6D0B2B9D-62C7-4842-BA28-F3379E887D93</string>
<string>CADC55BD-0D0A-48C8-B296-35FA7AAE09CA</string>
</array>
<key>name</key>
<string>C++ Snippets</string>
</dict>
</dict>
Each submenu needs to have an associated UUID inside <key>...</key>. I created one from an online UUID generator. You can then add the submenu's UUID to the top-level items array to add the submenu to your bundle's menu.
Finally, when loading your bundle into textmate you must first delete all cached instances of the bundle from:
~/Library/Application Support/Avian/Bundles
~/Library/Application Support/Avian/Pristine Copy/Bundles
If you don't, textmate will sometimes ignore the newly loaded bundle. Not sure if there's a cleaner way to reload a bundle, but deleting it worked for me.
For a complete example see this commit in the ROS bundle on my Github.
Just some extra info on the excellent answer above
As of TM2 rc23, you can access the UUID of an existing item by right-clicking on it in the bundle editor window (accessed with cntrl-option-command-B)
You can create a UUID in terminal.app with the command uuidgen (you could also make this into a command if you use this often)
TM2 doesn't need the cache clearing - it watches for changes in the plist.
#user96157 is clear about this, but note you have to also add your new submenu to the mainMenu. So:
<key>mainMenu</key>
<dict>
<key>items</key>
<array>
<string>COPY-UUID-FOR-YOUR-NEW-SUB-MENU-HERE!</string>
My login.keychain does not appear in the keychain search list. I am convinced this is a permissions problem, left over from a recent migration from an older machine, which caused havoc for a time.
I can add the keychain in Keychain Access (KA) and can use it, even adding and deleting items. However, when I quit and re-start KA, it's missing again. I tried using Terminal to add it using "security", but this had the same result. The list simply won't change.
The chain itself seems fine, and I used the Recreate and Keychain First Aid to no avail - I think because they're attacking different issues.
So, does anyone know where this information is stored, and what files I might need to fix/delete to get everything working again?
Keychain search lists are stored in /Library/Preferences/com.apple.security.plist for the system, and ~/Library/Preferences/com.apple.security.plist for each user.
The plist contents look like this:
<dict>
<key>DLDBSearchList</key>
<array>
<dict>
<key>DbName</key>
<string>... path to keychain file ...</string>
<key>GUID</key>
<string>{...}</string>
<key>SubserviceType</key>
<integer>6</integer>
</dict>
... more dict entries ...
</array>
<key>DefaultKeychain</key>
<array>
<dict>
<key>DbName</key>
<string>... path to keychain file ...</string>
<key>GUID</key>
<string>{...}</string>
<key>SubserviceType</key>
<integer>6</integer>
</dict>
</array>
</dict>
I wonder is it possible to keep list of files or folders opened before on sandboxed app without re-opening them or copying to it's own library ?
Thanks in advance
To keep track of files being accessed by the user, you should create security bookmarks for each file, then that will allow your application to access these files on future runs of the application without getting permission everytime.
I've made this class that wraps up persisting permissions you already have from a using opening a file via NSOpenPanel, and then you can use the class to access that file in the future.
https://github.com/leighmcculloch/AppSandboxFileAccess
At this time only using temporary entitlements.
You should use something like
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>
<array>
<string>absolute path to use</string>
</array>
</dict>
</plist>
I hope Apple will clarify how this can be done without 'temporary' solutions because it breaks many many apps
Is it possible to to register a folder extension on Mac to be opened with a specific application (something like .app folders behave in a special way)? If it's possible, then how?
I'm looking for a solution similar to this: related question, only for folders, not files.
I had a look at the reference of the UTIs UTIs, but I did not find any identifier that seems suitable (e.g. something like public.folder-extension).
Is it possible to do this at all? On the GUI I did not see any way to do it either (for a folder with a specific extension, there is no "Open With..." option). [Important: I do not want to do this on the GUI, this was only a remark to say why I think it might be impossible.]
I found out a way that works for me (in case somebody else also encounters this problem):
Add the following snippet in the Info.plist file of the application bundle:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>ext1</string>
<string>ext2</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>documentlogo.icns</string>
<key>CFBundleTypeName</key>
<string>My Bundle Type Name</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSTypeIsPackage</key>
<true />
</dict>
</array>
Replace ext1, ext2 with the extensions you would like to support, documentlogo.icns with the name of the icon of the document (which must be located in Application Bundle.app/Contents/Resources/documentlogo.icns), and My Bundle Type Name with a sensible name for your bundle)
In this example, any folder, to be recognized as a bundle of our application, must have the extension ext1 or ext2, and must contain a Contents/PkgInfo file, with 8 "?"s. All the other contents are up to you.
I base my solution on these sources, Document Packages, Information Property List Key Reference, Document Packages Examples.
Please, correct me if there is a better/more efficient way to do it, because I still have some doubts (e.g.: as I see, this should work also for normal files, not just Packages. Then why do we need the LaunchServices way as well? Is the application bundle the default, and the LaunchServices the way each user customizes it?)
I found how to do this manually, which I will list here for others to find, and to do this programmatically you can combine this info with the answer at: https://superuser.com/questions/273756/how-to-change-default-app-for-all-files-of-particular-file-type-through-terminal
You must have XCode installed. Open Terminal or iTerm and:
cd ~/Library/Preferences
open com.apple.LaunchServices.plist
Add or overwrite the following entry (use Cmd+F to search for "folder"):
LSHandlerContentType String public.folder
LSHandlerRoleAll String com.somecompany.someproduct
Replace the com.somecompany.someproduct with an existing name - you can see these in the same directory (~/Library/Preferences) - they end with .plist - e.g. com.macromates.textmate or com.sublimetext.2.
Alternative if you use Quicksilver: add a custom keyboard trigger for "Current Selection (Proxy Object) -> Open With -> Your App Here". I found that this also creates (and vigorously re-creates) the above association whenever you use the newly created keyboard shortcut on a folder in Finder.