Skip to content

Instantly share code, notes, and snippets.

@k-motoyan
Created December 16, 2018 10:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save k-motoyan/c4be847b2b36060f2cbb410df7076c20 to your computer and use it in GitHub Desktop.
Save k-motoyan/c4be847b2b36060f2cbb410df7076c20 to your computer and use it in GitHub Desktop.
Elm <-> Swift
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no">
<title>Elm App</title>
</head>
<body>
<h1>Elm App</h1>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<script src="js/main.js"></script>
<script>
const app = Elm.Main.init({
node: document.getElementById("root"),
flags: 0
});
app.ports.incremented.subscribe((data) => {
try {
webkit.messageHandlers.increment.postMessage(data);
} catch (err) {
console.log(err);
}
});
app.ports.decremented.subscribe((data) => {
try {
webkit.messageHandlers.decrement.postMessage(data);
} catch (err) {
console.log(err);
}
});
</script>
</body>
</html>
port module Main exposing (..)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
type alias Model = Int
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
type Msg = Increment | Decrement | Set Model
init : Maybe Model -> ( Model, Cmd msg )
init flags =
case flags of
Just model ->
( model, Cmd.none )
Nothing ->
( 0, Cmd.none )
port incremented : Model -> Cmd msg
port decremented : Model -> Cmd msg
update msg model =
case msg of
Increment ->
let
newModel = model + 1
in
( newModel, incremented newModel )
Decrement ->
let
newModel = model - 1
in
( newModel, decremented newModel )
Set newModel ->
( newModel, Cmd.none )
port fixModel : (Model -> msg) -> Sub msg
subscriptions model =
fixModel Set
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment ] [ text "+" ]
]
import UIKit
import WebKit
class ViewController: UIViewController, WKScriptMessageHandler {
private var webView: WKWebView!
@IBOutlet private var fixButton: UIButton!
private let baseURL: URL = {
let basePath = Bundle.main.path(forResource: "elm-app/public", ofType: nil)!
return URL(fileURLWithPath: basePath)
}()
private let contents: String = {
let htmlPath = Bundle.main.path(forResource: "elm-app/public/index", ofType: "html")!
return try! String(contentsOfFile: htmlPath, encoding: .utf8)
}()
override func viewDidLoad() {
super.viewDidLoad()
self.setWebView()
self.webView.loadHTMLString(self.contents, baseURL: self.baseURL)
}
private func setWebView() {
let contentController = WKUserContentController();
contentController.add(self, event: .increment)
contentController.add(self, event: .decrement)
let webConfiguration = WKWebViewConfiguration()
webConfiguration.userContentController = contentController
self.webView = WKWebView(frame: .zero, configuration: webConfiguration)
self.webView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(self.webView)
self.view.addConstraints([
self.webView.topAnchor.constraint(equalTo: self.webView.superview!.topAnchor),
self.webView.leftAnchor.constraint(equalTo: self.webView.superview!.leftAnchor),
self.webView.rightAnchor.constraint(equalTo: self.webView.superview!.rightAnchor),
self.webView.bottomAnchor.constraint(equalTo: self.fixButton.topAnchor, constant: -10)
])
}
@IBAction private func onTapFixButton(sender: UIButton) {
let js = "app.ports.fixModel.send(10);"
self.webView.evaluateJavaScript(js) { _, error in
if let error = error {
print(error)
}
}
}
// MARK: - WKScriptMessageHandler
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
switch message.name {
case ElmEvent.increment.rawValue:
print("increment")
case ElmEvent.decrement.rawValue:
print("decrement")
default:
assertionFailure()
}
print(message.body)
}
}
enum ElmEvent: String {
case increment, decrement
}
private extension WKUserContentController {
func add(_ scriptMessageHandler: WKScriptMessageHandler, event: ElmEvent) {
self.add(scriptMessageHandler, name: event.rawValue)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment