📁

SwiftUIでmacOSとiOSをサポートするアプリを作ってみた

2022/12/25に公開

初めに

この記事はSwiftUI Advent Calendar 2022の24日目の記事です。
SwiftUIをベースにしたアプリでmacOSとiOSのマルチプラットフォームで動作するアプリを作ったので紹介します!

Use Xcode to develop a multiplatform app

WWDC22で発表されたXcode14の新機能に「単一ターゲットで複数のプラットフォームをサポートしたアプリを作れる」という機能があります。

https://developer.apple.com/videos/play/wwdc2022/110371/

従来はiOSアプリとmacOSアプリをサポートしたい場合は別のターゲットを用意する必要があったのですが、Xcode14からは単一のターゲットで開発できるようになりました。
これによってBuildSettingsやアプリの共通化したコードベース・アセットの共通化が簡単になると思います。

作ってみた

丁度夏くらいにCsv2Imgというcsvファイルをpng/pdfに変換できるアプリを作っていたので、そのアプリをmacOSとiOSに対応してみました。

GitHubに上げているのでもし良かったらスターをください

https://github.com/fummicc1/csv2img

辛かったこと

macOSとiOSをサポートするに当たってインターフェースが異なる部分が多く、結局#if osは所々使うことになりました。

NSxxxとUIxxx: Application / View / Responder / ViewRepresentable

毎回書くと大変なのでType.swiftというOSごとに違うインターフェースだけど同じような責務の型を定義しておくファイルを作りましたが、結局ViewModel内部でもos毎に処理を分ける必要があったのであまり恩恵は得られませんでした。

https://github.com/fummicc1/csv2img/blob/0e4ecd0ab0fc70a5d1603c7fc6e2aa7464ec1f4e/Csv2ImageApp/Csv2ImageApp/Type.swift#L11-L25

もっと綺麗にアーキテクチャ分けすれば共通化できるコードが増えると思います。

ファイルの選択方法

  • iOS: UIDOcumentPickerViewController
    • フォルダアプリからファイルを読み込む・ファイルを出力する
  • macOS: NSOpenPanel
    • Finder経由でファイルの読み書きをする

今回ユーザーがcsvのファイルを選択をする際にiOSとmacOSで別々のアプリから読み書きしたのでAPIを共通化できず分岐が必要でした。

カラー・描画

Appleが提供する色はOSごとに異なります。

https://developer.apple.com/design/human-interface-guidelines/foundations/color/#system-colors

NSColorにもUIColorにもseparator色はあるのですが、separatorColor / separatorと微妙に異なる命名がされており、以下のようにマクロで分けることになりました。

https://github.com/fummicc1/csv2img/blob/0e4ecd0ab0fc70a5d1603c7fc6e2aa7464ec1f4e/Sources/Csv2Img/ImageMaker.swift#L113-L117

また、GraphicsContextを生成する処理もmacOSにはUIGraphicsBeginImageContextUIGraphicsImageRendererは存在しなく、一度NSImageを作成してlockFocusメソッドを呼んでからCGContextを取得する流れになっており、分岐が必要でした。

https://github.com/fummicc1/csv2img/blob/0e4ecd0ab0fc70a5d1603c7fc6e2aa7464ec1f4e/Sources/Csv2Img/ImageMaker.swift#L81-L94

あとは同じCoreGraphicsでもiOSだと.zeroが左上になってmacOSだと左下になるので以下の分岐が必要でした。

https://github.com/fummicc1/csv2img/blob/0e4ecd0ab0fc70a5d1603c7fc6e2aa7464ec1f4e/Sources/Csv2Img/ImageMaker.swift#L172-L176

https://developer.apple.com/documentation/corefoundation/cgrect

他にもmacOSにはNavigationのpopアニメーションがなかったりと異なる点があり都度対応する必要があると思います。個人的意見ですが企業のようなデザイナーさんがいて仕様通りのデザインやサービス全体で統一されたデザインシステムがあるとSwifUIの中でもっとmacOSとiOS間で分岐処理が必要になってくると思いました。

良かったところ

SwiftUIで作れると状態管理が楽ちんなので個人的にはSwiftUI好きです。

終わりに

SwiftUIでの開発体験が来年再来年と良くなっていくと嬉しいです。来年もよろしくお願いします!

Discussion