iOS

【Swift】SwiftUIの理解のためDSL記法とFunctionBuilderを調べてみた

投稿日:

はじめに

Xcode11でSwiftUIという機能が追加されました。iOSの開発者になってから、StoryboardとSwiftと同じような大きな影響が今後出てくるのではないかと思っております。今回はSwiftUIの記述方法にも関係しているDSLとDSLを実現するための関数ビルダという機能について触れていこうと思います。macOS10.15じゃないとCanvasという機能が使えず、せっかくなので少し背景を調べたものとなります。

DSL(ドメイン固有言語)について

SwiftUIを調べていると出てくるDSLという言葉、何らかの問題領域や処理対象向けに特化した記述言語を指します。
しかしこのような機能があればDSLであるとか、このような水準に達していれば汎用言語であるといったような厳密な基準や定義はないらしいです。
例としてWebページ記述のためのHTML、スタイル記述言語のCSS、データベースへの問い合わせ言語SQLのようなものDSLと思ってください。

またrailsにおけるテストフレームワークのRSpecのように開発用言語の中にその一部として記述できるDSLを埋め込みDSLといい
SwiftUIはユーザーインターフェースに特化したSwiftの埋め込みDSLとなります。
SwiftUIは文字列を表示する場合などは下記のようにシンプルに記述できます。

また文字の色を変更したい時や、その他のプロパティを設定したい場合は、下記のように続けて表記することで、シンプルかつわかりやすく記述することができます。

関数ビルダ

関数ビルダとはプログラム中に記述されたDSLの構文要素を組み合わせ、Swiftのインスタンスを生成する関数を作る仕組みです。SwiftUIのような埋め込みDSLを実装するための中心的な機能です。

定義方法

ひとまとまりのDSL記述は、全体として一つのSwiftのインスタンスとして解釈されます。
@functionBuilder(Xcode11.3では@_functionBuilder)という属性を指定することで定義が可能です。
buildBlock関数はこの関数ビルダを利用する際に暗黙的に呼び出されインスタンスを返却します。

使用方法

関数ビルダを使用するためには「@」+関数ビルダ型の名前をつけることで利用できます。今回であれば @ArrayMaker です。
実際に記述してみましょう。シンプルな書き方であると下記のような形です。

ArrayMakerではジェネリクスを利用しているので、型はなんでもいいので、文字列でもIntでも作成可能です。
また書かれている内容を見ると普段のSwiftのコードとは異なることがわかるかと思います。関数ビルダの関数内部には式を文として列挙できます。
式文 と呼ばれ、文なので改行や[;]が区切りとなります。

先ほどのような使い方では関数ビルダを利用するメリッとが不明かもしれません。実際に使われる方法としては下記のような使われ方がされます。
クロージャを引数とする関数を定義してクロージャの引数で関数ビルダを使用します。先ほどと行なっていることは変わらないですが、使いやすそうです。

SwiftUIの関数ビルダ

せっかくなのでSwiftUIのToggleのコードで実際にどのように使われているかみていきます。

initの中の @ViewBuilder label: labelとしてクロージャを引数とする関数を定義しています。

ViewBuilder側では下記のbuildBlockが呼ばれていることでしょう。

カスタム属性

今回のfunctionBuilderはカスタム属性の一種です。Swift5.1から他にも下記のようなカスタム属性が追加されています。
どれもこれも理解が及んでいませんが、SwiftUIの後に改めて調べていこうと思います。
@propertyWrapper
@dynamicCallable
@dynamicMemberLookup

さいごに

最後までありがとうございました。アプリの開発では特に意識をしていなかったので、理解を進めるのにとても時間がかかりました。もうすぐiOS13が出るのに、開発アプリの下限対象がiOS9です。自分の頭もそれぐらいで止まっている気がしてきたので、少しずつバージョンアップしていきます。

おすすめ書籍

[改訂新版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 WEB+DB PRESS plus 詳解 Swift 第4版 [改訂新版]Swiftポケットリファレンス (POCKET REFERENCE)

blog-page_footer_336




blog-page_footer_336




-iOS
-

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

swift

[Swift3] スクロールする画面に固定でボタンを表示する方法

1 はじめに1.1 前提条件2 Storyboardの準備3 Controllerの実装3.1 スクロールする画面の実装(TableView)3.2 固定で表示するボタンを配置している画面の実装(Co ...

iOS13で申請するために押さえておきたいポイント

1 はじめに2 presentViewController3 DeviceToken4 Launch Storyboard5 Dark Mode6 Sign In with Apple7 さいごに8 ...

iOSでFirebase Authenticationを実装してみる その1

1 はじめに2 Firebaseプロジェクトの設定3 新規ユーザー登録4 既存ユーザーのログイン5 匿名ログイン6 エラーメッセージ7 最後に8 おすすめ書籍 はじめに はじめまして、Yossyです。 ...

swift

Swift3 StoryBoard上でUIButtonやUILabel、UIViewのcornerを変更する

1 はじめに1.1 前提条件2 StoryBoardの準備3 カスタムクラスの作成3.1 class ~について3.2 @IBDesignableを記述すると3.2.1 Live Renderingと ...

swift

[Swift]通信状況を取得できるReachability.swiftを使ってみた

1 はじめに2 準備3 実装3.1 通信状況を確認する3.2 通信可能になった時に通知する4 さいごに はじめに こんにちは、nukkyです。 今回は端末の通信状況を取得できるReachability ...

フォロー

blog-page_side_responsive

2020年4月
 1234
567891011
12131415161718
19202122232425
2627282930  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。