-
Firebase Authentication κΈ°λ₯μ μ¬μ©νμ¬ μ¬μ©μ λ‘κ·ΈμΈ κΈ°λ₯ ꡬνν©λλ€
-
Email / Password νμκ°μ ν, λ‘κ·ΈμΈ
-
Google ID λ‘ λ‘κ·ΈμΈ
-
Apple ID λ‘ λ‘κ·ΈμΈ
-
Firebase console μμ νλ‘μ νΈ μΆκ° νλ€μμ, ios μ±μ μΆκ°νμ¬ μμνκΈ°λ₯Ό λλ₯΄κ³ xcode λ΄μ νλ‘μ νΈ
Bundle identifier
λ₯Ό Apple λ²λ€ ID μ μΆκ° μν΅λλ€. κ·Έλ¦¬κ³ , μ± λ±λ‘μ ν©λλ€ -
ꡬμ±νμΌμ μμ±λ
GoogleService-Info.plist
λ₯Ό λ€μ΄λ‘λν΄μ νλ‘μ νΈ root κ²½λ‘μ μΆκ° μν΅λλ€ -
CocoaPods μ ν΅ν΄ Firebase SDK ν¨ν€μ§λ₯Ό νλ‘μ νΈ μμ μ€μΉ ν©λλ€
pod init
# in Podfile
...
# Pods for 08_firebase_login_app
pod 'Firebase/Auth'
...
- μΆκ°νκ³ terminal μμ
pod install
ν΄μ Firebase/Auth SDK μ€μΉ
μ€μΉ μμΈν 보기 - https://firebase.google.com/docs/ios/installation-methods?authuser=0#cocoapods
-
Pod μ μΆκ°νλ©΄ xcode λ₯Ό workspace λ‘ λ³κ²½νκ³ νλ‘μ νΈ μμν΄μΌ λ¨
-
Root κ²½λ‘μ AppDelegate μ κ°μ firebase initialization ν΄μ€μΌ App μμ μ€νμ΄ λ©λλ€
import UIKit
import Firebase
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// Firebase init
FirebaseApp.configure()
return true
}
- Authentication λ©λ΄μ κ°μ μμνκΈ° νκ³ μ 곡 μ 체μμ email/password λ₯Ό νμ± ν μν΅λλ€
// in EnterEmailViewController.swift
// MARK: Actions
@IBAction func tabNextBtn(_ sender: UIButton) {
// Firebase email/ password μΈμ¦
let email = emailTextField.text ?? "" // nilμ΄λ©΄ optional λ‘ λΉκ°μΌλ‘ μ²λ¦¬
let password = passwordTextField.text ?? ""
// Firebase μ κ· μ¬μ©μ μμ±
Auth.auth().createUser(withEmail: email, password: password) { [weak self] authResult, error in
guard let self = self else { return } // μΌμμ μΌλ‘ Strong μ°Έμ‘° λκ² ν¨
self.showMainViewController() // λ‘κ·ΈμΈμ΄ μ¬λλ‘ λλ¬μλ mainView λ‘ μ΄λ
}
}
// MARK: Methods
// λ‘κ·ΈμΈ μ±κ³΅μ mainViewController λ‘ μ΄λ νλ method
private func showMainViewController() {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let mainViewController = storyboard.instantiateViewController(identifier: "MainViewController")
mainViewController.modalPresentationStyle = .fullScreen
navigationController?.show(mainViewController, sender: nil)
}
// in MainViewController.swift
// MARK: Actions
@IBAction func tabLogoutBtn(_ sender: UIButton) {
// λ‘κ·Έμμ method
let firebaseAuth = Auth.auth()
do { // error κ° λ°μνμ§ μμΌλ©΄
try firebaseAuth.signOut()
// RootViewController λ‘ μ΄λ
self.navigationController?.popToRootViewController(animated: true)
} catch let singOutError as NSError {
debugPrint("ERROR : signout \(singOutError.localizedDescription)")
}
}
- λ¨Όμ firebase μ¬μ΄νΈμμ Google μ sign-in-method μ 곡μ μ²΄λ‘ λ±λ‘ ν©λλ€
- Google login μ μ¬μ©νκΈ° μν΄μλ μΆκ°λ‘ Podfile μμ googleSignIn νν€μ§λ₯Ό μ€μΉν΄ μ€λλ€
# in Podfile
target '08_firebase_login_app' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for 08_firebase_login_app
pod 'Firebase/Auth'
pod 'GoogleSignedIn'
end
- Google λ‘κ·ΈμΈμ μ¬μ©νλ €λ©΄, λ§μΆ€ URL schema λ₯Ό ꡬμ±ν΄μ£Όμ¬μΌ ν©λλ€. μ²μ firebase μ°κ²°μ μ¬μ©λ
GoogleService-info.plist
νμΌμμREVERSED_CLIENT_ID
κ°μ 볡μ¬ν΄μ νλ‘μ νΈTargets
μInfo
μμURL Types
μURL Schemes
μ 볡μ¬ν κ°μ λΆμ¬ λ£κΈ° ν΄ μ€λλ€ (μ΄ κ°μ μ±μλΉμ€λ§λ€ κ°κ° λ€μ€ κ°μ κ°μ§κ³ , μ΄ κ°μ ν΅ν΄μ Google μ κΆνμ μμν κ²μ ꡬλΆνκ² λ¨)
Google λ‘ λ‘κ·ΈμΈ official reference - https://firebase.google.com/docs/auth/ios/google-signin?hl=ko#swift
GoogleSignIn v.6.0.0 κΈ°μ€ - https://developers.google.com/identity/sign-in/ios/release
π GIDSignIn sharedInstance is now a class property.
-
κΈ°μ‘΄μ method λ‘ μ 곡λμλ
sharedInstance()
κ° class μ property λ‘ λ³κ²½λμμ΅λλ€ -
GIDSignIn.sharedInstance()
=>GIDSignIn.sharedInstance
π AppDelegate.swift
μμ GIDSignInDelegate
μμ²΄κ° μμ λμμ΅λλ€(λ°λ‘ delegate λ₯Ό ꡬννμ§ μμ λ λ©λλ€)
(The GIDSignInDelegate protocol has been removed in favor of GIDSignInCallback and GIDDisconnectCallback blocks.)
π GIDSignInButton
no longer makes calls to GIDSignIn
internally and will need to be wired to an IBAction
similar in order for you to call signInWithConfiguration:presentingViewController:callback:
to initiate a sign-in flow. (GIDSignInButton μ΄ μλμ μΌλ‘ GIDSignIn μ νΈμΆνμ§ μμΌλ―λ‘ μ°λ¦¬κ° κΈ°μ‘΄μ AppDelegate λ΄μ GIDSignInDelegate μ ν΅ν΄ ꡬνν κ²μ googleLoginButtonAction IBAction λ©μλ λ΄μ ꡬνν΄μ£Όμ΄μΌ ν©λλ€)
// AppDelegate.swift
import UIKit
import Firebase
import GoogleSignIn
@main
class AppDelegate: UIResponder, UIApplicationDelegate{
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// Firebase init
FirebaseApp.configure()
return true
}
// Google μ μΈμ¦ process κ° λλ λ, app μ΄ μμ νλ urlμ μ²λ¦¬νλ method
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance.handle(url)
}
.....
}
// in LoginViewController.swift
// MARK: Action
// Google Login action
@IBAction func tapGoogleLoginBtn(_ sender: UIButton) {
// λ²νΌ λλ₯΄λ©΄ google login webView κ° λμ€κ² νλ logic
//
guard let clientID = FirebaseApp.app()?.options.clientID else { return }
let config = GIDConfiguration(clientID: clientID)
GIDSignIn.sharedInstance.signIn(with: config, presenting: self) { [unowned self] user, error in
if let error = error {
print("ERROR", error.localizedDescription)
return
}
guard let authentication = user?.authentication,
let idToken = authentication.idToken else { return }
let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken)
// λ‘κ·ΈμΈ μλ£λ credential κ°μ mainViewController μ λκΈ°λ method μ€ν
Auth.auth().signIn(with: credential) { _, _ in
self.showMainViewController()
}
}
}
// MARK: Methods
// login λ credeatial κ°μ mainViewController μ λκΈ°λ method
private func showMainViewController() {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let mainViewController = storyboard.instantiateViewController(identifier: "MainViewController")
mainViewController.modalPresentationStyle = .fullScreen
UIApplication.shared.windows.first?.rootViewController?.show(mainViewController, sender: nil)
}
- Firebase λ μ¬μ©μ κ΄λ¦¬μλν λ€μν method λ±μ μ 곡νκ³ μλλ°, κ°μ₯ μμ£Ό μ¬μ©λλ λΉλ°λ²νΈ κ²μ΄ λΉλ°λ²νΈ λ³κ²½μ λλ€.
μμ
ID λ‘ λ‘κ·ΈμΈ ν κ²½μ°μλ App μ체 λ΄μμ λΉλ°λ²νΈ λ³κ²½μ ν μ μκ³ , email/ password λ°©μμΌλ‘ λ±λ‘ν κ³μ μ νν΄μ sendPasswordReset()
μ ν΅ν΄μ reset κ°λ₯ν email μ λ³΄λΌ μ μμ΅λλ€
// in mainViewController.swift
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// viewμ navigation 보μ΄μ§ μκΈ°
navigationController?.navigationBar.isHidden = true
// λ‘κ·ΈμΈμ λ겨 λ°μ email νλ©΄μ λνλ΄κΈ°
let email = Auth.auth().currentUser?.email ?? "User"
welcomeLabel.text = """
Welcome.
\(email)
"""
// resetPasswordBtn 보μ΄κ² νκΈ° (google Signin κ²½μ°μλ resetPasswordBtn μ μ¨κΉ
let isEmailLogin = Auth.auth().currentUser?.providerData[0].providerID == "password"
resetPasswordBtn.isHidden = !isEmailLogin
}
// Reset password action
@IBAction func tabResetPasswordBtn(_ sender: UIButton) {
// Google Auth κΈ°λ₯μ ν΅ν΄μ μ¬μ©μμ email μ reset ν μ μλ email μ 보λ΄κ² λ¨
let email = Auth.auth().currentUser?.email ?? ""
Auth.auth().sendPasswordReset(withEmail: email, completion: nil)
}
Apple κ³μ μ μν λ‘κ·ΈμΈ κΈ°λ₯μ μ 곡νλ €λ©΄, Apple Developer νλ‘κ·Έλ¨μ κ°μ μ ν΄μΌ ν©λλ€ (1λ λ¨μλ‘ κ΅¬λ ν΄μΌ λ¨) - μ λ£ κ²°μ ν, μΆν μ λ°μ΄νΈ μμ
Describing check point in details in Jacob's DevLog - https://jacobko.info/ios/ios-08/
- λμΌ κ³μ μΌλ‘ κ³μ κ°μ νλκ²μ λ°©μ§νμ§ νκ³ , λ‘κ·ΈμΈ μ²λ¦¬νκΈ°λ‘ νκΈ°
// Firebase μ κ· μ¬μ©μ μμ±
Auth.auth().createUser(withEmail: email, password: password) { [weak self] authResult, error in
guard let self = self else { return } // μΌμμ μΌλ‘ Strong μ°Έμ‘° λκ² ν¨
if let error = error {
let code = (error as NSError).code
// μλ¬ μ²λ¦¬
switch code {
case 17007: // μ΄λ―Έ κ°μ
ν κ³μ μΌ λ
// λ‘κ·ΈμΈ νκΈ° μ²λ¦¬
self.loginUser(withEmail: email, password: password)
default:
self.errorMessageLabel.text = error.localizedDescription // μλ¬ λ©μΈμ§ νμ
}
} else { // error κ° λ°μνμ§ μμμ κ²½μ°
self.showMainViewController() // λ‘κ·ΈμΈμ΄ μ¬λλ‘ λλ¬μλ mainView λ‘ μ΄λ
}
}
}
// λ‘κ·ΈμΈ method
private func loginUser(withEmail email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) {[ weak self] _, error in
guard let self = self else { return }
if let error = error {
self.errorMessageLabel.text = error.localizedDescription
} else {
self.showMainViewController()
}
}
}
πΆ π· π π π
Jacob's DevLog - https://jacobko.info/firebaseios/ios-firebase-01/
firebase documentation - https://firebase.google.com/docs/auth/ios/start
How to Sign in to Your iOS App with Email/Password Using Firebase Authentication - https://medium.com/firebase-developers/ios-firebase-authentication-sdk-email-and-password-login-6a3bb27e0536
fastcampus - https://fastcampus.co.kr/dev_online_iosappfinal