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

UITableViewでTableViewCell(Xib)を使ってみた

はじめに どうも、はじめです。 今回はXib(TableViewCell)を使用したカスタムセルの使い方を書いてみようと思います。   前提条件 Swift 3.1   事前準備 ...

【Swift】FabricからFirebase CrashLyticsのアップデート

はじめに こんにちは、suzukiです。今回は下記2点の問題を解決するための記事です。 11月15日から古いライブラリのクラッシュレポートの送信ができなくなる 最近リリースした際にFabricのdsy ...

swift

Swiftでのパーミッション取得を簡単に

はじめに こんにちは、nukkyです。 今回は、アプリにはつきもののユーザへのパーミッションの確認を 簡単に行えるライブラリを紹介したいと思います。 これ何かと忘れがちですし急遽追加したいとなった時に ...

swift

Swift3でMapKitの吹き出し(Callout)タップを取得したい!

はじめに こんにちは、nukkyです。 今回、iOSのMapKitでGoogleMapのように 吹き出しのタップを取得しようと思ったのですが、 これが案外簡単にいかなかったというか無理矢理やりました。 ...

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzukiです。今回wwdcでも発表のあったプライバシーマニフェストについて、現時点でわかっている内容の整理も兼ねてまとめました。 特に重要な点としては2023年秋から開始され ...

フォロー

blog-page_side_responsive

2020年4月
日 月 火 水 木 金 土
 1234
567891011
12131415161718
19202122232425
2627282930  

アプリ情報

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