visionOS × Supabase環境構築

2024/09/07に公開

はじめに

visionOSは、Apple社が開発した空間コンピューティングプラットフォームで、Supabaseは、オープンソースのFirebase代替として人気のあるバックエンドサービスです。本記事では、これら最先端の技術を組み合わせ、visionOSアプリケーションでSupabaseを効率的に利用するための知識と技術を習得できることを目指します。環境構築から実際の実装まで、段階的に解説していきますので、ぜひ最後までお付き合いください。

できるようになること

  1. visionOSアプリケーションにSupabaseを導入する
  2. 開発環境と本番環境を適切に切り替える
  3. Supabaseでの認証機能をvisionOSアプリで利用する

対象読者

  • visionOSアプリケーション開発に興味がある開発者
  • Supabaseをバックエンドとして使用したい開発者

Supabaseプロジェクトの設定

Supabaseを使用するための最初のステップは、プロジェクトを作成し、必要な設定を行うことです。
以下の手順に従って進めてください。

  1. Supabaseプロジェクトの作成

    • Supabase公式サイトにアクセスし、アカウントを作成またはログインします。
    • ダッシュボードから「New Project」を選択し、プロジェクト名や地域などの基本情報を入力します。
    • データベースのパスワードを設定し、「Create new project」をクリックしてプロジェクトを作成します。
  2. 認証設定の構成

    • プロジェクトのダッシュボードから「Authentication」→「URL Configuration」に移動します。
    • 「Redirect URLs」セクションで、以下のURLを追加します。
      io.supabase.supabase-sample://login-callback
    • この設定により、認証後にアプリに正しくリダイレクトされます。
  3. プロジェクト情報の取得

    • ダッシュボードの「Project Settings」→「API」タブを開きます。
    • 「Project URL」と「Project API Keys」セクションから必要な情報をコピーします。

supabase-swiftの導入

supabase-swiftライブラリをプロジェクトに導入します。このライブラリは、SupabaseのAPIをSwiftから簡単に利用するためのクライアントSDKです。

導入手順

  1. Xcodeでプロジェクトを開き、メニューバーから「File」→「Add Package Dependencies」を選択します。

  2. 表示されたウィンドウの検索バーに以下のURLを入力します。

    https://github.com/supabase/supabase-swift
    
  3. 「Add Package」ボタンをクリックします。

  4. 次の画面で、supabase-swiftパッケージを追加するターゲットを選択します。通常は、メインのアプリターゲットを選択します。

  5. 再度「Add Package」ボタンをクリックして、パッケージの追加を確定します。

Supabase Swift Package追加画面

SupabaseClientの作成

supabase-swiftの導入が完了したら、次はSupabaseClientの初期化と基本的な使用方法を学びます。SupabaseClientは、Supabaseの各種機能(認証、データベース操作、リアルタイムサブスクリプションなど)にアクセスするための中心的なオブジェクトです。

SupabaseClientの初期化

まず、新しいSwiftファイルを作成し、以下のコードを記述します。

Supabase.swift
import Foundation
import Supabase

let supabase = SupabaseClient(
  supabaseURL: URL(string: "YOUR_SUPABASE_URL")!,
  supabaseKey: "YOUR_SUPABASE_ANON_KEY"
)

ここで、"YOUR_SUPABASE_URL""YOUR_SUPABASE_ANON_KEY"は、Supabaseプロジェクトの設定画面から取得した実際の値に置き換える必要があります。

インポートエラーの解決

しかし、import Supabaseを記述すると、以下のようなエラーが発生する場合があります。

Supabaseのエラー画面

このエラーは、Supabaseパッケージが正しくリンクされていないことを示しています。
Supabaseのドキュメントには以下のように記載されています。

Install using Swift Package Manager#
You can install Supabase package using Swift Package Manager.
The package exposes multiple libraries, you can choose between adding all of them using Supabase, or some of:

この問題を解決するには、以下の手順を実行します。

  1. Xcodeで、プロジェクトナビゲータからプロジェクトを選択します。
  2. 「Targets」セクションで該当のターゲットを選択し、「Build Phases」タブを開きます。
  3. 「Link Binary With Libraries」セクションで「+」ボタンをクリックします。
  4. 表示されたリストから「Supabase」を探して選択し、「Add」をクリックします。

Supabaseライブラリのリンク画面

これにより、SupabaseライブラリがプロジェクトとLinkされ、インポートエラーが解消されるはずです。

https://github.com/orgs/supabase/discussions/19764

環境の切り替え

開発過程では、開発環境と本番環境を適切に分離することが重要です。
xcconfigファイルを使用することで、これらの環境を効率的に切り替えることができます。

xcconfigファイルの作成

まず、プロジェクトのルートディレクトリに Config フォルダを作成し、その中に以下の2つのファイルを作成します。

  • Debug.xcconfig
  • Release.xcconfig

xcconfigファイルの設定

各ファイルに、環境固有の変数を記述します。

Debug.xcconfig
INFOPLIST_KEY_CFBundleDisplayName = $(TARGET_NAME)-dev
PRODUCT_BUNDLE_IDENTIFIER = YOUR_BUNDLE_ID-debug
BASE_URL = YOUR_SUPABASE_URL
API_KEY = YOUR_SUPABASE_ANON_KEY
Release.xcconfig
INFOPLIST_KEY_CFBundleDisplayName = $(TARGET_NAME)
PRODUCT_BUNDLE_IDENTIFIER = YOUR_BUNDLE_ID
BASE_URL = YOUR_SUPABASE_URL
API_KEY = YOUR_SUPABASE_ANON_KEY

Info.plistの設定

Info.plistファイルを開き、以下の項目を追加します。

Info.plist
<dict>
    <key>BASE_URL</key>
    <string>${BASE_URL}</string>
    <key>API_KEY</key>
    <string>${API_KEY}</string>
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>io.supabase.supabase-sample</string>
            </array>
        </dict>
    </array>
</dict>

これにより、xcconfigファイルで定義した値をInfo.plistから参照できるようになります。

Schemeの編集

Xcodeのスキームを適切に設定することで、開発環境と本番環境を効率的に切り替えることができます。

Edit Schemeの選択

  1. Xcodeのツールバーで現在のスキームをクリックします。
  2. ドロップダウンメニューから「Edit Scheme」を選択します。

Scheme選択画面

新しいSchemeの作成

  1. 「Duplicate Scheme」をクリックします。
  2. 新しいスキームに適切な名前を付けます。

Duplicate選択

Debug用とRelease用のSchemeを設定

  1. 左側のメニューから「Run」を選択します。
  2. 「Build Configuration」を適切に設定します。
    • Debug用スキームでは「Debug」を選択
    • Release用スキームでは「Release」を選択

Scheme編集画面

xcconfigファイルの関連付け

  1. プロジェクトナビゲータでプロジェクトファイルを選択します。
  2. 「Info」タブを開きます。
  3. 「Configurations」セクションで、以下のように設定します。
    • Debugビルドには「Debug.xcconfig」を選択
    • Releaseビルドには「Release.xcconfig」を選択

PROJECT画面

以上の設定により、visionOSアプリケーションの開発において、Supabaseの開発環境と本番環境を効率的に切り替えることができます。

環境変数の使用

Info.plistファイルで定義した環境変数をアプリケーション内で使用するには、Bundle.main.infoDictionaryを活用します。
以下のように、Supabase.swiftファイルを修正します。

Supabase.swift
import Foundation
import Supabase

let supabase = SupabaseClient(
    supabaseURL: URL(string: Bundle.main.infoDictionary?["BASE_URL"] as? String ?? "")!,
    supabaseKey: Bundle.main.infoDictionary?["API_KEY"] as? String ?? ""
)

gitignoreの設定

プロジェクトのセキュリティを確保するためには、機密情報を含むファイルをバージョン管理システムから除外することが重要です。

.gitignore
## Config files containing secret keys
**/Debug.xcconfig
**/Release.xcconfig

ログイン画面の作成

visionOSアプリケーションでSupabaseを使用したログイン機能を実装します。
以下のコードは、メールアドレスを使用したマジックリンク認証を行うためのAuthViewを定義しています。
このログイン方式は、パスワードレスで安全性が高く、ユーザーの利便性も考慮されています。

AuthView.swift
import SwiftUI
import Supabase

struct AuthView: View {
    @State private var email = ""
    @State private var isLoading = false
    @State var result: Result<Void, Error>?

    var body: some View {
        VStack(spacing: 20) {
            Text("Welcome")
                .font(.largeTitle)
                .fontWeight(.bold)

            VStack(alignment: .leading, spacing: 8) {
                TextField("Enter your email", text: $email)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .autocapitalization(.none)
                    .keyboardType(.emailAddress)
            }
            if let result {
                Section {
                    switch result {
                    case .success:
                        Text("Check your inbox.")
                    case .failure(let error):
                        Text(error.localizedDescription).foregroundStyle(.red)
                    }
                }
            }
            Button(action: login) {
                if isLoading {
                    ProgressView()
                        .progressViewStyle(CircularProgressViewStyle())
                } else {
                    Text("Log In")
                        .frame(minWidth: 0, maxWidth: .infinity)
                }
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            .disabled(email.isEmpty || isLoading)
        }
        .padding()
        .frame(minWidth: 300, idealWidth: 350, maxWidth: 400, minHeight: 300, idealHeight: 350, maxHeight: 400)
        .onOpenURL(perform: { url in
            Task {
                do {
                    try await supabase.auth.session(from: url)
                } catch {
                    self.result = .failure(error)
                }
            }
        })
    }

    func login() {
        Task {
            isLoading = true
            defer { isLoading = false }

            do {
                try await supabase.auth.signInWithOTP(
                    email: email,
                    redirectTo: URL(string: "io.supabase.supabase-sample://login-callback")
                )
                result = .success(())
            } catch {
                result = .failure(error)
            }
        }
    }
}

.onOpenURL モディファイアを使用して、アプリが起動されたときのURLを処理します。
これは、ユーザーがマジックリンクをクリックしてアプリに戻ってきたときに呼び出されます。
あとはContentViewなどでログインしているかチェックなどしてログイン後の画面に切り替えるとよいでしょう。

ContentView.swift
import SwiftUI
import Supabase

struct ContentView: View {
    @State var isAuthenticated = false

    var body: some View {
        Group {
            if isAuthenticated {
                ProfileView()
            } else {
                AuthView()
            }
        }
        .task {
            for await state in supabase.auth.authStateChanges {
                if [.initialSession, .signedIn, .signedOut].contains(state.event) {
                    isAuthenticated = state.session != nil
                }
            }
        }
    }
}

以上の実装により、visionOSアプリケーションでSupabaseを使用した基本的な認証フローを実現できます。

まとめ

本記事では、visionOSアプリケーションにSupabaseを導入し、効率的な開発環境を構築する方法について詳しく解説しました。
特に、認証機能の実装に焦点を当て、セキュアで使いやすいログインフローを作成する方法を示しました。

今後も、visionOSの進化に合わせて、より高度な機能や最適化テクニックについて発信していく予定です。
この記事が皆様のvisionOS開発の一助となれば幸いです。もし参考になったと思われましたら、ぜひ♡をお願いいたします。皆様のフィードバックが、今後のコンテンツ作成の励みになります。

参考資料

https://supabase.com/docs/guides/getting-started/tutorials/with-swift

Discussion