The SDK offers a simple interface that allows you to offer Experiences to your users in few lines of code.
An app can be configured to exist as an embed within a written article, rather like a widget. But you can also set the same app to display full page with its header and footer.
By default, the SDK will respect the height specified within your application and display a scrollbar when necessary so the user can navigate the full content.
However, the SDK can automatically manage the height of the view for you, by respecting the width set and updating the height to match that of the content in the app:
Note: This feature only works with FanKit versions 24.33.0 or later. Non-FanKit applications may not support the behaviour.
let config = ExperienceConfiguration(
autoresizesHeight: true
)
let experience = Launcher.getExperience(config: config)
<yourView>.addSubview(experience)
// You need to ensure you layout the experience correctly using autolayout,
// but ensure you don't constraint yet the height of the view
// (or use a low priority constraint), as that will be managed by the SDK.
//
// For instance, to attach to the top, and both sides, start with
// 300px height, and eventually let the SDK manage the height,
// you'd use the following code:
experience.translatesAutoresizingMaskIntoConstraints = false
experience.topAnchor.constraint(equalTo: <yourView>.topAnchor, constant: 0).isActive = true
experience.leadingAnchor.constraint(equalTo: <yourView>.leadingAnchor, constant: 0).isActive = true
experience.trailingAnchor.constraint(equalTo: <yourView>.trailingAnchor, constant: 0).isActive = true
// Setting default low priority on the constraint so the height
// constraint set by the SDK overrules it.
let heightConstraint = experience.heightAnchor.constraint(equalToConstant: 300)
heightConstraint.priority = .defaultLow
heightConstraint.isActive = true
// Assumes `this` is an activity, otherwise update this line
// to locate the context you want to use.
val context = this
val config = ExperienceConfiguration(
autoresizesHeight = true
)
val experienceView = Launcher.default.getExperience(context, config)
root_container.addView(experience)
Additionally, the SDK lets you listen to changes in the intrinsic size of the web page, so you can handle the resize with your preferred approach:
let experience = Launcher.getExperience()
// Assumes that we want to embed in the ViewController's view
// If you want to embed somewhere else use the relevant view instead
<yourView>.addSubview(experience)
// You need to ensure the experiences are laid out however you see fit.
// For instance, could use autolayout constraints, or setting
// their frame
// Assumes `self` implements ExperienceViewDelegate
experience.delegate = self
// Example implementation of ExperienceViewDelegate
extension MyViewController: ExperienceViewDelegate {
// [...]
// Implementation of the rest of ExperienceViewDelegate
// [...]
func didChangeIntrinsicSize(experienceView: ExperienceView, size: CGSize) {
// Here you can update your size as needed
}
}
// Assumes `this` is an activity, otherwise update this line
// to locate the context you want to use.
val context = this
val experienceView = Launcher.default.getExperience(context, config)
experience.listener = object: ExperienceViewListener {
override fun onIntrinsicSizeChanged(experienceView: ExperienceView, width: Float, height: Float) {
// Here you can update your size as needed
}
}
const exp = getExperience();
onIntrinsicSizeChanged(exp, (width, height) => {
// Here you can update your size as needed
});
await embed(exp, 'container-id');
Launch a specific Event
By default, the SDK will launch the app without specifying a specific event and will use the project's default Event.
If you want to launch to a specific event, you can do so by specifying the Event ID using the example below. To retrieve and determine the event you want, refer to Getting and displaying Events
let eventId = "<event id>"
let config = ExperienceConfiguration(
eventId: eventId
)
let experience = Launcher.getExperience(config: config)
<yourView>.addSubview(experience)
// You need to ensure the experiences are laid out however you see fit.
// For instance, could use autolayout constraints, or setting
// their frame
val eventID = "<event id>"
val config = ExperienceConfiguration(eventId = eventID)
val experienceView = Launcher.default.getExperience(context, config)
root_container.addView(experience)
const eventId = '<event id>';
const experience = getExperience({
eventId,
// Other ExperienceConfiguration values can be added,
// such as autoresizesHeight, hidesHeadersAndFooters, etc...
});
await embed(experience, 'container-id');
Provide custom parameters
The SDK allows you to provide custom query parameters in LauncherKit to customise the app you embed. How the app responds depends on how it was created so this is general feature available for developers.
You can use it as follows:
let parameters = ["customKey": "customValue"]
let config = ExperienceConfiguration(
parameters: parameters
)
let experience = Launcher.getExperience(config: config)
<yourView>.addSubview(experience)
// You need to ensure the experiences are laid out however you see fit.
// For instance, could use autolayout constraints, or setting
// their frame
val config = ExperienceConfiguration(
parameters = hashMapOf("customKey" to "customValue")
)
val experienceView = launcher.getExperience(
context,
config
)
root_container.addView(experience)
By default, the SDK will use the loading view from the app itself. You can enable a custom loading / error view by setting supportsLoadingState to true.
On Android, loading and error views are not supported when using the ExperienceActivity and ExperienceFragment classes rather than ExperienceView as we can't parcelise the view providers.
Use instead an ExperienceView or wrap it with your own Activity or Fragment.
let config = ExperienceConfiguration(
supportsLoadingState: true
)
let experience = Launcher.getExperience(config: config)
<yourView>.addSubview(experience)
// You need to ensure the experiences are laid out however you see fit.
// For instance, could use autolayout constraints, or setting
// their frame
// Assumes `this` is an activity, otherwise update this line
// to locate the context you want to use.
val context = this
val config = ExperienceConfiguration(
supportsLoadingState = true
)
val experienceView = Launcher.default.getExperience(context, config)
root_container.addView(experience)
When enabled, a simple black-on-white loading screen is displayed so as to avoid having a blank screen whilst the app is loaded.
If you want to customise said views, you can do so by passing via ExperienceConfiguration a ViewProvider, which is responsible to create a view to display instead of the default loading/error views.
let config = ExperienceConfiguration(
loadingViewProvider: { MyLoadingView() },
errorViewProvider: { error in MyErrorView(error) }
)
let experience = Launcher.getExperience(config: config)
<yourView>.addSubview(experience)
// You need to ensure the experiences are laid out however you see fit.
// For instance, could use autolayout constraints, or setting
// their frame
// Assumes `this` is an activity, otherwise update this line
// to locate the context you want to use.
val context = this
val myLoadingView = View.inflate(context, R.layout.my_loading_view, null)
val myErrorView = View.inflate(context, R.layout.my_loading_view, null)
val config = ExperienceConfiguration(
loadingViewProvider = { myLoadingView },
errorViewProvider = { errorMessage -> myErrorView }
)
val experienceView = Launcher.default.getExperience(context, config)
root_container.addView(experience)
const exp = getExperience({
loadingTemplate: () => '<div>My custom loading view</div>'
// errorLoadingTemplate not available on Javascript SDK
});
await embed(exp, 'container-id');
Customise Loading timeout
To customise how long the loading view is displayed before transitioning to either the main app view or an error view, you can specify a timeout parameter in your ExperienceConfiguration.
let config = ExperienceConfiguration(
dismissLoadingViewTimeout: <TimeInterval>
)
let experience = Launcher.getExperience(config: config)
<yourView>.addSubview(experience)
// You need to ensure the experiences are laid out however you see fit.
// For instance, could use autolayout constraints, or setting
// their frame
val config = ExperienceConfiguration(
dismissLoadingViewTimeout: <Duration>
)
val experienceView = Launcher.default.getExperience(context, config)
root_container.addView(experience)
Show or hide the app's header and footer
Note: This feature only works on FanKit versions 24.33.0 or later and may not be supported by non-FanKit apps.
By default, the SDK assumes that the parent application will be displaying its own header and footer, and therefore we hide the app's default header if one exists. You can override this behaviour and present the header and footer of the app by using the following snippet:
let config = ExperienceConfiguration(
hidesHeadersAndFooters: false
)
let experience = Launcher.getExperience(config: config)
<yourView>.addSubview(experience)
// You need to ensure the experiences are laid out however you see fit.
// For instance, could use autolayout constraints, or setting
// their frame
// Assumes `this` is an activity, otherwise update this line
// to locate the context you want to use.
val context = this
val config = ExperienceConfiguration(
hidesHeadersAndFooters = false
)
val experienceView = Launcher.default.getExperience(context, config)
root_container.addView(experience)
By default, the SDK does not open hyperlinks externally in the web browser. You can override this behaviour and allow for any link containing the blank target to open in an external app by using the following snippet:
let config = ExperienceConfiguration(
launchesURLsWithBlankTargetToSafari: true
)
let experience = Launcher.getExperience(config: config)
<yourView>.addSubview(experience)
// You need to ensure the experiences are laid out however you see fit.
// For instance, could use autolayout constraints, or setting
// their frame
// Assumes `this` is an activity, otherwise update this line
// to locate the context you want to use.
val context = this
val config = ExperienceConfiguration(
launchesURLsWithBlankTargetToChrome = true
)
val experienceView = Launcher.default.getExperience(context, config)
root_container.addView(experience)