- 印刷する
Webview の配信リストとネイティブ Play の連携
- 印刷する
ハイブリッドアプリを連携する際、配信リストまでネイティブで作り直す必要はありません。Webview のプラグインリストをそのまま使い、配信をタップしたときだけネイティブに渡して再生します。

実装方式の比較
リストもネイティブで実装 リスト UI をネイティブで実装し、項目ごとにプレビュー画面を呼び出します。リストの構成・ページング・状態更新をすべて自前で管理する必要があります。 | Webview のリストを再利用(本ガイド) リストは Webview 内でプラグインの |
Webview とネイティブは別レイヤーです。accessKey はネイティブが既に保持しているため、Webview からネイティブへ渡す値は
campaignKeyひとつだけです。
処理の流れ
- Webview — リストを描画し、タップ時にネイティブへ
campaignKeyを渡す - ネイティブ — 渡された値を受け取る
- ネイティブ — SDK で再生する
ステップ 1. リストの描画とタップ時のネイティブ連携
リストは setOverall が描画します。クリックコールバックはネイティブインターフェースが無い場合、自動的に既定の Web モーダル再生として動作するため、Web でもハイブリッドアプリでも同じページを安全に配置できます。
iOS の Webview では、インライン再生のために
WKWebViewConfigurationのallowsInlineMediaPlayback = trueが必要です。(下記コードとは別の、Webview 自体の設定です。)
JavaScript
<script src="https://static.shoplive.cloud/shoplive.js"></script>
<script>
var accessKey = 'YOUR_ACCESS_KEY';
var messageCallback = {
ON_CLICK_CAMPAIGN_LIST_ITEM: function (payload) {
var APP_INTERFACE = "ShopLiveAppInterface";
var campaignKey = payload.campaignKey;
if (window[APP_INTERFACE]) {
// Android, Flutter - どちらも postMessage(String) のみ対応
window[APP_INTERFACE].postMessage(campaignKey);
} else if (window.webkit?.messageHandlers?.[APP_INTERFACE]) {
// iOS
window.webkit.messageHandlers[APP_INTERFACE].postMessage(campaignKey);
} else {
// ネイティブインターフェースが無い場合(通常の Web)は Web モーダルで
cloud.shoplive.showFeaturedPlayerModal({ campaignKey: campaignKey });
}
}
};
cloud.shoplive.init({ accessKey: accessKey, messageCallback: messageCallback });
</script>
<div id="shoplive-overall"></div>
<script defer>
cloud.shoplive.setOverall('shoplive-overall');
</script>ステップ 2. ネイティブでの受け取り
上記コードが呼び出すインターフェース名(ShopLiveAppInterface)をネイティブ側にそのまま登録します。この登録処理は Shoplive SDK の機能ではなく、Webview が標準で提供する JS↔ネイティブ通信の仕組みです。やり取りするのは campaignKey 文字列ひとつだけなので、3 プラットフォームとも解析なしでそのまま受け取れます。
iOS では
userContentController.add()を WKWebView 生成前、つまりこの configuration で Webview を作成する前に呼び出す必要があります。
Kotlin · Android
webView.addJavascriptInterface(ShopLiveAppInterface(activity), "ShopLiveAppInterface")
class ShopLiveAppInterface(val activity: Activity) {
@JavascriptInterface
fun postMessage(campaignKey: String) {
activity.runOnUiThread {
/* ステップ 3: ShopLive.play() を呼び出す */
}
}
}Swift · iOS
configuration.userContentController.add(self, name: "ShopLiveAppInterface")
func userContentController(_ controller: WKUserContentController,
didReceive message: WKScriptMessage) {
guard message.name == "ShopLiveAppInterface",
let campaignKey = message.body as? String else { return }
// ステップ 3: ShopLive.play() を呼び出す
}Dart · Flutter
controller.addJavaScriptChannel(
'ShopLiveAppInterface',
onMessageReceived: (JavaScriptMessage message) {
final campaignKey = message.message;
// ステップ 3: ShopLive.play() を呼び出す
},
);このブリッジは Webview 内のどの JavaScript からも呼び出せます。Webview が自社ページ以外の URL(商品リンクなど)へ遷移し得る場合、そのページからも
ShopLiveAppInterfaceを呼べるということです。外部遷移は新規ウィンドウまたは外部ブラウザで開き、Webview 内には自社ページのみが残る構成を推奨します。
ステップ 3. ネイティブでの再生
ブリッジで受け取った campaignKey ひとつで、3 プラットフォームとも同じ形で正式なプレーヤーを起動できます。(ゲスト再生の場合。ネイティブ SDK が accessKey で初期化済みであることが前提です — Android ShopLive.setAccessKey、iOS ShopLive.configure)
Kotlin · Android
ShopLive.play(activity, ShopLivePlayerData(campaignKey))Swift · iOS
ShopLive.play(data: .init(campaignKey: campaignKey))Dart · Flutter
shopLivePlayer.play(data: ShopLivePlayerData(campaignKey: campaignKey));ログインユーザーとして再生する(任意)
ゲスト再生であればこのステップは省略できます。決めることは 2 つです — どの方式で認証するか、その値をどこから取得するか。
認証方式
A · セキュア認証 加盟店サーバーが署名した JWT で検証します。 | B · 簡易認証 署名・サーバー検証なしで |
A · セキュア認証(JWT)
Kotlin · Android
ShopLive.setAuthToken(jwt) // play() の呼び出し前Swift · iOS
ShopLive.authToken = jwtDart · Flutter
shopLiveCommon.setAuthToken(userJWT: jwt);JWT は Shoplive が発行したシークレットキーを使い、加盟店サーバーが自ら署名して生成します。Webview プラグインで使用した JWT と同じユーザー基準で発行してください。
B · 簡易認証(userId)
Kotlin · Android
ShopLive.setUser(ShopLiveCommonUser(userId))Swift · iOS
ShopLiveCommon.setUser(user: ShopLiveCommonUser(userId: userId))Dart · Flutter
shopLiveCommon.setUser(user: ShopLiveCommonUser(userId: userId));値の取得元
上記の認証値を play() 呼び出し前にどこから取得するかは、ハイブリッドアプリのログイン構成によって分かれます。
A · ネイティブがログインを管理 ネイティブアプリが既に値を保持しています。ブリッジの payload はそのままにし、 | B · ログインが Webview セッションのみに存在 ネイティブはユーザー情報を知りません。ステップ 1 のブリッジ payload に値を載せて送り、ネイティブはその値で上記 API を呼び出します。 |
B の場合は文字列ひとつでは足りないため、ステップ 1 のコードをオブジェクトに変更して値を一緒に送り、ステップ 2 も文字列ではなく JSON/オブジェクトを解析するように変更する必要があります。(以下は JWT を例とした実装です)
JavaScript · ステップ 1 のコード拡張
var bridgePayload = { campaignKey: campaignKey, authToken: currentUserJWT };
if (window[APP_INTERFACE]) {
window[APP_INTERFACE].postMessage(JSON.stringify(bridgePayload));
} else if (window.webkit?.messageHandlers?.[APP_INTERFACE]) {
window.webkit.messageHandlers[APP_INTERFACE].postMessage(bridgePayload);
}