Mobile apps
This page is for developers. The Android and iOS SDKs open a channel full screen inside your app and tell your app what happens in the game. Flutter and React Native apps use a web view for now.
The SDKs show the same games, pre-game pages and reward pages as the web, from
https://play.keliplay.com. When a game is updated, your app gets the update
without a new release.
Install
Section titled “Install”Android 6.0 (API 23) or later. The SDK is on Maven Central:
dependencies { implementation("com.keliplay:games-sdk:0.1.0")}iOS 14 or later. Add the KeliplayGames package with Swift Package Manager: in Xcode, choose File, then Add Package Dependencies, and enter the Keliplay iOS SDK repository address.
Show a game
Section titled “Show a game”-
Register your app. In the dashboard, open Settings, then Allowed origins, choose Add origin and pick Android app or iOS app. Enter the app’s application id or bundle id, such as
com.example.app. See Allowed origins. -
Mint the token on your backend. When the app is about to show the game, it asks your backend for a client token. Your backend mints one with
originset to your registered app,android:com.example.apporios:com.example.app. See Client tokens. Never put your API key in the app.{"channelId": "3f6b1c0a-8e2d-4b7a-9c15-2d4e6f8a0b1c","participantRef": "user_8412","origin": "android:com.example.app"} -
Open the channel. The SDK asks your token provider for a token each time it opens, because a token is good for one play.
KeliplayGames.open( activity, KeliplayGamesConfig( channelId = "3f6b1c0a-8e2d-4b7a-9c15-2d4e6f8a0b1c", playBaseUrl = "https://play.keliplay.com", tokenProvider = { callback -> backend.mintToken( onSuccess = { token -> callback.onToken(token) }, // null between campaigns onError = { error -> callback.onFailure(error) }, ) }, ),) { event -> when (event) { is KeliplayGameEvent.SessionCompleted -> showThanks(event.score) is KeliplayGameEvent.Closed -> refreshHome() else -> Unit }}import KeliplayGames
let config = KeliplayGamesConfig( channelId: "3f6b1c0a-8e2d-4b7a-9c15-2d4e6f8a0b1c", playBaseURL: URL(string: "https://play.keliplay.com")!, tokenProvider: { completion in backend.mintToken { result in completion(result) } // Result<String?, Error> })
try KeliplayGames.shared.open(from: self, config: config) { event in switch event { case .sessionCompleted(_, let score, _): showThanks(score) case .closed: refreshHome() default: break }}When nothing is live on the channel, your backend gets a null token. Pass it on:
the screen shows the channel’s between-campaigns message instead of an error.
close() closes the game screen from your code. Players close it with the back
button on Android, and with the close button on iOS.
Events
Section titled “Events”Events arrive on the main thread, in order. Nothing follows Closed.
| Event | When |
|---|---|
Ready |
The game has loaded and the player can play. |
SessionStarted |
A play has started and counts towards the player’s limit. |
OutcomeRevealed |
An instant-win game has shown its result: a label and whether it is a win. Never a coupon code. |
SessionCompleted |
The play is over and scored. |
Error |
Something went wrong. See the codes below. |
Closed |
The game screen has gone. The reason is USER_DISMISSED, PROGRAMMATIC, AFTER_COMPLETE or ERROR. |
Coupon codes and winners reach your backend through webhooks, never through the app.
Error codes
Section titled “Error codes”The codes are the same on both platforms. GAME_REPORTED keeps the game open;
every other code is followed by Closed.
| Code | Meaning |
|---|---|
NO_TOKEN |
Your token provider failed, or did not answer in time. |
NETWORK_UNAVAILABLE |
The device is offline. |
LOAD_FAILED |
The game could not load. |
HTTP_ERROR |
The game’s page answered with an error. |
SSL_ERROR |
The secure connection failed. The SDK never continues past a certificate error. |
BLOCKED_ORIGIN |
Something tried to leave the Keliplay play address. Links a player taps open in the browser. |
LOAD_TIMEOUT |
The first page did not finish loading in time. |
RENDER_PROCESS_GONE |
The system stopped the web view. |
BAD_MESSAGE |
The game sent something the SDK did not recognise. |
GAME_REPORTED |
The game reported a problem. The game stays open. |
Options
Section titled “Options”| Option | Default | Description |
|---|---|---|
channelId |
The channel to open. Required. | |
playBaseUrl (Android), playBaseURL (iOS) |
https://play.keliplay.com. Required. |
|
tokenProvider |
Fetches a client token from your backend. | |
theme |
the game’s own | LIGHT or DARK (Android), .light or .dark (iOS). |
locale |
the game’s own | A language tag such as en-GB. |
orientation |
any | Lock the game screen to portrait or landscape. Your app’s own orientation is untouched. |
loadTimeoutMs / loadTimeout |
30 seconds | How long the first page may take to load. Time a player spends on the pre-game page is never counted. |
tokenTimeoutMs / tokenTimeout |
15 seconds | How long your token provider may take. |
showsCloseButton (iOS) |
true |
Turn off only if your app closes the game itself with close(). |
On iOS, open throws if the screen you call it from cannot show the game right
now, for example because it is already showing something else.
How it looks
Section titled “How it looks”The game fills the screen. Its background, its position on the screen and any decorations come from the campaign’s Branding tab, so you can change them without an app release.
Flutter and React Native
Section titled “Flutter and React Native”Host a small page on your own site that embeds the channel with the web SDK, then open that page in a web view.
-
Add your site to allowed origins. The page is served from your site, so its address is the origin to allow, for example
https://app.example.com. -
Mint the token on your backend. Your backend mints a client token with
originset to your site and returns a link to the page, for examplehttps://app.example.com/play#token=.... Putting the token after#keeps it out of server logs. -
Mount the game on the page. The page reads the token from
location.hashand callsKrdsGames.mountwith your channel id. -
Open the page in a web view. Use
webview_flutterin Flutter orreact-native-webviewin React Native, with JavaScript enabled.
To pass game events to the app, forward them through the web view’s message bridge:
const game = KrdsGames.mount('#keliplay-game', { channelId, clientToken, playBaseUrl })
game.on('session_completed', (payload) => { const message = JSON.stringify({ type: 'session_completed', score: payload.score }) if (window.ReactNativeWebView) window.ReactNativeWebView.postMessage(message) else if (window.KeliplayFlutter) window.KeliplayFlutter.postMessage(message)})Register the matching handler: onMessage in React Native, or a
JavaScriptChannel named KeliplayFlutter in Flutter. Load the page again with a
new token for each play.