【SwiftUI】Firestoreに保存されたデータの削除

① Firestoreに保存されているデータを削除

TestFirebase/DataModel.swift

func deleteData(id: String) {
        let db = Firestore.firestore()
        
        db.collection("testDatas").document("\(id)").delete() {  error in
            if let error = error {
                print("データの削除に失敗しました。\(error)")
                return
            }
            
            print("データの削除に成功しました。")
        }
    }
② 表示されている内容を変更(配列から削除したデータを取り除く)

TestFirebase/DataModel.swift

init() {
        let db = Firestore.firestore()
        
        db.collection("testDatas").addSnapshotListener { (snap, error) in
            if let error = error {
                print("データの読み込みに失敗しました。\(error)")
                return
            }
            
            if let snap = snap {
                for i in snap.documentChanges {
                    if i.type == .added {
                        // 省略
                    } else if i.type == .removed {
                        let id = i.document.documentID
                        
                        for j in 0 ..< self.testDatas.count {
                            if self.testDatas[j].id == id {
                                self.testDatas.remove(at: j)
                                return
                            }
                        }
                        
                        print("削除するデータが存在しません。")
                    }
                }
            }
        }
    }

【SwiftUI】Firestoreに保存されたデータの表示

保存データ表示までの手順

① 定義した配列を複数代入できる空の配列を定義
(今回は「TestDataModel」で定義した配列が複数代入されます)
② Firebaseに保存されたデータの呼び出し
③ 呼び出したデータを、①で定義した配列に代入(追加)
④ データが代入された配列の値を表示(例:List, ForEach)

参考コード

TestFirebase/DataModel.swift

class DataModel: ObservableObject {
    @Published var testDatas = [TestDataType]()
    
    init() {
        let db = Firestore.firestore()
        
        db.collection("testDatas").addSnapshotListener { (snap, error) in
            if let error = error {
                print("データの読み込みに失敗しました。\(error)")
                return
            }
            
            if let snap = snap {
                for i in snap.documentChanges {
                    if i.type == .added {
                        let id = i.document.documentID
                        let country = i.document.get("country") as! String
                        let prefecture = i.document.get("prefecture") as! String
                        
                        self.testDatas.append(TestDataType(id: id, country: country, prefecture: prefecture))
                    }
                }
            }
        }
    }
}

struct TestDataType: Identifiable {
    var id: String
    var country: String
    var prefecture: String
}

TestFirebase/ContentView.swift

struct DataView: View {
    @ObservedObject var testDataVM = DataModel()
    
    var body: some View {
        List(testDataVM.testDatas) { data in
            VStack(alignment: .leading) {
                Text("国名:  \(data.country)")
                Text("都道府県:\(data.prefecture)")
            }
            .font(.title)
        }
    }
}
表示結果

【SwiftUI】Firebase/Firestoreを用いたデータ保存

はじめに

本記事の内容は、前回の記事「 【SwiftUI】Firebaseの導入 - nekoyutanekoのブログ 」の続きです。

Firestoreの導入

Podfileに新しくインストールするライブラリを追記します。 今回は「Firebase/Firestore」を追記します。

Pods/Podfile

pod 'Firebase/Analytics'
pod 'Firebase/Firestore'  // 左記を追加

記述を終えたら、ターミナル上でアプリケーションが格納されているディレクトリに移動したのち、 以下のコマンドを実行してください。

% pod update
データベースの作成

Firebase 」 のメニューから「Firestore Database」を選択して、 「データベースの作成」をクリックしてください。

① セキュリティ保護ルールの設定

今回は「テストモードで開始する」を選択します。

<注意点!>
この設定は「すべてのユーザーに対する読み取りと書き込みのアクセス権を可能にしている」ので、セキュリティ上安全ではありません。

そのため、 必ず アプリケーションの使用状況・方法に合わせて、セキュリティの設定を変更するようにしてください。

参考URL:https://firebase.google.com/docs/firestore/security/insecure-rules?hl=ja

② ロケーションの設定

今回は「asia-northeast1(東京)」を選択します。

参考URL:https://firebase.google.com/docs/firestore/locations?hl=ja

選択後、右下の「有効にする」をクリックすると、 データベースの作成が始まります。
作成が完了すると、以下の画面になります。

データの保存

TestFirebase/ContentView.swift

import SwiftUI

struct ContentView: View {
    @ObservedObject var testDataVM = DataModel()
    var body: some View {
        Button(action: {
            testDataVM.addData(country: "日本", prefecture: "東京都")
        }) {
            Text("データ保存の実行")
        }
    }
}

TestFirebase/DataModel.swift

import Foundation
import Firebase

class DataModel: ObservableObject {
    func addData(country: String, prefecture: String) {
        let data = [
            "country": country,
            "prefecture": prefecture
        ]
        
        let db = Firestore.firestore()
        
        db.collection("testDatas").addDocument(data: data) { error in
            if let error = error {
                print("データの保存に失敗しました。\(error)")
                return
            }
            
            print("データの保存に成功しました。")
        }
        
    }
}

addDocumentメソッドにより、データを保存します。
データの保存に成功すると、Firestore Databaseにデータが追加されます。

【SwiftUI】Firebaseの導入

プロジェクトの新規作成
1. FirebaseのWebサイト上で「プロジェクトを追加」を選択

参考URL:https://firebase.google.com/?hl=ja

2. プロジェクト名を入力

3. Googleアナリティクスを設定

Googleアナリティクスを利用しない場合は、チェックを外して「プロジェクトを作成」を選択

作成が完了すると、以下の画面になります。

Googleアナリティクスを有効にすると、アカウント入力画面に遷移します。

iosアプリとプロジェクトの紐付け
1. 設定画面に遷移

プロジェクト一覧から、先ほど作成したプロジェクトを選択

iosを選択

2. 必要事項を順番に設定
① アプリの登録

xcodeでアプリのBundle Identifier(ID)を確認

確認したBundle Identifier(ID)を入力

② 設定ファイルのダウンロード

ダウンロードした「GoogleService-info.plist」をxcodeにドラッグ&ドロップして、ターゲットに追加

③ Firebase SDKの追加

CocoaPodsにより、必要なライブラリをインストール

  • Podfileを生成

ターミナル上でアプリケーションが格納されているフォルダに移動したのち、 以下のコマンドを実行してください。

% pod init
  • Podfileを開き、インストールするライブラリを記述
% open podfile

今回は「Analytics」をインストールします。

参考URL:https://firebase.google.com/docs/ios/setup?hl=ja#available-pods

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'TestFirebase' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for TestFirebase
  pod 'Firebase/Analytics'  # 左記のコードを追加

end
  • 記述後、「command + S」により変更内容を保存
  • 保存後、ライブラリをインストール
% pod install

インストールが完了したら、xcodeを再起動して以下のワークスペースでアプリを開き直してください。(※今までのワークスペースではPodファイルが含まれないので、今後の作業ができなくなります。)

④ 初期化コードの追加

Firebaseの関数を初期化するためのコードを記述します。
Webサイトで紹介されている以下の方法は、UIkitを使用しているときの記述ですので、SwiftUIでアプリ制作をしているときは別の方法が必要になります。

SwiftUIを使用しているときは、以下の記述をお試しください。

TestFirebaseApp.swift(TestFirebaseはアプリ名)

import SwiftUI
import Firebase  // 左記のコードを追加

@main
struct TestFirebaseApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }

// 以下範囲のコードを追加    
    init() {
        FirebaseApp.configure()
    }
// ここまで

}
⑤ 設定完了

SwiftUI Gihubの更新

ブランチの作成
① Branchesフォルダ上でメニューを開き、「Branch from "main"...」を選択する(※mainはmasterブランチ名)

② ブランチ名を入力した後、「Create」を選択する

③ 作業中のブランチには、名前の後ろに「(current)」が記述される

コミットの実行
ツールバーのSource Controlタグから「Commit...」を選択する

② コミット名を入力した後、「Commit ファイル数 Files」を選択

③-1 作業中だったテストブランチには変更が反映されている

③-2 mainブランチには変更がない

マージ(テストブランチの変更をmainブランチに反映)
① mainブランチ上でメニューを開き、「Checkout...」を選択する(※この操作で作業中のブランチをmainブランチに切り替えています)

② 「Checkout」を選択する

③ テストブランチ上でメニューを開き、「Merge "テスト" into "main"...」を選択する

④ 「Merge」を選択する

プッシュ(ローカルリポジトリの変更をリモートリポジトリに反映)
ツールバーのSource Controlタグから「Push...」を選択する

SwiftUI GitHubへの保存

新しくアプリケーションをGitHubに保存までの手順

① .gitignoreファイルの作成

(※.gitファイル作成後に行うと、変更が反映されないことがあります。)

VSCode」や「ターミナル」を用いて「.gitignoreファイル」を作成後、除外設定を記述してください。

参考URL:https://github.com/github/gitignore/blob/master/Swift.gitignore

Macを使用している場合、「.DS_Store」というファイルが自動生成されてしまうので、私は除外設定に「.DS_Store」も追記しています。

.gitignore

~省略~
iOSInjectionProject/

# Mac
.DS_Store

② .gitファイルの作成

「Source Control」タグから「New Git Repositories」を選択してください。

確認画面で「Create」ボタンを押してください。

③ リモートリポジトリの作成

「Remotes」フォルダの上で右クリックして、メニューから「New "アプリ名" Remote」を選択してください。

確認画面が表示されたら、「Public」と「Private」どちらかを選択して、「Create」ボタンを押してください。

※デフォルトだと「Public」が選択されていますが、このまま作成するとGitHub上で他ユーザーから閲覧できてしまうので、初めのうちは「Private」を選択して作成した方が良いかもしれません。

SwiftUI 要素のレイアウト調整

はじめに

今回は、SwiftUIにおける要素のレイアウト調整を紹介したいと思います。

HTMLがdisplay, positionのようなプロパティを使用することで、要素の並びを調整できるのに対して、 SwiftUIでは「Stack」を組み合わせることで、レイアウト調整を行うことができます。

Stack一覧

以下の色ブロックをレイアウト調整します。

HStack {
    Text("")
        .frame(width: 300, height: 300)
        .background(Color.red)
    Text("")
        .frame(width: 200, height: 200)
        .background(Color.blue)
    Text("")
        .frame(width: 100, height: 100)
        .background(Color.green)
}

HStack

HStackは要素を横並びにすることができます。

VStack

VStackは要素を縦並びにすることができます。

ZStack

ZStackは要素を重ね合わせることができます。