iOS
Swift
Firebase
remoteconfig

Firebase Remote Configの設定値にHTML, JSON, JavaScriptを設定してパース・実行してみた

利用環境

macOS 10.12.6
Xcode 9.2

Firebase Remote Configの設定値の制約

https://firebase.google.com/docs/remote-config/parameters?hl=ja
公式のドキュメントの「パラメータと条件の制限」によると、

Firebase プロジェクト内には、最大 2,000 個のパラメータ、最大 100 個の条件を設定できます。パラメータキーの長さは最大 256 文字で、アンダースコアまたはアルファベット (A~Z、a~z)で始める必要があります。数字を使用することもできます。プロジェクト内のパラメータ値文字列の合計長は、500,000 文字以内にする必要があります。

「パラメータ値文字列の合計が500,000文字以内」ってなかなか上限には達しないけど、もし、この上限まで達するとすれば、どんな文字列があるだろうか・・・・と考えて、検証するのが下記の3つ
・HTML
・JSON
・JavaScript

Firebase Console

Remote Configのコンソール上で、HTML, JSON, JavaScriptを設定する。

firebase_remote_config.png

今回、下記の3つのキーに設定された値を利用する。
・test_html
・test_json
・test_js

WebViewの準備

HTML、JavaScriptの動作検証用に、WKWebViewを配置したViewControllerを用意する。
javascriptがalertが呼ばれた時に何か処理を実行するために、WKUIDelegateも設定

ViewController.swift
import Foundation
import WebKit

class WebViewController: BaseViewController, WKUIDelegate {

    var webView: WKWebView?

    override func viewDidLoad() {
        super.viewDidLoad()

        // webviewの初期化処理
        self.webView = WKWebView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
        self.webView?.uiDelegate = self

        self.view.addSubview(webView!)
    }

    /// WKUIDelegate

    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        print("javascriptでalertが呼ばれた")
    }
}

HTML

HTMLの文字列をパースして、webViewに表示する。

ViewController.swift
override func viewDidLoad(){

    // 中略

    // Firebase Remote Configから"test_html"に設定されたHTMLの文字列を取得する。
    let remoteConfig = RemoteConfig.remoteConfig()
    let remoteConfigSettings = RemoteConfigSettings(developerModeEnabled: true)
        remoteConfig.configSettings = remoteConfigSettings!
        remoteConfig.setDefaults(fromPlist: "remoteConfigDefaults")

    let htmlString = remoteConfig["test_html"].stringValue
    self.webView?.loadHTMLString(htmlString!, baseURL: nil)   
}

JSON

JSONをパースして、コンソールに表示してみる。

ViewController.swift
override func viewDidLoad(){

    // 中略

    // Firebase Remote Configから"test_json"に設定されたJSONの文字列を取得する。
    var escapedJsonString = remoteConfig["test_json"].stringValue
    let jsonData = escapedJsonString?.data(using: .utf8)
    var dict: [String : Any]?
    do{
        dict = try JSONSerialization.jsonObject(with: jsonData!, options: []) as? [String : Any]
        //利用したいデータのkeyを指定してデータ取り出し
    } catch {
        print(error.localizedDescription)
    }
    print(dict)
}

RemoteConfigからjsonを取り出した直後は、ダブルクォートがエスケープされた状態になっている。
JSONパースして、アプリに必要な値は、取り出して画面に反映するのが良さそう。

JavaScript

JavaScript文字列を取得して、webViewで表示中のwebサイトに、javascriptを実行してみる。

ViewController.swift
override func viewDidLoad(){

    // 中略


    // Firebase Remote Configから"test_js"に設定されたJavaScriptの文字列を取得し、実行する
    let jsString = remoteConfig["test_js"].stringValue
    self.webView?.evaluateJavaScript(jsString!, completionHandler: { (obj, error) in })
}

自前の環境の設定値とはいえ、アプリ外から取得したJavaScriptが設定できて、
それを実行できるというのは少々怖い・・・

まとめ

HTML, JSON, JavaScriptをFirebase Remote Configから取得して、それをアプリ側に反映させるのは可能なようだった。
文字列の制限があるから、実際に設定するデータはMinifyしておく必要はありそう。
そうなると、専用のフォームを作ってあげる必要がありそうですね。
Remote ConfigはREST APIが利用可能なため、これを利用した管理ツールを作るのが良さそう。
https://firebase.google.com/docs/remote-config/use-config-rest?hl=ja