6.0 Plugin SDK Changes - realmacsoftware/RWPluginKit GitHub Wiki

There are three areas of particular importance in your adoption of the RapidWeaver 6 Plugin SDK:

  • Sandboxing
  • RapidWeaver 6 being 64-bit only
  • RapidWeaver 6 has a new design, and Plugin Icon Template PSDs are included with the SDK. We recommend that you make your plugin fit in with RapidWeaver by using it - however it is not required that you use this design.
  • The documents in this wiki will provide you with details on how to move to RapidWeaver 6.

As the methods to offer sandbox-safe file access are not available across the many versions of OS X supported by RapidWeaver 5, RapidWeaver 6 uses a new document format that is not backwards compatible. You can export from RapidWeaver 5 to RapidWeaver 6, but not vice versa. We strongly advise developers to ensure that they move to RapidWeaver 6 (and RapidWeaver-6-only) plugins as quickly as possible, and RapidWeaver 6’s .rapidweaverplugin extension for plugins means that only RapidWeaver 6 will open these plugin types.

64-bit

RapidWeaver 6 is 64-bit only, and your RapidWeaver plugins must use the .rapidweaverplugin file extension. When rebuilding your plugin, link against the 64-bit version of RMKit included with RapidWeaver 6.0.

RapidWeaver 6 no longer links against QuickTime.framework as this framework is not 64-bit, and you should audit your code for any calls to this framework.

This 64-bit migration guide from Apple may prove useful in auditing other areas of your code to ensure 64-bit readiness.

Persistent File Access

If your plugin references files outside the RapidWeaver sandbox, you’ll need to make sure you support sandbox-safe file access - Security Scoped Bookmarks.

It is important that plugin developers only use the methods provided by RapidWeaver to export security-scoped bookmark data. Do not attempt to access the RapidWeaver document object directly to create security scoped bookmarks using Apple’s own sample code.

Exporting from RapidWeaver 5.4 to RapidWeaver 6

Simply use the File > Export to RapidWeaver 6 menu item to kick this off.

As far as plugins are concerned, an "upgrade export" is exactly the same as a regular save operation. For plugins that don't require security-scoped file access there's nothing to do. Your data should be exported to the new document without issue.

For plugins that do require security-scoped file access, we need to modify our save routine to register said file URLs. We do this via the following API method:

- (NSString *)registerFileURL:(NSURL *)fileURL error:(NSError **)error; Calling this on the plugin instance will return a identifier for the provided URL. This identifier is all the plugin required to track this file across runs of the application. Take the provided identifier and include it in your archive data when saving. For example:

NSString *bookmarkToken = [self registerFileURL:theMovieURL error:NULL]; [encoder encodeObject:bookmarkToken forKey:@"bookmarkToken"];

Handling File Access in RapidWeaver 6

Anywhere the code actually reads from disk we need to use the identifier to get a sandbox-safe NSURL object. We do this with the following code:

NSError *error = nil; NSURL *resolvedFileURL = [self fileURLForToken:bookmarkToken error:error];

At this point we have a usable NSURL object as resolved by the system. The only thing left to do is inform the system when we begin and end our file access. We do this like so:

if (![resolvedFileURL startAccessingSecurityScopedResource])<br>{<br>// File access here.<br>[resolvedFileURL stopAccessingSecurityScopedResource];<br>}

Update capture code to register file URLs with the document.

If we get a file URL from the NSOpenPanel or via drag and drop we need to register it with the document at that time. We do this the same way we did when doing an "upgrade export". While it's no longer necessary to track files via path it can be useful to keep the path info around in case a file can't be resolved. This typically happens if the user has deleted a file or moved it to a different volume. In these cases, having the path info allows us to show the user which file we were expecting to find.

Enable Verbose Logging for Plugin Updates

RapidWeaver 6 includes plugin update checking to negate the need to include a copy of Sparkle. Optional plugin update logging can be enabled by entering the following in the Terminal.

defaults write com.realmacsoftware.rapidweaver6 RWVerboseAddonUpdateChecking YES Sandbox Reference Guide RapidWeaver 5.4 will accompany RapidWeaver 6. Please ensure you are familiar with the differences between RapidWeaver 5.4 and 6.0.

RapidWeaver 5.4

  • Not Sandboxed
  • 32-bit app
  • 32-bit RMKit
  • OS X 10.6.8+
  • Open & Save .rwsw (Sandwich) Documents
  • Exports .rw6 Documents on versions of OS X supported by RW6

RapidWeaver 6

  • Sandboxed (N.B. Both the Mac App Store and Direct versions will be sandboxed)
  • 64-bit only app
  • 64-bit RMKit
  • Opens & Saves .rw6 Documents

WWDC Sandboxing Reference Video

If you are unfamiliar with the concept of sandboxing, please watch WWDC 2013 session 710!

More Details on the Sandbox As a result of being sandboxed, all RapidWeaver 6 resources (including the Preferences and App Support folder) are stored in the following Finder location:

~/Library/Containers/com.realmacsoftware.rapidweaver6/

Please be aware that you must not use this path in your code - this is simply for your reference in locating the sandbox in the Finder: instead, you should make use of the NSString method "stringByExpandingTildeInPath". Under no circumstances should you use absolute paths.

As the sandbox gives the app the equivalent of a user home directory, the RapidWeaver App Support folder is located at:

~/Library/Containers/com.realmacsoftware.rapidweaver6/Data/Library/Application Support/

Reminder: Under no circumstances should you use absolute paths. This path is documented solely for your reference.

Sandboxing Entitlements in RapidWeaver 6+

The following entitlements are the ones that we will be officially supporting in RapidWeaver 6. Remember that your plugin will be running in the RapidWeaver process, and you are bound by the entitlements applied to RapidWeaver 6.

We may, at our discretion, include other entitlements (including temporary ones) however unless documented below any other entitlements should be treated as a Private API that you cannot depend on, and you should not assume their presence when updating your plugins. In short: anything deemed “Private API” should not be used in your plugins.

The entitlements below are all set to YES in the RapidWeaver entitlements file and are considered a Public API, and documented part of the RapidWeaver Plugin SDK.

  • Sandbox Enabled
  • Network: Allow Outgoing Connections
  • Network: Allow Incoming Connections
  • Printing
  • Allow Address Book Data Access
  • User Selected Files: Read & Write
  • Music Folder: Read-Only
  • Pictures Folder: Read-Only
  • Movies Folder: Read-Only

Should you wish to confirm the entitlements that RapidWeaver has applied to it, you can run the following Terminal command with the path to the RapidWeaver app:

codesign -d --entitlements - /path/to/RapidWeaver.app

You cannot modify the entitlements of RapidWeaver yourself.

We will not be adding carte-blanche entitlements to RapidWeaver as this defeats the point of the sandbox, and would not pass App Review. Please bear in mind that only truly extraordinary circumstances or technical reasons would give us cause to consider adding to the entitlements that RapidWeaver uses.

Debugging the Sandbox When debugging your plugins in a sandboxed build of RapidWeaver, it may be useful to set up a custom Console query to look for log messages from sandboxd. Any attempts by RapidWeaver to access resources which it is not permitted to access are logged to the console by sandboxd and include a stack trace to help you figure out where the requests are coming from.

Changes in your Plugin for the Sandbox

The “Export to RW6” Preflight in RapidWeaver 5.4 performs a check on your RapidWeaver 5 plugin’s PLIST. You will need to add a BOOL to your plugin’s Info.plist file for the key RWPluginSupportsSandbox with the value set to YES.

The RWPluginSupportsSandbox is not used in RapidWeaver 6 plugins, as any plugin that targets RapidWeaver 6 must be sandbox ready. It is only of use to plugins in RapidWeaver 5.4. You should also take this opportunity to add (or update) a string to your plugin’s Info.plist file for the RWAddonSupportURLString key, as well as a RWAddonAuthor string. This web address must be included if you choose to list your plugin in the RapidWeaver Addons area. The RWAddonAuthor key will prevent your add-on from being shown as from an Unknown Developer within the RapidWeaver UI.

If your plugin does NOT use or require persistent file access you’re basically done - however you should check for:

Absolute file paths NSOpenPanel and NSSavePanels Any private data access (that is, Address Book, Calendar or Location Services access) Any text fields that the user can enter file paths into Any attempts to directly read preference files on-disk instead of via NSUserDefaults or CFPreferences. Do not attempt to read preferences directly from a PLIST.

If your plugin allows the user to enter file paths, you will need to prompt the user to re-allow access to that path via an NSOpenPanel, and store the necessary security-scoped bookmark to the document. If your file references files on disk (instead of copying into the document bundle) via either drag and drop, or an NSOpenPanel you will need to make some further changes to your document.

Migrating Content from the RapidWeaver 5 App Support Folder If your plugin stores content in the App Support folder, you should consider monitoring the RWDidPerformSandboxMigration boolean in the RW6 using NSUserDefaults to see whether the user has migrated from RapidWeaver 5, and respond accordingly - either by prompting the user, or ideally by seamlessly copying over your data from RW5 to your own sub-folder of the RW6 app support folder.

RapidWeaver has a temporary entitlement to access the RW5 App Support folder. We don’t envisage this disappearing in the near future, but remember that it is a temporary entitlement and that a policy change by Apple may require its unexpected removal. You must gracefully handle the inability to access the App Support folder.

⚠️ **GitHub.com Fallback** ⚠️