SwiftUI 사용자 인증 구현하기: Firebase Auth 활용

작성일 :

SwiftUI 사용자 인증 구현하기: Firebase Auth 활용

SwiftUI는 iOS 애플리케이션 개발을 위한 강력하고 직관적인 프레임워크입니다. 앱에 사용자 인증 기능을 추가하는 것은 많은 애플리케이션에서 필수적인 요소입니다. 이 글에서는 Firebase Auth를 사용하여 SwiftUI 애플리케이션에 사용자 인증 시스템을 구현하는 방법을 설명하겠습니다.

Firebase Auth 설정

첫 번째로, Firebase 프로젝트를 설정하고 Firebase Auth를 구성하는 방법을 알아보겠습니다.

  1. Firebase에 프로젝트 생성: Firebase 콘솔(🔗 https://console.firebase.google.com/)로 이동하여 새 프로젝트를 생성합니다.
  2. iOS 앱 등록하기: Firebase 프로젝트에 iOS 앱을 추가합니다. GoogleService-Info.plist 파일을 다운로드하여 Xcode 프로젝트에 추가합니다.
  3. Firebase Auth 활성화하기: Firebase 콘솔에서 'Authentication' 섹션으로 이동하여 이메일/비밀번호 인증을 활성화합니다.
  4. Firebase SDK 설치: Swift Package Manager(SPM)나 CocoaPods를 사용하여 Firebase SDK를 설치합니다. Swift Package Manager를 사용하는 경우 다음 처럼 사용합니다:
    swift
    dependencies: [
        .package(url: "https://github.com/firebase/firebase-ios-sdk.git", from: "8.0.0")
    ]

SwiftUI 프로젝트 설정

이제 Xcode 프로젝트에서 SwiftUI를 사용하여 Firebase Auth를 설정하는 과정을 시작하겠습니다. Firebase 초기화를 위해 AppDelegateSceneDelegate를 설정해야 합니다.

  1. AppDelegate 설정: AppDelegate 파일을 생성하고, Firebase를 초기화합니다.

    swift
    import UIKit
    import Firebase
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            FirebaseApp.configure()
            return true
        }
    }
  2. SceneDelegate 설정: SceneDelegate 파일을 업데이트합니다.

    swift
    import UIKit
    import SwiftUI
    
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
        func scene(_ scene: UIScene, willConnectTo session: UIScene.Session, options connectionOptions: UIScene.ConnectionOptions) {
            let contentView = ContentView()
            if let windowScene = scene as? UIWindowScene {
                let window = UIWindow(windowScene: windowScene)
                window.rootViewController = UIHostingController(rootView: contentView)
                self.window = window
                window.makeKeyAndVisible()
            }
        }
    }

사용자 인터페이스 작성

사용자 인증 인터페이스를 작성하기 위해 SwiftUI 뷰를 생성합니다.

  1. 로그인 화면: LoginView를 생성하여 사용자로부터 이메일과 비밀번호를 입력받는 화면을 만듭니다.

    swift
    import SwiftUI
    
    struct LoginView: View {
        @State private var email: String = ""
        @State private var password: String = ""
        @ObservedObject var viewModel: AuthViewModel
    
        var body: some View {
            VStack {
                TextField("Email", text: $email)
                    .autocapitalization(.none)
                    .padding()
                    .background(Color.gray.opacity(0.2))
                    .cornerRadius(5.0)
                SecureField("Password", text: $password)
                    .padding()
                    .background(Color.gray.opacity(0.2))
                    .cornerRadius(5.0)
                Button(action: {
                    viewModel.signIn(email: email, password: password)
                }) {
                    Text("Login")
                        .foregroundColor(.white)
                        .padding()
                        .background(Color.blue)
                        .cornerRadius(5.0)
                }
            }
            .padding()
        }
    }
  2. 회원가입 화면: 사용자가 새로운 계정을 생성할 수 있는 SignUpView를 만듭니다.

    swift
    import SwiftUI
    
    struct SignUpView: View {
        @State private var email: String = ""
        @State private var password: String = ""
        @ObservedObject var viewModel: AuthViewModel
    
        var body: some View {
            VStack {
                TextField("Email", text: $email)
                    .autocapitalization(.none)
                    .padding()
                    .background(Color.gray.opacity(0.2))
                    .cornerRadius(5.0)
                SecureField("Password", text: $password)
                    .padding()
                    .background(Color.gray.opacity(0.2))
                    .cornerRadius(5.0)
                Button(action: {
                    viewModel.signUp(email: email, password: password)
                }) {
                    Text("Sign Up")
                        .foregroundColor(.white)
                        .padding()
                        .background(Color.green)
                        .cornerRadius(5.0)
                }
            }
            .padding()
        }
    }

ViewModel 설정

이제 Firebase Auth를 사용하여 실제 인증 로직을 처리하는 AuthViewModel을 구성합니다.

  1. AuthViewModel: Firebase를 사용하여 사용자 인증을 처리합니다.
    swift
    import Foundation
    import FirebaseAuth
    
    class AuthViewModel: ObservableObject {
        @Published var isLoggedIn: Bool = false
        private var auth = Auth.auth()
    
        func signIn(email: String, password: String) {
            auth.signIn(withEmail: email, password: password) { [weak self] result, error in
                if let error = error {
                    print("Error signing in: \(error.localizedDescription)")
                } else {
                    self?.isLoggedIn = true
                }
            }
        }
    
        func signUp(email: String, password: String) {
            auth.createUser(withEmail: email, password: password) { [weak self] result, error in
                if let error = error {
                    print("Error signing up: \(error.localizedDescription)")
                } else {
                    self?.isLoggedIn = true
                }
            }
        }
    }

통합 및 완료

이제 모든 구성 요소를 통합하여 전체 애플리케이션을 완성합니다.

  1. ContentView에서 조건에 따라 다른 뷰를 보여줍니다.
    swift
    import SwiftUI
    
    struct ContentView: View {
        @StateObject var viewModel = AuthViewModel()
    
        var body: some View {
            if viewModel.isLoggedIn {
                Text("Welcome!")
            } else {
                VStack {
                    LoginView(viewModel: viewModel)
                    SignUpView(viewModel: viewModel)
                }
            }
        }
    }

이렇게 하면 Firebase Auth를 사용한 SwiftUI 애플리케이션의 사용자 인증 기능이 완성됩니다. 이제 사용자 인증 상태에 따라 적절한 화면을 표시할 수 있게 되었습니다.