🍎

[Swift] SwiftUIをやってみる

に公開2

ぽちぽちのつどいGW Advent(?) Calendar3日目の記事です!

どうもいつもFlutterばっかりやってるせいで授業でやるPythonを忘れてきた大学生です!
最近はHonoとSupabase使ったAPI叩いてFlutterでフロント書いてるのが多いですが今日気分を変えてHonoで作ったAPIを使ってSwiftに挑戦した時のことを書きます。
そんなに深いこと書けないし他の方やAIの方が多分詳しいのでここではFlutterと比べてどうかみたいなことやほぼ初挑戦なので気になったことを書きます。

SwiftUI

https://developer.apple.com/jp/xcode/swiftui/

SwiftUIでは、Swiftを利用してすべてのAppleプラットフォーム向けに、驚くほど少ないコードで美しいアプリを構築できます。1つにまとまったツールとAPIを使用するだけで、あらゆるAppleデバイス向けに優れたユーザー体験を提供できます。

だそうですまぁ百聞は一見になんとやらということで早速初めて行きます。
今回のゴールはAPI経由でSupabaseに今の時間を記録して勉強や読書、案件などのタイマーアプリをゴールとしました。

UI構築

ここ1年くらいずっとFlutterをやっていたのですが昔UIkitがエラーばかり吐いていてストレスで諦めたのが2回くらいあってそれ以来のiOSのネイティブ開発でした(笑)。
そんなこんなで、今回久しぶりにiOSネイティブ開発に戻ってきたわけですが、SwiftUIは想像以上に良かったです!まぁ昔よりモバイルアプリに対するやる気と知識が増えてるので当然かもしれないですが...
例えばTextに対して.で繋げてフォントやpaddingを当てていくのはFlutterの構造とはまた違った良さがあって書きやすかったです。

  Text("Hello")
    .font(.title2)
    .foregroundColor(.black)

こんな感じですがFlutterだとTextの()の中に,で繋いでスタイルを変更するので最初見た時なんだこれって感じでしたが書いたり見たりしてるうちに慣れてきて最後は「これ結構良くね?」って感じになってました(笑)。

Swiftの構文

関数の作成についてはfuncで宣言して名前をつけて()で引数を渡すスタイル。
これは正直、JS/TSやGoなどと似た感じだったので、特に驚きはありませんでした。

func fetchData(name: String){}

ローカル変数の宣言はえ?なんだこれと思いました。
今までわりと色々な言語に触れてきたつもりでしたが遭遇したことのない感じで慣れませんでした。
変化しない物(API keyなど)は今までやってきたletとかvarはJS/TSやdartとかで使うのと同じ感じなのでここまではいいんですが@State privateが出てきて最初はよくわかりませんでした😭😭
慣れれば便利そうなのでもうすこしやればわかってきそう...

@State private var start: [String] = []

最初は「これ、Javaのprivate String msg = "hello";みたいなやつなのかな?」とかそんな適当なノリで進めてました(笑)。

FlutterのStatefulWidgetでは、setStateやクラスが2個あったりとどうしてもコードが長くなって読みづらくなることが多かったんですがSwiftUIでは@Stateアノテーションだけで同じようなことができるので、すごくスッキリしてて嬉しいですね。

あとJavaとかJS,dartあたりやってるとクセで;をつけがちですがエラーが出ます(当たり前だろとか言わないで🙏)
Swiftの構文自体はこれらの言語と大体似ているのでなれなかったです。
初めてすぐの時に変数宣言で;を付けてしまいエラーになりAIに聞いてみたらそれが原因だとわかりました(ハズカシイ🫣)。

API通信

API通信のロジックや状態管理の処理をプロジェクトの概要をGPTさんに渡して出力してもらったところ想像以上に精度が高くて驚きました💦
初心者でも品質を多少無視すれば1日あればAPI通信ができるiOSアプリを完成させられるとは思っていなかったのでかなり衝撃でした。

実際に使ったサンプルコードはこちらです👇

func fetchData(completion: @escaping (Result<[String], Error>) -> Void) {
        guard let url = URL(string:"\(api)start") else {
            completion(.failure(NSError(domain: "Invalid API URL", code: 400, userInfo: nil)))
            return
        }
        
        URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200,
                  let data = data else {
                completion(.failure(NSError(domain: "Failed to load data", code: 500, userInfo: nil)))
                return
            }
            
            do {
                if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
                   let createdAtList = json["createdAt"] as? [String] {
                    // 日時フォーマットを変換
                    let formattedDates = createdAtList.compactMap { self.formatDate($0) }
                    print("フェッチ\(createdAtList)")
                    completion(.success(formattedDates))
                } else {
                    completion(.failure(NSError(domain: "Invalid JSON format", code: 500, userInfo: nil)))
                }
            } catch {
                completion(.failure(error))
            }
        }.resume()
    }

SwiftUIをやってみて

SwiftUI、すごくいいですね。
Flutterはマテリアルデザインに準拠しているため、どうしてもiOS上で実行すると、デザインが浮いてしまうことが多かったのですが、SwiftUIでは、Listの表示やボタンなどをiOSの標準アプリとほとんど変わらないデザインで簡単に構築できるので、全体に統一感が出るのがとても良いと感じました。
今回SwiftUIに触れたことで、今後Flutterで開発する際のデザインの参考にもなりそうだと感じています。

まとめ

結論:AIはまじで優秀

まぁこれだけだと驚き屋みたいになるのでもうすこし深めるとAIのおかげで1〜2日程度で一応目標としていたアプリが完成し今回のチャレンジは達成できました。もともと過去に一度挑戦して諦めた経験もあったため、今回は再々入門のような気持ちで取り組みましたがAI技術の発達もあり開発はとてもスムーズに進みました。
今回はセキュリティ面はあまり考慮せず入門用のシンプルなアプリを作ったのでアーキテクチャやセキュリティ面など突っ込みどころは多いコードになっていますがそれでもとても楽しく開発できたと感じています。

また、ロジック部分をAIにかなり丸投げしたので次回ネイティブ開発に挑戦する際は自分でロジックを考えながら作ることにもチャレンジしたいです。
言語面でもPythonと比べるとDartやJavaScriptに近い感覚だったため思っていたよりも取っつきやすかったのもよかったポイントでした。
次は、直接DBに接続してCRUD操作ができるシンプルなアプリやSwiftUIで推奨されているMVCアーキテクチャを取り入れた開発にも挑戦してみたいですね。
...とはいえ、なかなか時間が取れないのが悩みどころですが(笑)

というわけで普段とは気分を変えてFlutterではなくSwiftUIに挑戦してみましたがとても楽しかったです!
またSwiftUI関連で新しいことに挑戦したら記事にまとめたいと思うのでお楽しみに!

ぽちぽちのつどいGW Advent(?) Calendar3日目はSwiftUIに取り組んだ内容をお届けしました。
ここまで読んでいただき、本当にありがとうございました🙇🙇🙇

ぽちぽちのつどい

Discussion

みそしるみそしる

実行できないんかい!

toltotolto

少し前まで実行できてたんですが書いてる時にスクリーンショット貼りたくて実行したところエラーで動かなかったです。😢😢😢😢