見出し画像

SwiftUIでアプリを作ったときの良かった点/苦労した点

はじめに

Appleが去年の6月に発表した新しい開発システムである『SwiftUI』ですが、まだなかなかプロダクト開発のメインで使われているという状況ではないと思います。

SwiftUI自体は、画期的で素晴らしい機能だと思いますが、まだまだ開発途上でUIKitと比べると粗い点も多く、運用面のリスクを考えると乗り換えられないというのは当然です。
新しい技術全般はそういうものなので仕方ないですね。

とはいえ普及しきってから、触るのもエンジニアとしてはなんだかもったいない気がするので、SwiftUIだけでアプリを1つ作ってみました。

「TTimer」という、シンプルなタスクの作業時間を記録するアプリです。
日々のタスク管理のアプリは他に自分で使用しているのですが、いまいち完全に合ったものがなく、自分用で作ってみるか。と思ったのがモチベーションです。
今は、ローカルでのみ保存になっていますが、将来的にはクラウド同期なども追加してもうちょっと使いやすくはしたいと思っています。

今回は、このアプリを作るにあたってSwiftUIで良かった点、悪かった点などを自分なりの観点でまとめてみようと思います。

ちなみに僕は、元々iOS5とかiOS6とかの時代にiPhoneアプリの開発をしていました(昔すぎ笑)が、最近はiOSのネイティブアプリを開発することはほとんどなく、書いていることに至らない点もあるかと思いますが、個人の主観ということでご容赦ください。

SwiftUIを使って良かった点

① コード量が短くシンプルに書ける

SwiftUIは、今までのUIKitとは独立した開発システムのため画面を作成するためのUIコンポーネントも独立して用意されています。
文字を表示するための「Text」や、ボタン「Button」などです。
このようなコンポーネントが用意されていることで、UIKitよりもシンプルに短いコードでアプリを開発できるのがメリットの1つです。

struct ContentView: View {
   @State var text: String = ""

   var body: some View {
       return VStack {
           Text("名前を入力してください。")
           TextField("名前", text: $text)
           Button(action: {
               // 通信処理
           }) {
               Text("登録する")
           }
       }
   }
}

例えば、文字を入力してどこかへ登録するような画面であれば、上記のような記述だけで1画面が作成されます。

UIKitで同じような画面を作成する場合、ViewControllerをコードで用意し、ViewControllerに対応するStoryboardを用意し、各パーツをIBOutletなどで紐付けるか、または全てコード上でUIパーツを配置(レイアウト含め)するような形になると思いますが、いずれにせよSwiftUIの記述よりは複雑になるかと思います。

同じアプリをUIKitで開発したわけではないので体感値ではありますが、コード量が少ないことでスピーディーに開発できた実感はあります。

② Previewを見ながらコードが書けるため、いちいちアプリをビルドして確認する必要がない

UIKitでもレイアウトの確認は、StoryBoardなどを利用してある程度はできました。
しかし、実際にデータが注入されたときの見え方やアニメーションの挙動を確認する際には、アプリをビルドして実機やシミュレータで確認する必要があります。

SwiftUIでは、記述したコードをViewごとに「プレビュー」できる機能がついています。
これによって、実際にテストデータを注入した状態をリアルタイムで確認できたり、プレビュー画面で実際にアプリを起動できます。
アプリは画面単位で起動でき、画面遷移やアニメーションも確認でき、レイアウトや細かなデザインを適用しているときには非常に便利です。
(通信処理なども動かすこともできます)

struct SecondView_Previews: PreviewProvider {
   static var previews: some View {
       PreviewWrapper()
   }
   
   struct PreviewWrapper: View {
       var body: some View {
           ContentView(text: "モックデータ")
       }
   }
}

スクリーンショット 2020-05-09 10.18.39

(「PreviewProvider」というプロトコルを使うとプレビューにモックデータを注入して画面を確認できる。)

Web開発のReactなどを経験している方は、「storybook」を書いているような感覚に近いかもしれません。

SwiftUIを使って苦労した点

① 標準のUIコンポーネントだけでは、開発出来ないことが多い

標準のUIコンポーネントを使った開発は非常に便利でシンプルに開発できますが、用意されているコンポーネントだけアプリケーションを完成させることは、おそらく難しいだろうと思います。

理由は、UIKitには存在するが、SwiftUIには存在しないコンポーネントが少なくないからです。
例えば、Webページを表示するためのコンポーネント(UIKitのSFSafariView,WKWebView)や、TextView(複数行のテキスト入力コンポーネント)、細かいところではインジケータの表示(UIkitのUIActivityIndicatorView)など、SwiftUIには標準で用意されていないコンポーネントが多く存在します。

基本的には、これらのコンポーネントをSwiftUIで使用するためには、UIKitの代替コンポーネントをSwiftUIで使用できるようにするためにブリッジ処理を書いて対応します。(UIViewRepresentable,UIViewControllerRepresentable)つまり、結局はUIKitの実装がある程度必要になります。

また、既に用意されているSwiftUIのコンポーネントでうまく動かないものも存在します。
例えばテキスト入力のために「TextField」というコンポーネントがSwiftUIには存在しますが、現状だと日本語の入力にうまく対応できません。(情報が古い可能性あり)
僕のアプリでも、UIKitの「UITextField」をブリッジしたコンポーネントで代用しています。

このように、現状ではUIKitの力を借りないとアプリを作り上げることは難しいです。
特にSwiftUIからiOS開発を始めようと思っている人にとっては、結局UIKitの勉強が必要になってしまうため、今から始めるのはメリットが薄いかもしれません。

② プレビューがすぐ壊れる

これは、僕個人の特有の問題の可能性がありま。
SwiftUIの強力なサポート機能である「プレビュー」機能ですが、これがすぐに使えなくなるという問題があります。

具体的にどういうことかというと、「プレビュー画面上でアプリがクラッシュしてしまいプレビューが表示されない」ということがよく起こります。

コンパイルエラーが存在するときは、当然プレビューも見れないのですが、コンパイルは通っているが、プレビュー実行時にクラッシュが発生していて、それが原因でプレビューが表示されないという現象です。

原因は、様々なのですが僕のケースでよく起きているのはデータベースのマイグレーションエラーなどでクラッシュするケースです。
(ちなみに僕はDBにはRealmを使用しています)
これは、モックデータを修正すれば治る時もありますが、それでも上手くいかないときもあり、プレビュー処理時はDBを参照しないルートを作るなどプレビュー用の実装コードを書いたりもしています。

一応、クラッシュログも見れることがあるのですが、原因がよくわからないこともあり、またプレビューのデータを初期化する方法も不明なので、発生すると結構モチベーションが下がります。

ちなみに、プレビューでもアプリのコンパイルが走るためこれも地味に重くてイライラします。(ほぼ通常のコンパイル時間と変わりません)

ランタイムを含む高度なプレビュー機能なだけに色々と複雑なのは理解できますが、肝な機能であるがゆえに動かなくなった時のストレスも大きいです。

③ ベストプラクティスが良くわからないことが多い

これも個人的な問題にはなりますが、世の中に参考となる事例が少ないため「問題は解決は出来たが、これで良かったのだろうか?」という事が多々あります。

例えば、「深い階層構造の画面遷移の管理方法」や「画面初期表示時の対応」、「Binding型の正しい使い方」など日々「これで合ってるのかな??」となることが多いです。

(事例の参考までに不要な再レンダリングを防ぐ方法について記事を添付しておきます)

この辺のアプリ開発のベストプラクティス的なものが世の中に一般化するまでは、新規プロダクトで採用するには多少リスクがあるかもしれません。

まとめ

まとめてみると、デメリットの方が多いように感じられたかもしれませんが、個人的な感想としてはSwiftUIは非常に良いと思っています。
(良いことの記述内容が少ないのは、アピールポイントについてはAppleの発表の通りなので、個人的な内容で特別書くことがないこともあります。)

コードで完結するというのは、個人的には大きなメリットなので、次からのアプリ開発もおそらくSwiftUIで作ると思います。

個人的には商用開発でも十分耐えられるとは思っていますが、次のような前提条件はあるかなと思います。

・ UIKitの知識がある程度あり、解決できない問題が発生したときにUIKitでカバーできる
・ 仕様変更を含むアップデートが発生した時に、対応できる余裕がある
    (あまりに大規模であったり、メンテナンス工数が少ないと厳しいかもしれません)
・原因不明で上手く動かないこともある程度許容できる

これらを満たしているのであれば、これからの開発でSwiftUIを採用してみても良いのではないでしょうか。

様々な人がSwiftUIを使って開発をして色々を知見が溜まってくれると開発者としては嬉しいです。

以上、読んでいただきありがとうございました。

この記事が気に入ったらサポートをしてみませんか?