質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.30%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

3478閲覧

SwiftUIでコードが長くなってしまう場合どう分ければ良いのか?

Ririka

総合スコア14

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2022/10/28 04:46

編集2022/10/28 07:36

初心者質問で申し訳ないのですが、どう検索したら自分の疑問に対する答えに辿り着くのかわからず、こちらで質問させていただきました。

コードそのものというよりSwiftUI(あるいはプログラムを書く際)の基本についてご指導いただけますと幸いです。

質問としては、『SwiftUIでコードが長くなってしまう場合、どのようにして分ければ良いのか』というものです。

当方、少しだけJavaをかじったことがあり、そこでは『オブジェクト指向』という形で、メインではなるべく長々とコードを書くことはせず、もう一つファイルを作って、それを呼び出すという形にした方が良いと目にした気がします。

ただ、それをSwiftUIの場合はどのようにすれば良いのかわからず、また、どう検索すれば自分の疑問が解決するのかわからず、質問させていただきました。

現在、作っているものの肝は

・ボタンを押すとランダムで1~100の中から1つの数字を決定する
・数字に対応する画像と長めの文章を表示する

というものです。

この部分だけで言えば、if文やswitch文を作れば実装できるので質問はありません。

ただ、分岐が100個もあるので、メインのContentViewにベタ書きをするとコードがとてつもなく長くなってしまいます。

なので、この100個の分岐に関しては別のファイルに書き、それを呼び出すのが正解なのかな、と思うのですが、その考えは正しいでしょうか?

ただ、調べると別のファイルに書くのではなく、ContentViewのコードの下に別のclass(struct)を改めて書き、メインでそれを呼び出す、という形で出てくることが多いのですが、SwiftUIではファイルそのものを分ける形ではなくこういった形でコードの視認性を良くするのが正解なのか?

以前別のアプリを作っていた時は、『画面の表示そのものが大きく変わる場合に新しいswiftファイルを作る』という形でやっていましたが、今回の場合は、そういった状況ではないのでどうしたら正解なのかがよくわかりません。

あまりに素人質問で質問の意図がお伝えしきれているのか心配ですが、聞きたい事の総意としては

『コードが長くなってしまう場合、Swiftのファイルそのものを分けるべきか』

です。

また、分ける場合、内部的にコード回すだけなのですが、

・SourceのSwift File
・User InterfaceのSwiftUI View

どちらを使うべきなのでしょうか?

二つを『違い』『とは』などで調べてみたもののいまいちよくわからず、名前的に

・Swift Fileはユーザーに見せる必要のないコード
・SwiftUI Viewはユーザーに見せる画面(+コード)

なのかな、と勝手に思っているのですがよくわからず…。

ご指導いただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2022/10/28 07:17

> ・ボタンを押すとランダムで1~100の中から1つの数字を決定する > ・数字に対応する画像を表示する それだけなら配列を使えば良さそうですが…。
Ririka

2022/10/28 07:35

説明不足で申し訳ありません! そこに1つにつき500文字以上の文字も入れる予定です(追記させていただきました) その場合にもおっしゃるようにContentViewのソースの中で配列で一気に書いてしまって…というのが普通でしょうか?
hoshi-takanori

2022/10/28 07:54

それなら、画像の名前と表示する文字列を構造体にして、その配列を使えば良いかと…。
guest

回答2

0

ベストアンサー

調べると別のファイルに書くのではなく、ContentViewのコードの下に別のclass(struct)を改めて書き、メインでそれを呼び出す、という形で出てくることが多いのですが、SwiftUIではファイルそのものを分ける形ではなくこういった形でコードの視認性を良くするのが正解なのか?

分けて作ったclass(struct)が、今のContentViewの中からしか使用されない小さなもので、ContentViewの外から見えないようにしたいものであれば、別ファイルにせずContentViewのファイル内に書いた方がわかりやすいだろうと思います。

Javaが小さなクラスでも別ファイルとして作っている理由は、Javaの文法が1クラス1ファイルというルールになっているからです。局所的なクラスを定義したい場合は、Javaファイルを保存するフォルダを分けてパッケージとして分類します。Swiftには、そういうフォルダ構成がパッケージとなるような概念はなく、1クラス1ファイルという制約もないため、1つのSwiftファイルの中に複数のクラスをまとめることができます。

要するに、それぞれの言語で対応できるやり方で、自分がわかりやすいようにまとめればよいと思います。

また、分ける場合、内部的にコード回すだけなのですが、

・SourceのSwift File
・User InterfaceのSwiftUI View

どちらを使うべきなのでしょうか?

基本的には、新しいViewを作るなら「SwiftUI View」、それ以外のSwiftファイルを作るなら「Swift File」ですが、この2つの違いは、あらかじめ記入されている雛形コードの違いだけです。「SwiftUI View」で作れば、Viewを構成するためのstructが雛形として記入されていますが、その雛形コードを削除してViewと関係ないSwiftクラスを作ってもいいし、「Swift File」で作ったファイルにViewを構成するためのstructを自分で書いてViewを作っても構いません。作りやすい方を使って作ればいいです。

投稿2022/10/29 02:32

TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ririka

2022/10/30 08:47

TakeOne様 大変丁寧に、そしてJavaとの考え方の違いまでわかりやすくご指導いただきありがとうございました! おっしゃるようにJavaですと『1クラス1ファイルが原則』というようなイメージが強く、そして『齧っただけで、しっかり理解していない』という私の未熟さも相まって何が正しいのかわからなくなってしまっておりました。 今回ご回答いただけたことで、自分の中にあった変な固定概念が解け、大変スッキリしました! また、SwiftUI ViewとSwift Fileの違いもとてもスッキリしました。 開いてはみるものの、拡張子も同じで「違い」と検索しても何も出ないという状態だったのでどうしても違いがわからず…。 ご回答をいただけスッキリしました! また何かありましたらよろしくお願いできればと思います。 本当にありがとうございました!
guest

0

個人で作成するアプリなら1つのファイルに全部詰め込んでも良いとは思いますが・・
チームで開発するアプリは(ファイル・クラスの)役割を決めて分割した方が作りやすいと言われていると思いますね。
*回答する際に質問者の背景がわからないと難しいところと感じます
*個人で開発しているのに、チームで開発するようなきっちりしたものを押し付けても逆に面倒になるだけだったりすることもありますので・・

業務アプリケーションでは、業務ロジックを整理するために、画面インターフェース/業務ロジック/データベース入出力の3つの関心事を分離するための三層アーキテクチャが一般的です。

表:三層アーキテクチャ

名前説明
プレゼンテーション層画面や外部接続インターフェース
アプリケーション層業務ロジック、業務ルール
データソース層デーベース入出力

『現場で役立つシステム設計の原則 変更を楽で安全にするオブジェクト指向の実践技法』P.069より

ざっくりした感じでは、プレゼンテーション層とアプリケーション層を分けた方が良いみたいです。
ですので、

・Swift Fileはユーザーに見せる必要のないコード
・SwiftUI Viewはユーザーに見せる画面(+コード)

この認識はざっくりした感じでは合っているのかなと思いました。

  • Swift Fileはアプリケーション層
  • SwiftUI Viewはプレゼンテーション層

ですね。
(ざっくりなので厳密には違うこともあるとは思います・・)

それらを踏まえまして、ボタンを押すとランダムに画像を表示するサンプルを書いてみました。
SwiftUI Viewにはできるだけif,forのようなロジック・ルールを記述しないようにすると、スッキリ分離できているのかなという印象です。
*必要な場合はSwiftUI Viewにif,forを記述するとは思います

swift

1import SwiftUI 2 3struct ContentView: View { 4 @StateObject var sample = SampleClass() 5 var body: some View { 6 VStack { 7 Button("tap!", action: action) 8 Image(systemName: sample.entity.name) 9 Text(sample.entity.bunsho) 10 } 11 .padding() 12 } 13 func action() { 14 sample.random() 15 } 16} 17 18class SampleClass: ObservableObject { 19 @Published var entity: SampleEntity = SampleEntity(name: "globe", bunsho: "") 20 var entities = [ 21 SampleEntity(name: "square.and.arrow.up.trianglebadge.exclamationmark", bunsho: "bunsho1"), 22 SampleEntity(name: "mic", bunsho: "bunsho2"), 23 SampleEntity(name: "sun.min", bunsho: "bunsho3"), 24 SampleEntity(name: "pencil", bunsho: "bunsho4"), 25 SampleEntity(name: "keyboard", bunsho: "bunsho5"), 26 SampleEntity(name: "circle.grid.cross", bunsho: "bunsho6"), 27 SampleEntity(name: "externaldrive.connected.to.line.below", bunsho: "bunsho7"), 28 SampleEntity(name: "airplane", bunsho: "bunsho8"), 29 SampleEntity(name: "folder.badge.person.crop", bunsho: "bunsho9"), 30 SampleEntity(name: "globe.americas", bunsho: "bunsho10"), 31 // 100個続く… 32 ] 33 func random() { 34 entity = entities.randomElement()! 35 } 36} 37 38struct SampleEntity { 39 var name: String 40 var bunsho: String 41}

SwiftUI View自体も役割に合わせて分割したりしますので、
一度公式のチュートリアルも実践してみると良いかもしれませんね。

https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation

投稿2022/10/28 09:49

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ririka

2022/10/30 08:47

xg63ex2b様 この度もご回答いただきありがとうございます! そして、説明不足な状態にも関わらず、コードまで掲載いただきとても感激しています! とても参考になりましたし、コード内に自分の考えが至っていない発見、また知らない記述方式がありましたので、本当に感謝しています。 また、三層アーキテクチャという考え方も初めて知りました。 プログラミングに対しての造詣がとても深くいらっしゃり、毎度本当に勉強になります。 SwiftUIチュートリアルがあったというのもはじめて知りました! 今後もお世話になるかと思いますが、一度こちらで自分でも勉強をしてみたいと思います。 本当にこの度もありがとうございました! またお願いできれば幸いです。
Ririka

2022/11/01 02:44

xg63ex2b様 ご覧になっていらっしゃるかわかりませんが、改めてお礼を言わせてください。 本日、実際にこちらのコードを自身のプロジェクト内で使ってみたところ、自分が理解しておらずエラーが出てしまったのですが一つ一つを紐解いていくことで、 ・ObservableObject(これ自体を知りませんでした) ・randomElement(これを思いつかず、数字を出して、数字を参照して文章などを取り出すという二度手間なものを作っていました) ・ Image(systemName: sample.entity.name)(これが全く思いつかず苦戦していたのでとても勉強になりました!言われてみれば確かに!と膝を打ちました) と本当に自分だけでは上手く行かなかったであろう部分まで、フォローしていただいており、大変感激し、この場を借りて改めてお礼をさせていただければと思い文章を打っています。 短い説明の中からここまで的確なコードを書いていただき、xg63ex2b様のすごさを実感しました! 上手く言葉が出てきませんが本当にありがとうございました!! またよろしくお願い致します。
退会済みユーザー

退会済みユーザー

2022/11/01 09:19

ご丁寧なメッセージを2回もありがとうございます。 回答者へのコメントはメールが届くのでちゃんと見ていますよ。 *逆に回答者がコメントしたものは質問者にメールが届かないっぽいのでこのコメントは気づかないかもしれませんね これまでいくつか回答などしてきましたが、 丁寧なメッセージをもらえるとやっぱり回答してみて良かったと思います。 よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問