swiftUI入門

「カウンターアプリ」ログイン機能を実装

カウンターアプリにfirebase利用したシンプルなログイン機能を追加。

AppDelegate

import SwiftUI
import FirebaseCore

class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    FirebaseApp.configure()
    return true
  }
}
@main
struct YourApp: App {
  // register app delegate for Firebase setup
  @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

  var body: some Scene {
    WindowGroup {
      NavigationView {
        ContentView()
      }
    }
  }
}

解説

このSwiftUIのコードは、Firebaseを使用するiOSアプリを設定するためのものです。各部分を詳しく解説していきます。


1. import

import SwiftUI
import FirebaseCore
  • SwiftUI: SwiftUIのフレームワークをインポートし、UIを作成するために使用します。
  • FirebaseCore: Firebaseのコア機能を提供するモジュールをインポートします。

2. AppDelegate クラス

class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    FirebaseApp.configure()
    return true
  }
}
  • AppDelegate は、NSObject を継承し、UIApplicationDelegate プロトコルに準拠しています。
  • application(_:didFinishLaunchingWithOptions:) メソッドは、アプリが起動したときに最初に呼ばれる処理を定義します。
  • FirebaseApp.configure(): Firebaseの初期設定を行います。
  • return true: 正常に起動したことを示します。

3. YourApp 構造体

@main
struct YourApp: App {
  // register app delegate for Firebase setup
  @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

  var body: some Scene {
    WindowGroup {
      NavigationView {
        ContentView()
      }
    }
  }
}
  • @main を付けることで、アプリのエントリーポイントとして認識されます。
  • @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate:
  • AppDelegate をアプリの UIApplicationDelegate として登録し、Firebaseの初期設定が実行されるようにします。
  • body: some Scene:
  • WindowGroup を使って、アプリのメインウィンドウを定義します。
  • NavigationView 内に ContentView() を配置し、画面遷移を可能にします。

このコードの役割

  1. AppDelegate で Firebase をセットアップ。
  2. YourAppUIApplicationDelegateAdaptor を使って AppDelegate を登録。
  3. ContentView()NavigationView 内で表示し、ナビゲーション機能を提供。

Firebaseを導入し、SwiftUIでナビゲーション付きのアプリを構築する基本的な構成になっています。

ContentView

import SwiftUI
import FirebaseAuth

struct ContentView: View {
    @State private var count = 0  // 状態変数
    @State private var isLoggedIn = false
    @State private var email = ""
    @State private var password = ""
    
    var body: some View {
        VStack(spacing: 20) {
            if isLoggedIn {
                Text("カウンター: \(count)")
                    .font(.largeTitle)
                    .padding()
                
                HStack {
                    Button(action: { count -= 1 }) {
                        Text("−")
                            .font(.largeTitle)
                            .frame(width: 80, height: 80)
                            .background(Color.red.opacity(0.7))
                            .foregroundColor(.white)
                            .clipShape(Circle())
                    }
                    
                    Button(action: { count += 1 }) {
                        Text("+")
                            .font(.largeTitle)
                            .frame(width: 80, height: 80)
                            .background(Color.blue.opacity(0.7))
                            .foregroundColor(.white)
                            .clipShape(Circle())
                    }
                }
                
                Button("ログアウト") {
                    logout()
                }
                .padding()
            } else {
                VStack {
                    TextField("Email", text: $email)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                    SecureField("Password", text: $password)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                    Button("ログイン") {
                        login()
                    }
                    .padding()
                }
            }
        }
    }
    
    func login() {
        Auth.auth().signIn(withEmail: email, password: password) { result, error in
            if error == nil {
                isLoggedIn = true
            }
        }
    }
    
    func logout() {
        do {
            try Auth.auth().signOut()
            isLoggedIn = false
        } catch {
            print("ログアウトに失敗しました: \(error.localizedDescription)")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

解説

このSwiftUIのコードは、Firebase Authenticationを使ってログイン認証を行い、認証後にカウンターアプリを操作できるシンプルなアプリです。


コードの概要

  1. ログイン画面
  • TextFieldSecureFieldを使ってメールアドレスとパスワードを入力
  • 「ログイン」ボタンを押すと、Firebase Authenticationを使って認証を実行
  1. カウンター画面(ログイン後)
  • 現在のカウントを表示 (Text("カウンター: \(count)"))
  • 「−」ボタンでカウント減少、「+」ボタンでカウント増加**
  • 「ログアウト」ボタンでログアウトし、ログイン画面に戻る

コードの詳細解説

1. @State変数

@State private var count = 0  
@State private var isLoggedIn = false
@State private var email = ""
@State private var password = ""
  • count:カウント値を保持(カウンターの数字)
  • isLoggedIn:ログイン状態を管理(trueならカウンター画面、falseならログイン画面を表示)
  • email / password:ユーザーが入力するメールアドレスとパスワードを保持

2. bodyの処理

ログイン状態 (isLoggedIn == true) の場合
if isLoggedIn {
    Text("カウンター: \(count)")
        .font(.largeTitle)
        .padding()

    HStack {
        Button(action: { count -= 1 }) {
            Text("−")
                .font(.largeTitle)
                .frame(width: 80, height: 80)
                .background(Color.red.opacity(0.7))
                .foregroundColor(.white)
                .clipShape(Circle())
        }

        Button(action: { count += 1 }) {
            Text("+")
                .font(.largeTitle)
                .frame(width: 80, height: 80)
                .background(Color.blue.opacity(0.7))
                .foregroundColor(.white)
                .clipShape(Circle())
        }
    }

    Button("ログアウト") {
        logout()
    }
    .padding()
}

カウンター機能

  • Text("カウンター: \(count)") でカウンターの値を表示
  • 「+」ボタンで count増やす
  • 「−」ボタンで count減らす
  • clipShape(Circle()) でボタンを円形にする

ログアウト機能

  • 「ログアウト」ボタンを押すと logout() 関数が実行される

ログイン状態 (isLoggedIn == false) の場合
else {
    VStack {
        TextField("Email", text: $email)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .padding()
        SecureField("Password", text: $password)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .padding()
        Button("ログイン") {
            login()
        }
        .padding()
    }
}

ログイン画面

  • TextFieldメールアドレス
  • SecureFieldパスワード
  • 「ログイン」ボタンで login() を実行

3. Firebaseログイン処理

ログイン関数 (login())
func login() {
    Auth.auth().signIn(withEmail: email, password: password) { result, error in
        if error == nil {
            isLoggedIn = true
        }
    }
}

処理内容

  • Firebase Authentication の signIn(withEmail:password:) を使ってログイン
  • エラーがなければ isLoggedIn = true にし、カウンター画面に遷移

ログアウト関数 (logout())
func logout() {
    do {
        try Auth.auth().signOut()
        isLoggedIn = false
    } catch {
        print("ログアウトに失敗しました: \(error.localizedDescription)")
    }
}

処理内容

  • Auth.auth().signOut() を呼び出してログアウト
  • 成功すれば isLoggedIn = false にしてログイン画面に戻る
  • エラーが発生した場合は print() でログ出力

動作の流れ

  1. 起動時
  • isLoggedIn = false なので、ログイン画面が表示
  1. メールアドレスとパスワードを入力し「ログイン」ボタンを押す
  • Firebase Authenticationでログイン成功すれば isLoggedIn = true
  • カウンター画面に遷移
  1. カウンターの増減
  • 「+」ボタンを押すと count が増加
  • 「−」ボタンを押すと count が減少
  1. ログアウト
  • 「ログアウト」ボタンを押すと logout() 実行
  • Firebaseからサインアウトし、isLoggedIn = false になり、ログイン画面に戻る

改善点 & 追加機能の提案

1. ログインのエラーハンドリング

func login() {
    Auth.auth().signIn(withEmail: email, password: password) { result, error in
        if let error = error {
            print("ログインに失敗: \(error.localizedDescription)")
        } else {
            isLoggedIn = true
        }
    }
}

エラー時に適切なメッセージを表示

2. ユーザー登録機能

  • Firebase Authentication を使って新規登録機能を追加できる
func register() {
    Auth.auth().createUser(withEmail: email, password: password) { result, error in
        if let error = error {
            print("登録失敗: \(error.localizedDescription)")
        } else {
            print("ユーザー登録成功")
            isLoggedIn = true
        }
    }
}

新規登録ボタンを追加し、初回ログインを可能にする

3. count の保存

  • @AppStorage を使えば、アプリ終了後もカウントを保持できる
@AppStorage("count") private var count = 0

まとめ

Firebase Authenticationを使ったログイン認証
ログイン後はカウンター機能を提供
ログアウト時に画面をリセット
エラーハンドリングや新規登録機能の追加で改善可能

シンプルなアプリですが、認証 & 状態管理の基本を学ぶのに適したSwiftUIの実装です! 🚀

シュミレーターでテストする場合、⌘K を押すと、ソフトウェアキーボードが出現して入力がスムーズですよ!