URL.Bookmark Class (bookmarks)
An instance of the URL.Bookmark class records the permission to access a given URL and will restore that permission, as well as a possibly renamed file, at a later point.
Because of security features in iOS/iPadOS/macOS the user must actively approve the use of files and folders located outside of the current applicationās sandbox security zone.
To eliminate the need for the plug-in user to locate and select a specified location or file used by the plug-in, every time the plug-in is run, you can store an approved reference to the user-selected location in the system Keychain. This reference is called a “bookmark.” Stored bookmarks can be retrieved and used without further user interaction.
The storing of bookmarks in the system Keychain is accomplished through the use of the Credentials class.
Credentials Instance Functions
readBookmark(service: String) → (URL.Bookmark or null) • Reads the entry for the given service identifier and attempts to return it as a URL.Bookmark, or null if no such entry exists.
writeBookmark(service: String, bookmark: URL.Bookmark) → ( ) • Stores the URL.Bookmark persistently for later access.
On macOS, bookmarks can be located in the Keychain Access application by filtering using the credential service title:
URL.Bookmark Class Functions
fromURL(url: URL) → (URL.Bookmark) • Creates a URL.Bookmark from an existing URL, which should have been returned by FilePicker. This can then be stored in a Credentials object to persistently record the permission to access this URL. (see plug-in example in this section)
URL.Bookmark Instance Functions
access() → (Promise of URL.Access) • Attempts to resolve the instance into a URL and grant access to it through the returned Promise. Access to the URL will only last as long as the URL.Access object exists (which should not be stored longer than necessary).
URL.Access Class
An instance of the URL.Access class holds the temporary access given by the URL.Bookmark.access() function. These should not be stored longer than needed.
url (URL r/o) • The URL being accessed.
Example Plug-In
Here is an example plug-in (compatible with all Omni apps) that demonstrates how to store and retrieve instances of the URL.Bookmark class:
Bookmark Example: Open Chosen/Stored Directory
/*{
"type": "action",
"targets": ["omnigraffle","omnifocus","omniplan","omnioutliner"],
"author": "Otto Automator",
"identifier": "com.omni-automation.all.bookmark-example",
"version": "1.1",
"description": "This plug-in uses the URL.Bookmark class to create and retrieve stored bookmark.",
"label": "Bookmark Example",
"shortLabel": "Bookmark Example",
"paletteLabel": "Bookmark",
"image": "bookmark.square"
}*/
(() => {
credentials = new Credentials()
serviceTitle = "source-folder"
const action = new PlugIn.Action(async function(selection, sender){
try {
// TO REMOVE BOOKMARK HOLD DOWN CONTROL KEY WHEN SELECTING PLUG-IN
if (app.controlKeyDown){
alertMessage = "Remove the stored bookmark?"
alert = new Alert("Confirmation Required", alertMessage)
alert.addOption("Remove")
alert.addOption("Cancel")
alert.show(buttonIndex => {
if (buttonIndex === 0){credentials.remove(serviceTitle)}
})
} else {
// RETRIEVE BOOKMARK
bookmark = credentials.readBookmark(serviceTitle)
// IF NO BOOKMARK, ASK FOR FOLDER
if(!bookmark){
picker = new FilePicker()
picker.folders = true
picker.multiple = false
chosenDirectoryURLs = await picker.show()
bookmark = URL.Bookmark.fromURL(chosenDirectoryURLs[0])
credentials.writeBookmark(serviceTitle, bookmark)
bookmark = credentials.readBookmark(serviceTitle)
}
}
// RETRIEVE ACCESS TOKEN AND PERFORM ACTION WITH FOLDER
token = await bookmark.access()
url = token.url
url.open()
}
catch(err){
if(!err.causedByUserCancelling){
console.error(err.name, err.message)
new Alert(err.name, err.message).show()
}
}
});
action.validate = function(selection, sender){
return true
};
return action;
})();