FxFactory offers third-party products a set of APIs to:
How does Auto-update work?
While an API allows your code to explicitly check whether a new version of your software has been released, there is no hard requirement to do so. FxFactory ensures that users have the most recent version of your software through two fully-automated methods:
- Any time users launch the FxFactory app, any update to your product is automatically downloaded and installed. (Users can control this behavior through Settings.)
- In recent versions of FxFactory, manually invoking the API to check for updates has become optional. As soon as your product checks for licensing status, FxFactory will automatically check for a new version of your software and allow users to begin the auto-update process. (Users can postpone or turn off these notifications.)
Each product is identified by its UUID, a unique identifier that allows various entities (our app, our plug-ins, our servers, and now your code too) to unequivocally identify each product available through FxFactory.
Checking for the licensing status of a product allows you to decide whether the product should run in trial mode or with its full feature set. Trial products may choose to render a watermark in its output, hide or limit certain functionality, etc.
When your code detects an error, your code can migrate any diagnostic information about the error to a new tech support contact form (for example: ”An error occurred reading file X when processing a frame with plug-in Y.”) This allows for faster resolution of any problems users may encounter with your product.
The API described above is provided by the FxFactory.framework. This framework is available on your system as long as any recent version of our software is installed.
To get a copy of the FxFactory.framework, all you have to do is install a recent version of FxFactory. The framework’s install location is:
/Library/Frameworks/FxFactory.framework
Add this framework to your project, and make sure it is part of the link phase for the appropriate target (or targets) that will need to use our API. We recommend that you link to our framework weakly, allowing your code to run even if the FxFactory.framework is missing from the system. The user may have uninstalled FxFactory, or deleted the framework by accident.
Start by adding the framework to your project. Drag the FxFactory.framework from the Finder to the Frameworks, Libraries, and Embedded Content section of your target:

When shipping an FxPlug or Workflow extension, you only need to have the PlugInKit / App Extension component link against the FxFactory framework. Unless your wrapper application needs to display licensing status, it should not need to link against, load or interact with our API.
If this is the first external framework you add to your target, Xcode will automatically create a Frameworks folder in your file hierarchy, and add the FxFactory.framework to it:

Select the framework:

While the framework is selected, open the inspector and right-click on each target that links against it. Switch the linking strategy to Optional:

When your code weak-links to the FxFactory.framework, its symbols may not be available at runtime. This would happen if FxFactory is not installed. The recommended approach is to treat the product as unlicensed (e.g. running in trial mode) and request the user to download and install a copy of FxFactory from our website.
Refer to this page on the Apple developer website for a detailed explanation of weak-linking:
In most situations, the app or loadable plug-in you are working on will already have the Hardened Runtime option enabled.
Workflow Extensions are an exception, since they require the App Sandbox instead. If your product happens to be a Workflow Extension, skip to the appropriate section further in this document. Any information related to the Hardened Runtime will not apply to your project.
Since your software is code-signed using a different identity than FxFactory, the Hardened Runtime will, by default, disallow your code from accessing the FxFactory framework while running.
To get past this limitation, turn on the Disable Library Validation option available under the Signing & Capabilities section of your Target configuration:

Note that in Debug builds and/or while running your software through the debugger, you may not encounter any problems accessing the FxFactory framework due to the fact that certain rules of the Hardened Runtime are automatically relaxed. Make sure the Disable Library Validation option remains enabled for the Release version of your product.
When planning to use the FxFactory framework from an FxPlug plug-in, you need to take some additional measures to ensure that our framework is allowed to load and access relevant licensing information for your product.
The entitlements you pick for the PlugInKit wrapper app do not matter, but the ones you choose for the PlugInKit component (the FxPlug) do. The easiest approach is to turn the App Sandbox off. If you followed the previous instructions related to the Hardened Runtime your entitlements file should also contain the entry that disables library validation:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
When the App Sandbox is off, the PlugInKit process is able to read any licensing information for your product. FxFactory records this information in its own NSUserDefaults domain. A sandboxed process would not – by default – be able to access this information outside its container.
What if I prefer to ship with the App Sandbox on? While Apple offers ways for code signed by the same team ID to access common NSUserDefaults domains, there is no way for one app (FxFactory) to grant access to its domain to just about any other process out there. Instead, this must be explicitly done by the client. The next section explains this process. As a developer, it is your choice whether the App Sandbox entitlement is enabled on your FxPlugs. As long as the PlugInKit component is codesigned and compatible with the Hardened Runtime, it will be loaded by the host app. On the other hand, Workflow Extensions must have the App Sandbox enabled to be loaded by
com.apple.security.temporary-exception.shared-preference.read-only
The entry should be an array of strings. Make sure the array contains the FxFactory User Defaults domain: com.fxfactory.FxFactory. Doing so gives read-only access to the licensing information written by our app, and our API will report the correct status when queried:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.temporary-exception.shared-preference.read-only</key>
<array>
<string>com.fxfactory.FxFactory</string>
</array>
</dict>
</plist>
If you hard-linked to the FxFactory framework, your code will cause an error if the framework is not installed on disk. When you weak-link your binary to the FxFactory framework (as recommended) the linker resolves all weak symbols automatically if the framework is installed. Symbols remain NULL otherwise.
Remember to test you code with and without the FxFactory.framework. Drag the framework away from its install location to prevent it from being loaded by your code.
The API exposed by the framework is located in the FxFactoryLicensing.h header. It is a simple, C-based API. If you have weak-linked your code against the FxFactory framework, check for each function pointer to be non-NULL before invoking it. Heed the warning contained in the official Apple documentation: use the explicit comparison against NULL rather than the ! operator, or else it will not work as expected:
#import <FxFactory/FxFactory.h>
FxFactoryLicensingStatus status = kFxFactoryLicensingStatusProductUnlicensed;
if (FxFactoryGetLicensingStatus != NULL) {
status = FxFactoryGetLicensingStatus(...);
} else {
// Remind user that FxFactory must be installed
}
if (status == kFxFactoryLicensingStatusProductIsLicensed) {
// Product has been purchased.
}
Refer to the documentation in the header for an explanation of the API, the meaning of its parameters, and the meaning of the values returned by each function.
It is important to point out certain requirements and behaviors of the API:
FxFactoryGetLicensingStatus() is dynamically updated while your code is running. If you wish to handle changes to the licensing status dynamically, refer to the new FxFactoryRegisterLicensingStatusChangeHandler() API. FxFactory.isInstalled(), your code can use to check if our APIs can be invoked without crashing the app. FxFactoryGetLicensingStatus, can be invoked from Swift via FxFactory.licensingStatus(for:). Look for the parameter to the NS_SWIFT_NAME macro in the the header file to determine how each function may be invoked from Swift. The code required to check if your product has been licensed through FxFactory from a Swift app is extremely simple:
import FxFactory
static func isLicensed() -> Bool {
FxFactory.isInstalled() &&
FxFactory.licensingStatus(for: <UUID>) == .productLicensed
}
Where <UUID> is the string representation of the UUID that uniquely identifies your product within our ecosystem.
If you plan on delivering your software as a codesigned application, remember to add the appopriate entries to the Info.plist of each deliverable bundle (app, plug-in, etc) to allow FxFactory to update your software:
{
"NSUpdateSecurityPolicy": {
"AllowPackages": [
0: "AZLNLGPTT3"
]
"AllowProcesses": {
"AZLNLGPTT3": [
0: "com.fxfactory.FxFactory”,
1: “com.fxfactory.FxFactory.helper”
]
}
}
}
This is discussed in greater detail on Developer.