FileWrapper
A FileWrapper is a representation of a node (a file, directory, or symbolic link) in the file system.
On a document-based app the FileWrapper acts as "middleware" between the file system and the actual models in an application, similar to a JSON API that is retrieved from a data source.
FileWrapper can handle single files or packages, which is a directory with files treated as a single file by the system, these packages are usually custom file formats created by the application. For example, OmniOutliner have a .ooutline and OmniGraffle a .graffle extension for their documents.
Class Functions
withContents(name: String or null, contents: Data) → (FileWrapper) • Returns a new FileWrapper that represents a flat file containing the given data.
withChildren(name: String or null, children: Array of FileWrapper) → (FileWrapper) • Returns a new FileWrapper that represents a directory with the given child file wrappers. Each child file wrapper must have a unique name specified.
fromURL(url: URL, options: Array of FileWrapper.ReadingOptions or null) → (FileWrapper) • Reads a FileWrapper from an existing URL.
Read Text File to Clipboard
var picker = new FilePicker()
picker.folders = false
picker.multiple = false
taskpaperType = new TypeIdentifier("com.taskpaper.text")
picker.types = [taskpaperType, TypeIdentifier.plainText]
picker.show().then(urls => {
url = urls[0]
wrapper = FileWrapper.fromURL(url)
Pasteboard.general.string = wrapper.contents.toString()
})
Wrapper from Text
fileName = "Cow.txt"
textData = Data.fromString("How now brown cow")
wrapper = FileWrapper.withContents(fileName, textData)
Instance Functions
filenameForChild(child: FileWrapper) → (String or null) • Returns the unique file name that will be used for the given child FileWrapper, or null if this file wrapper is not a child of the receiver.
write(url: URL, options: Array of FileWrapper.WritingOptions or null, originalContentsURL: URL or null) → () • Writes the FileWrapper to the given URL.
The following documentation contains two plug-ins that incorporate the write(…) function to write text to disk without using saving dialogs.
Save Clipboard to Omni App’s Documents Folder (@)
NOTE: the following Omni Automation plug-in uses the documentsDirectory property of the URL class to write a file to the host Omni application’s local Documents folder (the directory displayed with the Omni app’s icon).
- On an iPad (iPadOS), the Omni app’s default storage directory appears in the Files app as On My iPad > OmniAppName however the folder’s physical location on the device is similar to /var/mobile/
Containers/ which for security purposes, contains a random UUID to obscure the Omni application’s identify.Data/ Application/ 9CDD2525- 5DEF- 45B5- 95B6- 0DCB180DA56A/ Documents/ - On an iPhone (iOS), the Omni app’s default storage directory appears in the Files app as On My iPhone > OmniAppName however the folder’s physical location on the device is similar to /var/mobile/
Containers/ which for security purposes, contains a random UUID to obscure the Omni application’s identify.Data/ Application/ 9CDD2525- 5DEF- 45B5- 95B6- 0DCB180DA56A/ Documents/ - On a Mac (macOS), the Omni app’s default storage directory appears in the Finder app as Documents > OmniAppName however the folder’s physical location on the device is similar to /Users/USERNAME/
Library/ Containers/ com.omnigroup.OmniAppName/ Data/ Documents/
Save Clipboard Text to Omni App’s Documents folder
/*{
"type": "action",
"targets": ["omnifocus", "omnigraffle", "omniplan", "omnioutliner"],
"author": "Otto Automator",
"identifier": "com.omni-automation.all.write-clipboard-to-app-documents",
"version": "1.1",
"description": "Writes the text content of the clipboard to a file in the Omni app’s local Documents folder",
"label": "Clipboard to App Documents Folder",
"shortLabel": "Save to App Documents",
"paletteLabel": "Save to App Documents",
"image": "doc.on.clipboard.fill"
}*/
(() => {
var action = new PlugIn.Action(async function(selection, sender){
try {
inputForm = new Form()
fileNameField = new Form.Field.String(
"fileBaseName",
"File Name",
null,
null
)
inputForm.addField(fileNameField)
fileTypes = ["Text (plain)", "TaskPaper", "HTML", "JavaScript", "SVG"]
nameExtensions = ["txt", "taskpaper", "html", "js", "svg"]
savingTypeMenu = new Form.Field.Option(
"nameExtension",
"Text File Type",
nameExtensions,
fileTypes,
nameExtensions[0]
)
inputForm.addField(savingTypeMenu)
if (Device.current.mac){
shouldOpenFileField = new Form.Field.Checkbox(
"shouldOpenFile",
"Open file in default application",
null
)
inputForm.addField(shouldOpenFileField)
}
inputForm.validate = function(formObject){
textValue = formObject.values['fileBaseName']
return (textValue && textValue.length > 0) ? true:false
}
formPrompt = `Clipboard to ${app.name} Documents`
buttonTitle = "Continue"
formObject = await inputForm.show(formPrompt, buttonTitle)
fileBaseName = formObject.values["fileBaseName"]
nameExtension = formObject.values["nameExtension"]
fileName = fileBaseName + "." + nameExtension
if (Device.current.mac){
var shouldOpenFile = formObject.values["shouldOpenFile"]
}
folderURL = URL.documentsDirectory
fileURL = folderURL.appendingPathComponent(fileName)
textData = Data.fromString(Pasteboard.general.string, StringEncoding.UTF8)
wrapper = FileWrapper.withContents(fileName, textData)
wrapper.write(fileURL, [FileWrapper.WritingOptions.Atomic], null)
if (Device.current.mac){
if(shouldOpenFile){fileURL.open()}
}
} catch(err){console.error(err.message)}
});
action.validate = function(selection, sender){
return (Pasteboard.general.hasStrings)
};
return action;
})();
Instance Properties
children (Array of FileWrapper r/o) • Returns an Array of child FileWrappers, if this represents a directory. Otherwise, an empty array is returned.
contents (Data or null r/o) • Returns the regular file contents of the wrapper, if this represents a regular file. Otherwise, null is returned.
destination (URL or null r/o) • Returns the destination if this represents a symbolic link. Otherwise, null is returned.
filename (String or null) • Returns the actual file name that was last read for this file wrapper. Depending on the names of other sibling wrappers, this may not be what file name will be written.
preferredFilename (String or null) • Returns the preferred file name that should be used when writing the file wrapper if no other file in the same parent directory wrapper is in use.
type (FileWrapper.Type r/o) • Returns the type of this FileWrapper.
FileWrapper.Type Class Properties
Directory (FileWrapper.Type r/o) • A FileWrapper that represents a directory with zero or more child wrappers.
File (FileWrapper.Type r/o) • A FileWrapper that represents a regular file with data contents.
Link (FileWrapper.Type r/o) • A FileWrapper that represents a symbolic link to another location.
all (Array of FileWrapper.Type r/o) • All of the FileWrapper.Type usually used in creating plug-in forms.
FileWrapper.ReadingOptions Class Properties
Immediate ( FileWrapper.ReadingOptions r/o) • Whether the contents are read immediately, or (by default) as the file wrappers are accessed.
WithoutMapping (FileWrapper.ReadingOptions r/o) • Allow disabling file mapping.
all (Array of FileWrapper.ReadingOptions r/o) • All of the FileWrapper.ReadingOptions usually used in creating plug-in forms.
FileWrapper.WritingOptions Class Properties
Atomic (FileWrapper.WritingOptions r/o) • Write the entire FileWrapper atomically, so that either the entire file package is replaced or none of it is.
UpdateNames (FileWrapper.WritingOptions r/o) • On successful writing, update the filename of each file wrapper recursively so that following writes can use performance optimizations using hard links.
all (Array of FileWrapper.WritingOptions r/o) • All of the FileWrapper.WritingOptions usually used in creating plug-in forms.
Save Clipboard Text to Omni App’s iCloud Folder (@)︎
Here's a plug-in that draws upon the APIs of the Credentials, Bookmark, Pasteboard, and FileWrapper classes to save the current clipboard text to the host Omni application’s iCloud folder without requiring subsequent use of pickers. Text data may be saved in either Plain Text, HTML, TaskPaper, or JavaScript file formats.
The plug-in saves a bookmark to the host application’s iCloud folder selected by the user. That stored bookmark is then used with each subsequent running of the plug-in to save the text contents of the clipboard to the iCloud folder in either: plain text, HTML, TaskPaper, or JavaScript formats.
To reset the stored bookmark, hold down the Control key when selecting the plug-in from the Automation menu.
Use cases:
- Use the OmniFocus “Copy as TaskPaper” command with the selected items and then run this plug-in to save the clipboard text as a TaskPaper file in the OmniFocus iCloud folder.
- Use the OmniGraffle “Copy as JavaScript” command with the selected shapes and then run this plug-in to save the clipboard text as a JavaScript script file in the OmniGraffle iCloud folder.
TIP: This plug-in works with iCloud folders or any folder that requires user-approval for access.
Save Clipboard Text to Omni App’s iCloud Folder
/*{
"type": "action",
"targets": ["omnifocus", "omnigraffle", "omniplan", "omnioutliner"],
"author": "Otto Automator",
"identifier": "com.omni-automation.all.write-clipboard-to-app-documents",
"version": "1.1",
"description": "Writes the text content of the clipboard to a file in the Omni app’s local Documents folder",
"label": "Clipboard to App Documents Folder",
"shortLabel": "Save to App Documents",
"paletteLabel": "Save to App Documents",
"image": "doc.on.clipboard.fill"
}*/
(() => {
var action = new PlugIn.Action(async function(selection, sender){
try {
inputForm = new Form()
fileNameField = new Form.Field.String(
"fileBaseName",
"File Name",
null,
null
)
inputForm.addField(fileNameField)
fileTypes = ["Text (plain)", "TaskPaper", "HTML", "JavaScript", "SVG"]
nameExtensions = ["txt", "taskpaper", "html", "js", "svg"]
savingTypeMenu = new Form.Field.Option(
"nameExtension",
"Text File Type",
nameExtensions,
fileTypes,
nameExtensions[0]
)
inputForm.addField(savingTypeMenu)
if (Device.current.mac){
shouldOpenFileField = new Form.Field.Checkbox(
"shouldOpenFile",
"Open file in default application",
null
)
inputForm.addField(shouldOpenFileField)
}
inputForm.validate = function(formObject){
textValue = formObject.values['fileBaseName']
return (textValue && textValue.length > 0) ? true:false
}
formPrompt = `Clipboard to ${app.name} Documents`
buttonTitle = "Continue"
formObject = await inputForm.show(formPrompt, buttonTitle)
fileBaseName = formObject.values["fileBaseName"]
nameExtension = formObject.values["nameExtension"]
fileName = fileBaseName + "." + nameExtension
if (Device.current.mac){
var shouldOpenFile = formObject.values["shouldOpenFile"]
}
folderURL = URL.documentsDirectory
fileURL = folderURL.appendingPathComponent(fileName)
textData = Data.fromString(Pasteboard.general.string, StringEncoding.UTF8)
wrapper = FileWrapper.withContents(fileName, textData)
wrapper.write(fileURL, [FileWrapper.WritingOptions.Atomic], null)
if (Device.current.mac){
if(shouldOpenFile){fileURL.open()}
}
} catch(err){console.error(err.message)}
});
action.validate = function(selection, sender){
return (Pasteboard.general.hasStrings)
};
return action;
})();