Today we’re releasing a private beta of the upcoming RapidWeaver 7.1!
We’ve added some amazing new features in 7.1 and we think you’re going to love them. Please have a read through and let us know what you think.
We’re aiming to get a public beta out within the next few weeks, depending on how you guys get on.
Download: [RapidWeaver 7.1 Beta (17930b)] (https://dl.devmate.com/com.realmacsoftware.rapidweaver/17930b/1467026976/RapidWeaver-17930b.zip) Released 27th June
New in this release
- Caching of the plugins preferred file extension
- Revising the RWPluginEditingViewControllers protocol
Starting in RapidWeaver 7.1 we will be lazy loading plugins. What this means is that your plugin is not instantiated until it’s actually required. Using this technique we have decreased loading time by an order of magnitude. In some cases we’ve seen loading decrease from nearly 4 minutes right down to 8 seconds!
What you have to do
In most cases, absolutely nothing. Your existing plugins will just work. However, if your plugin employs some kind of wizardry to examine the RW document or plugins of other pages, you may need to do some work.
Methods to stay away from
There are some methods available through the API that will force plugins of other pages to load. It’s advised not to use these methods so please check your plugin to see if their use is absolutely necessary.
- (NSString *)overrideFileExtension
This method is currently documented only in the RMSamplePlugin project. It’s called when we build links between pages, say for example the menu bar. If your plugin implements it, we’re forced to load the plugin before returning a link, thus negating the benefits of lazy loading. In most cases this method can just be removed. We’ve just added caching of the preferred file extension so the effects of it’s use are far less noticeable on subsequent loads.
Saving a document in RapidWeaver 7.1 is now performed asynchronously! Construction of document sandwich will happen on a background thread and the main thread will be blocked. Once the sandwich has been built, the main thread is unlocked and the background thread continues on to write the sandwich data to disk.
Uninitialized or missing plugins
When building the document sandwich, we will ask each loaded plugin for their sandwich. For unloaded plugins, we simply duplicate the page’s sandwich as it was when the user opened the document.
Plugin shared data persistence
Some plugins require the ability to share data between pages. While you can easily share data internally using a static property, there has never been a good way to persist shared data. With RapidWeaver 7.1 we’re introducing shared data persistence. During save, each plugin will get the chance to create an RMSandwich containing shared data to be persisted at the document level. Your sandwich will be saved in the document with the following path.
A new API
To make use of the new shared data, you’ll need to adopt the
RWPluginSharedData protocol on your plugin. It’s important to note that this API doesn’t give you a way to pass information between instances of your plugin, that we leave to you. This API gives you an easy way to persist the information to the document. As static objects are shared across every instance of your plugin, we pass in the current document so you can restrict the sharing of data at the document level.
@protocol RWSharedPluginData <NSObject>
/// Load the passed in sandwich for the specified document. This will be called on document load if the plugin has stored shared plugin data
+ (void)loadSharedPluginDataSandwich:(RMSandwich *)sandwich forDocument:(NSDocument <RWDocument> *)document;
/// Return a sandwich containing shared data to be stored in the specified document.
+ (RMSandwich *)sharedPluginSandwichForDocument:(NSDocument <RWDocument> *)document;
/// Clear any shared data for the specified document
+ (void)clearSharedPluinDataForDocument:(NSDocument<RWDocument> *)document;
Existing shared data
If your plugin is already persisting shared data to one or more pages, you should consider migrating it to use the new shared data API. To help with migration, we’re providing the following protocol.
@protocol RWSharedPluginDataMigration <NSObject>
/// Move any shared data stored in the page to the shared plugin data store
/** THIS METHOD WILL BE CALLED ONLY ONCE PER PAGE
* Only plugins that conform to the RWSharedPluginDataMigration protocol will be migrated
* After migration, the page will me marked as being migrated and this method will not be called on subsequent loads
+ (void)migratePageSandwich:(RMSandwich *)sandwich toSharedPluginDataForDocument:(NSDocument<RWDocument> *)document;
During document load, we will call this method for all plugins that adopt the
RWSharedPluginDataMigration protocol. This method will be called exactly once for each page and gives you a chance to read the page’s data sandwich and migrate any shared data without actually loading the plugin. Anything you do in this method should be kept to a minimum to ensure documents load quickly.
Global Settings Area
Following on from the shared data above, we have also added the ability for plugins to provide a document-global settings area. You would put anything that would apply to every instance of your plugin in a document in here - for example, you might allow the user to provide a set of API keys or specific style options.
To implement this, we’ve started at looking at ways in which we can modernise the RapidWeaver plugin APIs to allow you (and us) the opportunity to take advantage of newer features in macOS. To this end, any plugins going forward will need to implement NSViewController subclasses for their main views. We’ve added two new protocols:
@protocol RWPluginEditingViewControllers <NSObject>
- (NSViewController *)editingViewController;
- (NSViewController *)pageInspectorViewController;
-editingViewController corresponds to the old
-userInteractionAndEditingView and is the main content area for your plugin. If you do not provide an NSViewController in this method, your plugin will not appear in the
Pages list when added.
-pageInspectorViewController corresponds to the old
-optionsAndConfigurationView, and as before you can choose not to provide anything here if you wish.
@protocol RWPluginSettingsViewController <NSObject>
- (NSViewController *)settingsViewController;
-settingsViewController is new: if you conform to the
RWPluginSettingsViewController protocol and provide an NSViewController instance here we’ll automatically add you to the
Plugins area of the sidebar when added. You may also build a settings-only plugin by only returning a NSViewController instance in this method (we’re looking at you, PlusKit).
This API is a work in progress, and we’re looking for feedback before RapidWeaver 7.1 launches.