RapidWeaver 9 API

Hey there developers,

We’re busy working on RW9 and have realised that a number of plugins are making use of private classes/methods or utilising method swizzling to achieve some functionality. Doing this puts a hard block on the development of RapidWeaver in fear of breaking plugins. It restricts the features we can add along with increasing development times.

As we have no idea which methods / classes you’re using, we would appreciate it if you could declare usage below.

I cannot guarantee that anything declared here will still function in RW9, but it gives us a chance to get an alternative in place so your plugins still function.


1 Like

No swizzling here ( that I know of ) :wink:

I have to know what swizzling is since I’m not an plugin developer. It sounds like an 80s dance move or some kind of 70s cocktail or something.

1 Like

It turns out that ‘swizzling’ refers to something far more inappropriate if you believe the Urban Dictionary LOL…

However, when coding in Objective-C it refers to the process of swapping out a method’s implementation for another one at runtime.


The most exotic thing our plugins do is catching drag and drop from resource manager and sidebar. This broke after each major release, but we promptly fixed so far. Having an official / documented way to do this would help.

Also, since console logging has been turned off by default, having an API to display some structured log data after export / publish would be welcome.


Thanks @gibo,

Could you give me some more info on what broke with the drag and drop stuff (if you can remember) and what you do now?

1 Like

Sure, IIRC we were looking for RWDragFlavorPagesSourceList into dragging info for RW 6 and 7 and needed to switch to NSFilesPromisePboardType in RW 8.

I’d need to review some code to be sure this is the only thing we adjusted, though. I’ll keep you posted if I’ll find anything else. Thanks!

1 Like

Hey @gibo

I’ve just checked RCP v4.17.2 in the latest build of RW9 and I’m hitting a crash because it’s looking for a pagesController on RWDocument when adding a RCP page for what looks to be some licensing code.

The pagesController isn’t in RW9 because we don’t need it, what are you trying to achieve with it? I should be able to add something to the API if nothing suitable exists.


2020-04-03 14:00:27.783279+0100 RapidWeaver 9[84441:11986619] [General] [<RWDocument 0x1040a5000> valueForUndefinedKey:]: this class is not key value coding-compliant for the key pagesController.
2020-04-03 14:00:27.786722+0100 RapidWeaver 9[84441:11986619] [General] (
	0   CoreFoundation                      0x00007fff41270cfd __exceptionPreprocess + 256
	1   libobjc.A.dylib                     0x00007fff6b93ca17 objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff4128a85d -[NSException raise] + 9
	3   Foundation                          0x00007fff4359c2ee -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 226
	4   Foundation                          0x00007fff434288c5 -[NSObject(NSKeyValueCoding) valueForKey:] + 281
	5   RapidCartPro                        0x000000012da0c95f RapidCartPro + 133471
	6   RapidCartPro                        0x000000012da2561c licensor_sha256_test + 22248
	7   RapidWeaver 9                       0x0000000100379e34 $sTa.3 + 20

Thanks for the heads-up @tpbradley

We’re looking for a pagesController to ensure there is only a single RCP instance per project.

From what I can tell, we’ve added some additional checks based on it to deal with some actions that could lead to a project containing multiple RCP pages (e.g. duplicating a RCP page or dragging and dropping it from another project).

Ah hah, ok that makes sense!

So there’s a couple of options in the API that may help.

The following two methods return an array of pages using your plugin, so calling that method would return all pages in the project currently using the RCP plugin.

Added in RW8


- (NSArray <RWPage> *)allPagesUsingPlugin;

Added in RW7


extern NSArray <RWPage> *RWAllPagesUsingPlugin(id <RWPlugin> plugin) WEAK_IMPORT_ATTRIBUTE;

This one asks if a new page can be created, passing a list of current pages using your plugin.

Added in RW7


+ (BOOL)canCreateNewPage:(NSError **)errorRef currentPages:(NSArray *)currentPages;

Would any of these be sufficient?

In RW9 I could add an API method that returns whether or not multiple pages are allowed, then RW could prevent page creation, drag drop, duplicate page etc. Sound good?

Sounds great, thanks for your help.

Hey @isaiah

I’ve just found that FAQMaker 3.1.0 is calling a private method on the RW document during export which is causing a crash.

-[MyDocument(PageExport) updateWebViewIfRequiredNow]

There shouldn’t be any need to call this method, can you remove it please.


6   RapidWeaver 8                       0x000000010002d098 -[MyDocument(PageExport) updateWebViewIfRequiredNow] + 72
7   FaqMaker                            0x000000012e0aa335 -[LHFaqMakerPlugin(setters_getters) setAnswersOnSubpage:] + 37
8   Foundation                          0x00007fff4341b2c9 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] + 685
9   Foundation                          0x00007fff4341affe -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 68
10  Foundation                      2020-04-15 11:40:48.517379+0100 RapidWeaver 8[34301:21561469] Running sidebarHTML: on <EasyTubeGallery>
    0x00007fff434a9ff7 _NSSetIntValueAndNotify + 252
11  FaqMaker                            0x000000012e0a4a60 -[LHFaqMakerPlugin contentHTML:] + 832
12  RWKit                               0x0000000100eabb9c -[RWExporter pageContents:params:] + 716