使用Elm构建iOS应用程序

网友投稿 690 2022-10-17

使用Elm构建iOS应用程序

使用Elm构建iOS应用程序

Elm for iOS

Build iOS apps with Elm. Use native or web UI. Or mix and match.

Continuous integration status:

Example

Let's build a counter:

Functional core

100% platform independent100% type safe100% purely functional

port module Counter exposing (..)type alias Model = Intmodel : Modelmodel = 0type alias Flags = { initialCount : Int }init : Flags -> ( Model, Cmd Msg )init flags = let initialModel = flags.initialCount in ( initialModel, view initialModel )type Msg = Increment | Decrementupdate : Msg -> Model -> ( Model, Cmd Msg )update msg model = let newModel = case msg of Increment -> model + 1 Decrement -> model - 1 command = view newModel in ( newModel, command )type alias View = { count : String }view : Model -> Cmd Msgview model = setCountLabelText (toString model)port userDidTapIncrementButton : (() -> msg) -> Sub msgport userDidTapDecrementButton : (() -> msg) -> Sub msgport setCountLabelText : String -> Cmd msgsubscriptions : Model -> Sub Msgsubscriptions _ = Sub.batch [ userDidTapIncrementButton (\_ -> Increment) , userDidTapDecrementButton (\_ -> Decrement) ]main : Program Flags Model Msgmain = Platform.programWithFlags { init = init , update = update , subscriptions = subscriptions }

Tests:

module Tests exposing (..)import Test exposing (..)import Expectimport Counter exposing (..)model : ( Model, Cmd Msg ) -> Modelmodel = Tuple.firstcommand : ( Model, Cmd Msg ) -> Cmd Msgcommand = Tuple.secondall : Testall = describe "Update" [ describe "Increment" [ test "Change model 1" <| \() -> update Increment 1 |> model |> Expect.equal 2 , test "Change model 2" <| \() -> update Increment 2 |> model |> Expect.equal 3 , test "Send command 1" <| \() -> update Increment 1 |> command |> Expect.equal (setCountLabelText "2") , test "Send command 2" <| \() -> update Increment 2 |> command |> Expect.equal (setCountLabelText "3") ] , describe "Decrement" [ test "Change model 1" <| \() -> update Decrement -1 |> model |> Expect.equal -2 , test "Change model 2" <| \() -> update Decrement -2 |> model |> Expect.equal -3 , test "Send command 1" <| \() -> update Decrement -1 |> command |> Expect.equal (setCountLabelText "-2") , test "Send command 2" <| \() -> update Decrement -2 |> command |> Expect.equal (setCountLabelText "-3") ] ]

Imperative shell

Platform dependentDivided into two parts — safe and unsafe

Safe part:

import UIKitimport Elmfinal class ViewController: UIViewController, Elm { @IBOutlet var countLabel: UILabel? struct Flags { let initialCount: Int } enum Input { case userDidTapIncrementButton case userDidTapDecrementButton } enum Output { case setCountLabelText(String) } override func viewDidLoad() { super.viewDidLoad() start(module: "counter", flags: .init(initialCount: 0)) } @IBAction func userDidTapIncrementButton() { send(.userDidTapIncrementButton) } @IBAction func userDidTapDecrementButton() { send(.userDidTapDecrementButton) } func observe(_ output: Output) { switch output { case .setCountLabelText(let text): countLabel?.text = text } }}

Unsafe part where we convert data between Swift to JavaScript:

extension ViewController.Flags: ElmValue { var javaScript: String { return ["initialCount": initialCount].javaScript }}extension ViewController.Input: ElmInput { var port: (ElmPort, ElmValue?) { switch self { case .userDidTapIncrementButton: return ("userDidTapIncrementButton", nil) case .userDidTapDecrementButton: return ("userDidTapDecrementButton", nil) } }}extension ViewController.Output: ElmOutput { init(port: ElmPort, value: ElmValue) { switch port { case "setCountLabelText": let value = value as! String self = .setCountLabelText(value) default: fatalError() } }}

Build

Add the following Run Script build phase to compile Elm during Xcode build:

elm make "$SRCROOT"/Elm/src/Counter.elm --output "$CONFIGURATION_BUILD_DIR"/"$UNLOCALIZED_RESOURCES_FOLDER_PATH"/counter.js --yes

Notes

Due to this bug, all port modules need to include:

import Json.Decode

Thanks

Questions? Comments? Concerns?

Say hello!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:HTTPS的加密方式以及证书
下一篇:光场(Light Field) 视频应用程序
相关文章

 发表评论

暂时没有评论,来抢沙发吧~