Platform API
A Platform and its content can be launched both programmatically and via a Platform manifest. Here we will explain the mechanisms that allow Application Providers to start a Platform and launch content into that Platform. As a best practice, we recommend leveraging a custom Platform Provider rather than in a snapshot on the Platform manifest.
Use the Platform API to:
- Launch a platform, create a window and add a view
- Launch content in a view
- Configure a layout
- Save and restore a snapshot
System requirements
- OpenFin CLI installed
- Windows 7 or 10+, Mac can be used for developer purposes
Launch a Platform
In order to use the API, your window must be a part of a manifest-launched platform. Let's launch one.
Copy the following manifest and save as app.json
locally:
{
"platform":
{
"uuid": "example_platform",
"applicationIcon": "https://openfin.github.io/golden-prototype/favicon.ico",
"autoShow": false,
"defaultWindowOptions":
{
"cornerRounding":
{
"height": 10,
"width": 10
},
"contextMenu": true
}
},
"snapshot":
{
"windows":
[
{
"defaultWidth": 600,
"defaultHeight": 600,
"layout":
{
"content":
[
{
"type": "stack",
"content":
[
{
"type": "component",
"componentName": "view",
"componentState":
{
"name": "component_A1",
"processAffinity": "ps_1",
"url": "https://www.example.com"
}
},
{
"type": "component",
"componentName": "view",
"componentState":
{
"name": "component_A2",
"url": "https://cdn.openfin.co/embed-web/chart.html"
}
}
]
}
]
}
},
{
"defaultWidth": 600,
"defaultHeight": 600,
"defaultLeft": 200,
"defaultTop": 200,
"layout":
{
"content":
[
{
"type": "stack",
"content":
[
{
"type": "component",
"componentName": "view",
"componentState":
{
"name": "component_B1",
"url": "https://openfin.co"
}
}
]
}
]
}
}
]
},
"runtime":
{
"arguments": "--v=1 --inspect",
"version": "stable"
},
"shortcut":
{
"company": "OpenFin",
"description": "OpenFin Platforms Prototype",
"icon": "https://openfin.github.io/golden-prototype/favicon.ico",
"name": "OpenFin Platforms Prototype"
}
}
Now let's launch it!
openfin -l -c app.json
Create a platform window
Now that we have our platform, let's create a new platform window, along with a platform view, using Platform.createWindow.
Open your developer console from a platform view and enter the following code:
let platform = await fin.Platform.getCurrent();
let myWinIdentity = await platform.createWindow({
contextMenu: true,
layout: {
content: [{
type: 'stack',
content:[{
type: 'component',
componentName: 'view',
componentState: {
name: 'my-new-test-view',
url: 'http://www.example.com' // The URL of the View
}
}]
}]
}
});
Add a view to an existing window
From the same view (and console), lets add an additional view to that window using Platform.createView():
// The `platform`and `myWinIdentity` here are the objects we captured in step above
platform.createView(
{ // View Configuration Options
name: 'my-new-test-view-2',
url:'http://www.example.com'
},
myWinIdentity // Target Identity
);
The Platform.createView leverages two arguments:
- View configuration options: the name, URL of the window and any other view options
- Target identity: the identity of the window to which the view will be attached.
You do not need to set a name for a view. Views that are not passed a name get a randomly generated one.
Launch content in a view
Content can be launched via manifest by calling the launchContentManifest()
method on a wrapped platform instance. If the manifest to be launched contains a snapshot
object, that snapshot is launched.
API calls
Once a platform is launched and running, snapshots can be launched into the platform using applySnapshot
. Content can also be launched into the platform by manifest using startFromManifest
. If that manifest also contains a snapshot
object, that snapshot is launched. Any view specified in the snapshot is assigned a randomly generated name to avoid collisions.
applySnapshot()
: A snapshot creates any windows and views that are not running in the snapshot
object.
// Get a wrapped layout platform instance
const platform = await fin.Platform.getCurrent();
const snapshot = {
windows: [
{
layout: {
content: [
{
type: 'stack',
content: [
{
type: 'component',
componentName: 'view',
componentState: {
name: 'component_X',
url: 'https://www.openfin.co'
}
},
{
type: 'component',
componentName: 'view',
componentState: {
name: 'component_Y',
url: 'https://cdn.openfin.co/embed-web/chart.html'
}
}
]
}
]
}
}
]
}
platform.applySnapshot(snapshot);
createWindow()
: creates a new platform window with default window UI
const platform = fin.Platform.getCurrentSync();
platform.createWindow({
layout: {
content: [
{
type: 'stack',
content: [
{
type: 'component',
componentName: 'view',
componentState: {
name: 'test_view_1',
url: 'https://developer.openfin.co/docs/javascript/stable/classes/OpenFin.Platform.html'
}
},
{
type: 'component',
componentName: 'view',
componentState: {
name: 'test_view_2',
url: 'https://developer.openfin.co/docs/javascript/stable/classes/OpenFin.Platform.html'
}
}
]
}
]
}
}).then(console.log);
createView()
: Creates a new platform view and attaches it to a specified target window.
let windowIdentity;
if (fin.me.isWindow) {
windowIdentity = fin.me.identity;
} else if (fin.me.isView) {
windowIdentity = (await fin.me.getCurrentWindow()).identity;
} else {
throw new Error('Not running in a platform View or Window');
}
const platform = fin.Platform.getCurrentSync();
platform.createView({
name: 'test_view',
url: 'https://developers.openfin.co/docs/platform-api'
}, windowIdentity).then(console.log);
Deep linking (fin
/ fins
link)
fin
/ fins
link)The RVM permits deep linking to an OpenFin application from anywhere that can invoke a “link” like a browser, email client, or another OpenFin application. The RVM uses a custom protocol handler to invoke an application, if not already running, and pass context to a specific location within an OpenFin application via a uniform resource identifier (URI).
You can use a fins
link to both start a platform and to launch content into a platform. A link that targets a single platform manifest starts the platform, if the platform is not already running, and launches a snapshot into the platform, if present in the manifest.
You can also designate a separate content manifest to be launched into the platform by targeting the platform manifest and adding an $$appManifestUrl parameter
. This starts the platform, if not already running, but launches the content in the second manifest at the $$appManifestUrl
location. If an $$appManifestUrl
parameter is included, any snapshot that exists on the platform manifest is ignored and only the content designated at the appManifestUrl
is launched.
Like the launchContentManifest()
method, if the manifest at the $$appManifestUrl
location contains a snapshot
object, that snapshot is launched. If instead it is a legacy manifest without a snapshot, the startup_app
is launched as a single View in the Layout of a new OpenFin Window.
fins://mydomain.com/path-to-platform-manifest/app.json?$$appManifestUrl=https://mydomain.com/path-to-content-manifest/
If both snapshot
and startup_app
object are present in the $$appManifestUrl
location, the following hierarchy of which of these is used applies:
startup_app
is always used if you are launching the manifest in a traditional way through the RVM.snapshot
is used only if the manifest is passed via the$$appManifestUrl
.
Changes to $$appManifestUrl
$$appManifestUrl
As part of OpenFin's effort to provide a secure and more controlled development environment, starting in Runtime version 36, behavior of the $$appManifestUrl
parameter changes from earlier versions.
Starting in version 36, using the $$appManifestUrl
parameter causes warning messages to appear in the Platform provider window console unless you specifically opt-in or opt-out of the allowLaunchIntoPlatform
manifest property.
To opt-in, set the allowLaunchIntoPlatform
property value to true
as shown below. To opt-out, set the allowLaunchIntoPlatform
property value to false
.
{
...
"platform": {
"allowLaunchIntoPlatform": true
}
}
If the allowLaunchIntoPlatform
property does not exist in the manifest file, the warnings appears at each launch that uses $$appManifestUrl
.
Starting in Runtime version 38, use of the $$appManifestUrl
parameter is disabled by default (opt-out behavior).
The warning messages appear in the Platform provider window console. However, the platform does not launch the new content.
To enable the $$appManifestUrl
parameter for Runtime versions 38 and later, set the allowLaunchIntoPlatform
manifest property to true
as shown above.
Configure a layout
OpenFin platforms allow end-users the freedom to easily move views within an OpenFin window to create their own customized workspace. Application providers may also wish to have presets that launch multiple views in a pre-configured window arrangement. Here we cover three basic layout configurations for tabs, columns and rows and a grid.
Tabs
//A window object within a snapshot that has one tabset (or “stack”) with three views represented as tabs.
{
"content": [
{
"type": "stack",
"content": [
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_E",
"url": "https://cdn.openfin.co/embed-web/chart.html"
}
},
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_F",
"url": "https://openfin.co"
}
},
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_G",
"url": "https://www.example.com"
}
}
]
}
]
}
Columns and rows
//A window object within a layout that has three views arranged as columns.
"content": [
{
"type": "row",
"content": [
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_C",
"url": "https://cdn.openfin.co/embed-web/chart.html"
}
},
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_D",
"url": "https://openfin.co"
}
},
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_E",
"url": "https://www.example.com"
}
}
]
}
]
Grid
//A window object within a snapshot that has four views arranged as a 2x2 grid.
{
"content": [
{
"type": "row",
"content": [
{
"type": "row",
"content": [
{
"type": "column",
"content": [
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_A",
"url": "https://cdn.openfin.co/embed-web/chart.html"
}
},
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_B",
"url": "https://cdn.openfin.co/embed-web/chart.html"
}
}
]
}
]
},
{
"type": "row",
"content": [
{
"type": "column",
"content": [
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_C",
"url": "https://www.example.com"
}
},
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_D",
"url": "https://www.openfin.co"
}
}
]
}
]
}
]
}
]
}
Snapshots
Earlier, we loaded a brand-new Platform Window with two Views in it. Here we will retrieve getSnapshot
a Platform Layout and apply applySnapshot
a previously saved Platform layout.
Get snapshot
Use the following code in the same console you were using in the Add a View to an Existing Window. Platform.getSnapshot returns a snapshot object and can be used to return the desktop back to this current state. You can store this object wherever you'd like, and use it later to apply this Snapshot.
// The `platform` here is the object we captured
const mySnapshot = await platform.getSnapshot();
console.log(mySnapshot);
Apply snapshot
Now let’s use our snapshot object to recreate our desktop using applySnapshot. First, rearrange your platform windows on your desktop.
- Close the window you created earlier (the one filled with www.example.com Views), move your windows to different locations.
- Move the views in their platform windows to different locations.
- Execute the code below to get your desktop back to the way it was before.
// The `platform` here is the object we captured
platform.applySnapshot(mySnapshot, {closeExistingWindows: true});
How a window can opt out of snapshots
There are some occasions where you may not want a window to be included in snapshots.
To make a window opt out of snapshots, set the window.includeInSnapshots
property to false
. To include the window in snapshots again, set the window.includeInSnapshots
property to true
.
Platform manifest
Here we will breakdown the various pieces of the OpenFin platform manifest file.
platform
: Defines the platform as a targetable unique entity. Requires a top-level platform
property and a UUID
. If you are previous accustomed to OpenFin manifest structure, platform acts in the same way as your startup_app
field.
{
"runtime": {
...
},
"shortcut": {
...
},
"platform": {
"uuid": "platform-example",
"defaultWindowOptions": {
"stylesheetUrl": "full-url-to-css-sheet",
"cornerRounding": {
"height": 10,
"width": 10
}
}
}
}
snapshot
: Defines the window and view configurations to be launched into a platform. If a snapshot
is defined as a top-level option in your platform manifest, the platform launches with that snapshot by default. It has a windows
property that contains an array of OpenFin Window objects. Windows should not be given names, because they can be destroyed and re-created by the user at any time.
{
"snapshot": {
"windows": [
{
"defaultWidth": 600,
"defaultHeight": 600,
"layout": {
...
}
}
]
}
}
layout
: Defines the layout configuration for a window. To position an OpenFin view within a window, your layout must contain a content declaration with a componentName of view. Content items have a "type" property, which can have the following values: "row", "column", "stack", or "component". Arrays of content items can be nested within other content items as well.
{
"snapshot": {
"windows": [
{
"defaultWidth": 600,
"defaultHeight": 600,
"layout": {
"content": [
{
"type": "stack",
"content": [
{
"type": "component",
"componentName": "view",
"componentState": {
...
}
},
{
"type": "component",
"componentName": "view",
"componentState": {
...
}
}
]
}
]
}
}
]
}
}
componentState
: Defines the componentState property to provide the OpenFin view options. The URL of a manifest that contains View Options can additionally be added as a manifestUrl
property. Properties in the manifest take precedence if there is any collision.
{
"snapshot": {
"windows": [
{
"defaultWidth": 600,
"defaultHeight": 600,
"layout": {
"content": [
{
"type": "stack",
"content": [
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_A1",
"processAffinity": "ps_1",
"url": "https://www.example.com"
}
},
{
"type": "component",
"componentName": "view",
"componentState": {
"name": "component_A2",
"url": "https://cdn.openfin.co/embed-web/chart.html"
}
}
]
}
]
}
}
]
}
}
Updated 6 months ago