swiftを使ってsupabaseのテーブルをリアルタイム監視する【手順書】

supabase内のテーブルを監視することができずに困っていましたが解決したので備忘録がてら記事を残しておきます。

# リアルタイム監視についてのswiftコード
[supabase公式ドキュメント](https://supabase.com/docs/reference/swift/subscribe, "supabase DOCS")にサンプルコードはありますが、非同期タスクの記載の仕方に慣れていないためAIを頼りながらコードを作成しました（AIすごい！）

コードの細かい説明はしませんが、
以下のコードでリアルタイム監視することができました。

```swift:ContentView.swift
import SwiftUI
import Supabase

//supabaseクライアントの設定
let supabase = SupabaseClient(
    supabaseURL: URL(string: "YOUR_SUPABASE_URL")!, //自身のURLを記述
    supabaseKey: "YOUR_SUPABASE_ANON_KEY" //自身のKEYを記述
)

//Instrumentモデル
struct Instrument: Decodable, Identifiable {
    let id: Int
    let name: String
}

struct ContentView: View {
    @State var instruments: [Instrument] = []
    @State private var channel = supabase.channel("channelId")
    
    var body: some View {
    
        Text("プレビュー画面")
        
        .task {
            let changeStream = channel.postgresChange(AnyAction.self, schema: "public")
            
            await channel.subscribe()
            
            for await change in changeStream {
                switch change {
                case .delete(let action): print("Deleted: \(action.oldRecord)")
                case .insert(let action): print("Inserted: \(action.record)")
                case .update(let action): print("Updated: \(action.oldRecord) with \(action.record)")
                }
            }
        }
    }
}

#Preview {
    ContentView()
}
```
 **"YOUR_SUPABASE_URL"** と **"YOUR_SUPABASE_ANON_KEY"** は、supabaseの「Project Setting」→「DataAPI」から確認することができます。


このコードをそのまま実装すればリアルタイム機能を実装できますが、これでもできない場合はいくつか準備が不足していると思うので、以下で説明していきます。

# supabase-seiftライブラリの導入
![2025-03-11 15.27の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/99c1485e-7bac-4ab2-9795-9d401430f95e.jpeg)
このようなエラーが出る場合は、まずライブラリをインストールする必要があります。

1. Xcodeでプロジェクトを開き、「File」→「Add Package Dependencies」を選択
![2025-03-11 15.33の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/fa061cd5-01ed-42b9-875f-f02adb360497.jpeg)

2. 以下のURLを検索し、「Add Package」をクリック
```URL
https://github.com/supabase/supabase-swift
```

![2025-03-11 15.36の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/49aaa777-0958-45cd-bc8a-53bc350e7293.jpeg)

3\.「Add Package」をクリック
![2025-03-11 15.37の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/4828f0ce-84ba-43a7-a2ed-c7450f53c513.jpeg)

4\. 「プロジェクト」→「Targets」セクションで該当のターゲットを選択」→「Build Phases」タブ→「Link Binary With Libraries」セクションで「+」ボタンをクリック
![2025-03-11 15.41の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/b328dfbc-63a5-47fb-bca7-9a3dd4627aee.jpeg)

5\. 「Supabase」を選択、「Add」をクリック
![2025-03-11 15.41の画像 (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/5ae53479-9acb-4706-afc8-0a40335c3b8e.jpeg)

# テーブル作成 & セキュリティ設定
今回の監視対象となるテーブルの作成、行レベルセキュリティ（RLS）の有効化、ポリシー設定を行います。
supabaseのSQL Editorを開き、以下のSQLを実行してください。

ちなみに[supabase公式ドキュメント](https://supabase.com/docs/guides/getting-started/quickstarts/ios-swiftui, "supabase公式ドキュメント")で紹介されているものと同じSQLです。

```SQL:SQL_EDITOR
-- テーブルを作成
create table instruments (
  id bigint primary key generated always as identity,
  name text not null
);
-- サンプルデータをinsert
insert into instruments (name)
values
  ('violin'),
  ('viola'),
  ('cello');
--行レベルセキュリティ（RLS）を有効化
alter table instruments enable row level security;
--ポリシー設定
create policy "public can read instruments"
on public.instruments
for select to anon
using (true);
```

# レプリケーション設定
[supabase公式ドキュメント](https://supabase.com/docs/reference/swift/subscribe,"supabase公式ドキュメント")から引用しますが、以下の記載があります。
>By default, listening to database changes is disabled for new projects due to database performance and security concerns. You can turn it on by managing Realtime's replication.
>デフォルトでは、データベースのパフォーマンスとセキュリティ上の問題から、新しいプロジェクトではデータベースの変更をリッスンする機能は無効になっています。Realtimeのレプリケーションを管理することで有効にすることができます。

よってレプリケーション機能を有効化します。
方法は以下2通りあります。
* SQLで有効化する
* コンソール画面から有効化する

どちらかお好きな方で設定してください。

### SQLによる有効化
supabeseのSQL Editorから以下のSQLを実行してください。
```SQL:SQL_EDITOR
alter publication supabase_realtime add table instruments;
```
:::note
supabase_realtimeというpublicationはプロジェクトを作成した時点で自動的に作成されるため、自分で作成する必要はありません
:::
### コンソール画面から有効化
1.[supabase](https://supabase.com/dashboard/projects, "supabaseダッシュボード")からプロジェクトを開き、「Database」を選択
![2025-03-11 16.31の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/5fbfef9b-09c4-4054-a863-874a2853bb92.jpeg)

2\.「Publications」→ Source列の「◯table」を選択
![2025-03-11 16.31の画像 (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/05258142-04cd-4c1b-b40f-6f2f016b3775.jpeg)

3\. 対象テーブルのトグルをONにする
![2025-03-11 16.32の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/baf5b8df-147c-4092-aaf7-2543ef226bf2.jpeg)

# 実際に監視してみる
simulatorを起動してから、テーブルに変更を加えてみます！

celloという値を持つレコードを削除すると...
![2025-03-11 20.08の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/bd63bedf-4171-4702-bacc-9dfdfea3f40f.jpeg)

Xcodeのデバッグエリアに削除されたレコードのidが表示されました！よかった！
![2025-03-11 20.11の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4031051/6ecf26c4-ebc5-483d-86d7-371dd24656d0.jpeg)



# まとめ
テーブルのリアルタイム監視を行うためには以下のような設定が必要でした。
* supabaseライブラリのインストール
* テーブルの作成 & セキュリティの設定
* レプリケーション設定

個人的には非同期処理のコードを書くことに一番苦戦しました...