Apple āĻĒā§āĻ˛ā§āϝāĻžāϟāĻĢāĻ°ā§āĻŽā§‡ Google āϏāĻžāχāύ-āχāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻ•āϰ⧁āύ

āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ⧇ Google āϏāĻžāχāύ-āχāύ āϏāĻ‚āĻšāϤ āĻ•āϰ⧇ āφāĻĒāύāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āĻĻ⧇āϰ āϤāĻžāĻĻ⧇āϰ Google āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ Firebase-āĻāϰ āϏāĻžāĻĨ⧇ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻ•āϰāϤ⧇ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤

āφāĻĒāύāĻŋ āĻļ⧁āϰ⧁ āĻ•āϰāĻžāϰ āφāϗ⧇

āĻĢāĻžāϝāĻŧāĻžāϰāĻŦ⧇āϏ āύāĻŋāĻ°ā§āĻ­āϰāϤāĻž āχāύāĻ¸ā§āϟāϞ āĻāĻŦāĻ‚ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰāϤ⧇ āϏ⧁āχāĻĢāϟ āĻĒā§āϝāĻžāϕ⧇āϜ āĻŽā§āϝāĻžāύ⧇āϜāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤

  1. Xcode-āĻ, āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ āĻ–ā§‹āϞāĻžāϰ āϏāĻžāĻĨ⧇, āĻĢāĻžāχāϞ > āĻĒā§āϝāĻžāϕ⧇āϜ āϝ⧋āĻ— āĻ•āϰ⧁āύ -āĻ āύ⧇āĻ­āĻŋāϗ⧇āϟ āĻ•āϰ⧁āύāĨ¤
  2. āĻ…āύ⧁āϰ⧋āϧ āĻ•āϰāĻž āĻšāϞ⧇, Firebase Apple āĻĒā§āĻ˛ā§āϝāĻžāϟāĻĢāĻ°ā§āĻŽ SDK āϏāĻ‚āĻ—ā§āϰāĻšāĻ¸ā§āĻĨāϞ āϝ⧋āĻ— āĻ•āϰ⧁āύ:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Firebase Authentication āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āĻŦ⧇āϛ⧇ āύāĻŋāύāĨ¤
  5. āφāĻĒāύāĻžāϰ āϞāĻ•ā§āĻˇā§āϝ⧇āϰ āĻŦāĻŋāĻ˛ā§āĻĄ āϏ⧇āϟāĻŋāĻ‚āϏ⧇āϰ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āϞāĻŋāĻ™ā§āĻ•āĻžāϰ āĻĢā§āĻ˛ā§āϝāĻžāĻ— āĻŦāĻŋāĻ­āĻžāϗ⧇ -ObjC āĻĒāϤāĻžāĻ•āĻž āϝ⧋āĻ— āĻ•āϰ⧁āύāĨ¤
  6. āĻļ⧇āώ āĻšāϝāĻŧ⧇ āϗ⧇āϞ⧇, Xcode āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ āĻĒāϟāĻ­ā§‚āĻŽāĻŋāϤ⧇ āφāĻĒāύāĻžāϰ āύāĻŋāĻ°ā§āĻ­āϰāϤāĻžāϗ⧁āϞāĻŋ āϏāĻŽāĻžāϧāĻžāύ āĻāĻŦāĻ‚ āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰāĻž āĻļ⧁āϰ⧁ āĻ•āϰāĻŦ⧇āĨ¤

āφāĻĒāύāĻžāϰ āĻĒā§āϰ⧋āĻœā§‡āĻ•ā§āĻŸā§‡ Google āϏāĻžāχāύ-āχāύ SDK āϝ⧋āĻ— āĻ•āϰ⧁āύ

  1. Xcode-āĻ, āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ āĻ–ā§‹āϞāĻžāϰ āϏāĻžāĻĨ⧇, āĻĢāĻžāχāϞ > āĻĒā§āϝāĻžāϕ⧇āϜ āϝ⧋āĻ— āĻ•āϰ⧁āύ -āĻ āύ⧇āĻ­āĻŋāϗ⧇āϟ āĻ•āϰ⧁āύāĨ¤

  2. āĻ…āύ⧁āϰ⧋āϧ āĻ•āϰāĻž āĻšāϞ⧇, Google āϏāĻžāχāύ-āχāύ SDK āϏāĻ‚āĻ—ā§āϰāĻšāĻ¸ā§āĻĨāϞ āϝ⧋āĻ— āĻ•āϰ⧁āύ:

    https://github.com/google/GoogleSignIn-iOS
    
  3. āĻļ⧇āώ āĻšāϝāĻŧ⧇ āϗ⧇āϞ⧇, Xcode āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ āĻĒāϟāĻ­ā§‚āĻŽāĻŋāϤ⧇ āφāĻĒāύāĻžāϰ āύāĻŋāĻ°ā§āĻ­āϰāϤāĻžāϗ⧁āϞāĻŋ āϏāĻŽāĻžāϧāĻžāύ āĻāĻŦāĻ‚ āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰāĻž āĻļ⧁āϰ⧁ āĻ•āϰāĻŦ⧇āĨ¤

āφāĻĒāύāĻžāϰ Firebase āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇āϰ āϜāĻ¨ā§āϝ Google āϏāĻžāχāύ-āχāύ āϏāĻ•ā§āώāĻŽ āĻ•āϰ⧁āύ⧎

āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āĻĻ⧇āϰ Google āϏāĻžāχāύ-āχāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϏāĻžāχāύ āχāύ āĻ•āϰāĻžāϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻāĻŋāϤ⧇, āφāĻĒāύāĻžāϕ⧇ āĻĒā§āϰāĻĨāĻŽā§‡ āφāĻĒāύāĻžāϰ Firebase āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇āϰ āϜāĻ¨ā§āϝ Google āϏāĻžāχāύ-āχāύ āĻĒā§āϰāĻĻāĻžāύāĻ•āĻžāϰ⧀āϕ⧇ āϏāĻ•ā§āώāĻŽ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇:

  1. Firebase āĻ•āύāϏ⧋āϞ⧇ , āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻŦāĻŋāĻ­āĻžāĻ—āϟāĻŋ āϖ⧁āϞ⧁āύāĨ¤
  2. āϏāĻžāχāύ āχāύ āĻĒāĻĻā§āϧāϤāĻŋ āĻŸā§āϝāĻžāĻŦ⧇, Google āĻĒā§āϰāĻĻāĻžāύāĻ•āĻžāϰ⧀ āϏāĻ•ā§āώāĻŽ āĻ•āϰ⧁āύ⧎
  3. āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰ⧁āύ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ⧁āύ.

  4. āφāĻĒāύāĻžāϰ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇āϰ GoogleService-Info.plist āĻĢāĻžāχāϞ⧇āϰ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ āĻāϟāĻŋ āφāĻĒāύāĻžāϰ Xcode āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇ āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻ•āϰ⧁āύāĨ¤ āύāϤ⧁āύ⧇āϰ āϏāĻžāĻĨ⧇ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āϝ⧇āϕ⧋āύ⧋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ“āĻ­āĻžāϰāϰāĻžāχāϟ āĻ•āϰ⧁āύāĨ¤ ( āφāĻĒāύāĻžāϰ iOS āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇ Firebase āϝ⧋āĻ— āĻ•āϰ⧁āύ āĻĻ⧇āϖ⧁āύāĨ¤)

āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āĻšā§‡āĻĄāĻžāϰ āĻĢāĻžāχāϞ āχāĻŽā§āĻĒā§‹āĻ°ā§āϟ āĻ•āϰ⧁āύ

āĻĒā§āϰāĻĨāĻŽā§‡, āφāĻĒāύāĻžāϕ⧇ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ⧇ Firebase SDK āĻāĻŦāĻ‚ Google āϏāĻžāχāύ-āχāύ SDK āĻšā§‡āĻĄāĻžāϰ āĻĢāĻžāχāϞāϗ⧁āϞāĻŋ āφāĻŽāĻĻāĻžāύāĻŋ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇⧎

āϏ⧁āχāĻĢāϟ

import FirebaseCore
import FirebaseAuth
import GoogleSignIn

āωāĻĻā§āĻĻ⧇āĻļā§āϝ-C

@import FirebaseCore;
@import GoogleSignIn;

Google āϏāĻžāχāύ-āχāύ āĻĒā§āϰāϝāĻŧā§‹āĻ— āĻ•āϰ⧁āύ

āĻāχ āĻĒāĻĻāĻ•ā§āώ⧇āĻĒāϗ⧁āϞāĻŋ āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰ⧇ Google āϏāĻžāχāύ-āχāύ āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāύ āĻ•āϰ⧁āύ⧎ iOS-āĻāϰ āϏāĻžāĻĨ⧇ Google āϏāĻžāχāύ-āχāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āĻŦāĻŋāώāϝāĻŧ⧇ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āϜāĻžāύāĻžāϰ āϜāĻ¨ā§āϝ Google āϏāĻžāχāύ-āχāύ āĻĄā§‡āϭ⧇āϞāĻĒāĻžāϰ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻĻ⧇āϖ⧁āύāĨ¤

  1. āφāĻĒāύāĻžāϰ Xcode āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇ āĻ•āĻžāĻ¸ā§āϟāĻŽ URL āĻ¸ā§āĻ•āĻŋāĻŽ āϝ⧋āĻ— āĻ•āϰ⧁āύ:
    1. āφāĻĒāύāĻžāϰ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύ āϖ⧁āϞ⧁āύ: āĻŦāĻžāĻŽ āĻŸā§āϰāĻŋ āĻ­āĻŋāωāϤ⧇ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇āϰ āύāĻžāĻŽ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ⧁āύāĨ¤ āϞāĻ•ā§āĻˇā§āϝ āĻŦāĻŋāĻ­āĻžāĻ— āĻĨ⧇āϕ⧇ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒāϟāĻŋ āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰ⧁āύ, āϤāĻžāϰāĻĒāϰ āϤāĻĨā§āϝ āĻŸā§āϝāĻžāĻŦāϟāĻŋ āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ URL āĻĒā§āϰāĻ•āĻžāϰ āĻŦāĻŋāĻ­āĻžāĻ—āϟāĻŋ āĻĒā§āϰāϏāĻžāϰāĻŋāϤ āĻ•āϰ⧁āύ⧎
    2. + āĻŦā§‹āϤāĻžāĻŽā§‡ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ āφāĻĒāύāĻžāϰ āĻŦāĻŋāĻĒāϰ⧀āϤ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ āφāχāĻĄāĻŋāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ URL āĻ¸ā§āĻ•āĻŋāĻŽ āϝ⧋āĻ— āĻ•āϰ⧁āύāĨ¤ āĻāχ āĻŽāĻžāύāϟāĻŋ āϖ⧁āρāĻœā§‡ āĻĒ⧇āϤ⧇, GoogleService-Info.plist āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύ āĻĢāĻžāχāϞāϟāĻŋ āϖ⧁āϞ⧁āύ āĻāĻŦāĻ‚ REVERSED_CLIENT_ID āϕ⧀āϟāĻŋ āϏāĻ¨ā§āϧāĻžāύ āĻ•āϰ⧁āύ⧎ āϏ⧇āχ āϕ⧀āϟāĻŋāϰ āĻŽāĻžāύ āĻ•āĻĒāĻŋ āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύ āĻĒ⧃āĻˇā§āĻ āĻžāϰ URL āĻ¸ā§āĻ•āĻŋāĻŽ āĻŦāĻ•ā§āϏ⧇ āĻĒ⧇āĻ¸ā§āϟ āĻ•āϰ⧁āύāĨ¤ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ•ā§āώ⧇āĻ¤ā§āϰāϗ⧁āϞāĻŋāϕ⧇ āĻ¸ā§āĻĒāĻ°ā§āĻļ āύāĻž āĻ•āϰ⧇ āϛ⧇āĻĄāĻŧ⧇ āĻĻāĻŋāύāĨ¤

      āϏāĻŽā§āĻĒāĻ¨ā§āύ āĻšāϞ⧇, āφāĻĒāύāĻžāϰ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύāϟāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻ–āĻŋāϤāϗ⧁āϞāĻŋāϰ āĻŽāϤ⧋ āĻĻ⧇āĻ–āϤ⧇ āĻšāĻŦ⧇ (āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ-āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻŽāĻžāύāϗ⧁āϞāĻŋāϰ āϏāĻžāĻĨ⧇):

  2. āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ āĻĒā§āϰāϤāĻŋāύāĻŋāϧāĻŋāϰ application:didFinishLaunchingWithOptions: āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇, FirebaseApp āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ āĻ•āϰ⧁āύāĨ¤

    āϏ⧁āχāĻĢāϟ

    FirebaseApp.configure()

    āωāĻĻā§āĻĻ⧇āĻļā§āϝ-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  3. āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ āĻĒā§āϰāϤāĻŋāύāĻŋāϧāĻŋāϰ application:openURL:options: āĻĒāĻĻā§āϧāϤāĻŋ āĻĒā§āϰāϝāĻŧā§‹āĻ— āĻ•āϰ⧁āύāĨ¤ āĻĒāĻĻā§āϧāϤāĻŋāϟāĻŋāϕ⧇ GIDSignIn āωāĻĻāĻžāĻšāϰāϪ⧇āϰ handleURL āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ āĻ•āϞ āĻ•āϰāĻž āωāϚāĻŋāϤ, āϝāĻž āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāϰ āĻļ⧇āώ⧇ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋ āϝ⧇ URLāϟāĻŋ āĻĒāĻžāĻŦ⧇ āϤāĻž āϏāĻ āĻŋāĻ•āĻ­āĻžāĻŦ⧇ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰāĻŦ⧇āĨ¤

    āϏ⧁āχāĻĢāϟ

    func application(_ app: UIApplication,
                     open url: URL,
                     options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
      return GIDSignIn.sharedInstance.handle(url)
    }

    āωāĻĻā§āĻĻ⧇āĻļā§āϝ-C

    - (BOOL)application:(nonnull UIApplication *)application
                openURL:(nonnull NSURL *)url
                options:(nonnull NSDictionary<NSString *, id> *)options {
      return [[GIDSignIn sharedInstance] handleURL:url];
    }
  4. āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ⧇āϰ āϜāĻ¨ā§āϝ āĻĒā§āϰ⧇āĻœā§‡āĻ¨ā§āϟāĻŋāĻ‚ āĻ­āĻŋāω āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞāĻžāϰ āĻāĻŦāĻ‚ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ āφāχāĻĄāĻŋ Google āϏāĻžāχāύ-āχāύ āĻĒā§āϰāĻĻāĻžāύāĻ•āĻžāϰ⧀āϰ signIn āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ āĻĒāĻžāϏ āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ āĻāϰ āĻĢāϞ⧇ Google āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻŸā§‹āϕ⧇āύ āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ Firebase āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻļāĻ‚āϏāĻžāĻĒāĻ¤ā§āϰ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ:

    āϏ⧁āχāĻĢāϟ

    guard let clientID = FirebaseApp.app()?.options.clientID else { return }
    
    // Create Google Sign In configuration object.
    let config = GIDConfiguration(clientID: clientID)
    GIDSignIn.sharedInstance.configuration = config
    
    // Start the sign in flow!
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { [unowned self] result, error in
      guard error == nil else {
        // ...
      }
    
      guard let user = result?.user,
        let idToken = user.idToken?.tokenString
      else {
        // ...
      }
    
      let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                     accessToken: user.accessToken.tokenString)
    
      // ...
    }

    āωāĻĻā§āĻĻ⧇āĻļā§āϝ-C

    GIDConfiguration *config = [[GIDConfiguration alloc] initWithClientID:[FIRApp defaultApp].options.clientID];
    [GIDSignIn.sharedInstance setConfiguration:config];
    
    __weak __auto_type weakSelf = self;
    [GIDSignIn.sharedInstance signInWithPresentingViewController:self
          completion:^(GIDSignInResult * _Nullable result, NSError * _Nullable error) {
      __auto_type strongSelf = weakSelf;
      if (strongSelf == nil) { return; }
    
      if (error == nil) {
        FIRAuthCredential *credential =
        [FIRGoogleAuthProvider credentialWithIDToken:result.user.idToken.tokenString
                                         accessToken:result.user.accessToken.tokenString];
        // ...
      } else {
        // ...
      }
    }];
  5. āφāĻĒāύāĻžāϰ āĻ¸ā§āĻŸā§‹āϰāĻŋāĻŦā§‹āĻ°ā§āĻĄ, XIB āĻĢāĻžāχāϞ⧇ āĻāĻ•āϟāĻŋ GIDSignInButton āϝ⧋āĻ— āĻ•āϰ⧁āύ āĻŦāĻž āĻāϟāĻŋāϕ⧇ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§āϝāĻžāϟāĻŋāĻ•āĻ­āĻžāĻŦ⧇ āχāύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟāĻŋāϝāĻŧ⧇āϟ āĻ•āϰ⧁āύāĨ¤ āφāĻĒāύāĻžāϰ āĻ¸ā§āĻŸā§‹āϰāĻŋāĻŦā§‹āĻ°ā§āĻĄ āĻŦāĻž XIB āĻĢāĻžāχāϞ⧇ āĻŦā§‹āϤāĻžāĻŽ āϝ⧋āĻ— āĻ•āϰāϤ⧇, āĻāĻ•āϟāĻŋ āĻ­āĻŋāω āϝ⧋āĻ— āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ āĻāϰ āĻ•āĻžāĻ¸ā§āϟāĻŽ āĻ•ā§āϞāĻžāϏ GIDSignInButton āĻ āϏ⧇āϟ āĻ•āϰ⧁āύāĨ¤
  6. āϐāĻšā§āĻ›āĻŋāĻ• : āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻŦā§‹āϤāĻžāĻŽāϟāĻŋ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāχāϜ āĻ•āϰāϤ⧇ āϚāĻžāύ āϤāĻŦ⧇ āύāĻŋāĻŽā§āύāϞāĻŋāĻ–āĻŋāϤāϗ⧁āϞāĻŋ āĻ•āϰ⧁āύ:

    āϏ⧁āχāĻĢāϟ

    1. āφāĻĒāύāĻžāϰ āĻ­āĻŋāω āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞāĻžāϰ⧇, āϏāĻžāχāύ-āχāύ āĻŦā§‹āϤāĻžāĻŽāϟāĻŋāϕ⧇ āĻāĻ•āϟāĻŋ āϏāĻŽā§āĻĒāĻ¤ā§āϤāĻŋ āĻšāĻŋāϏāĻžāĻŦ⧇ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰ⧁āύ⧎
      @IBOutlet weak var signInButton: GIDSignInButton!
    2. āφāĻĒāύāĻŋ āĻāχāĻŽāĻžāĻ¤ā§āϰ āĻ˜ā§‹āώāĻŋāϤ signInButton āϏāĻŽā§āĻĒāĻ¤ā§āϤāĻŋāϤ⧇ āĻŦā§‹āϤāĻžāĻŽāϟāĻŋ āϏāĻ‚āϝ⧁āĻ•ā§āϤ āĻ•āϰ⧁āύāĨ¤
    3. GIDSignInButton āĻ…āĻŦāĻœā§‡āĻ•ā§āĻŸā§‡āϰ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āϏ⧇āϟ āĻ•āϰ⧇ āĻŦā§‹āϤāĻžāĻŽāϟāĻŋ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāχāϜ āĻ•āϰ⧁āύāĨ¤

    āωāĻĻā§āĻĻ⧇āĻļā§āϝ-C

    1. āφāĻĒāύāĻžāϰ āĻ­āĻŋāω āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞāĻžāϰ⧇āϰ āĻšā§‡āĻĄāĻžāϰ āĻĢāĻžāχāϞ⧇, āϏāĻžāχāύ-āχāύ āĻŦā§‹āϤāĻžāĻŽāϟāĻŋāϕ⧇ āĻāĻ•āϟāĻŋ āϏāĻŽā§āĻĒāĻ¤ā§āϤāĻŋ āĻšāĻŋāϏāĻžāĻŦ⧇ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰ⧁āύāĨ¤
      @property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton;
    2. āφāĻĒāύāĻŋ āĻāχāĻŽāĻžāĻ¤ā§āϰ āĻ˜ā§‹āώāĻŋāϤ signInButton āϏāĻŽā§āĻĒāĻ¤ā§āϤāĻŋāϤ⧇ āĻŦā§‹āϤāĻžāĻŽāϟāĻŋ āϏāĻ‚āϝ⧁āĻ•ā§āϤ āĻ•āϰ⧁āύāĨ¤
    3. GIDSignInButton āĻ…āĻŦāĻœā§‡āĻ•ā§āĻŸā§‡āϰ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āϏ⧇āϟ āĻ•āϰ⧇ āĻŦā§‹āϤāĻžāĻŽāϟāĻŋ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāχāϜ āĻ•āϰ⧁āύāĨ¤

Firebase āĻĻāĻŋāϝāĻŧ⧇ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻ•āϰ⧁āύ

āĻ…āĻŦāĻļ⧇āώ⧇, āĻĒā§‚āĻ°ā§āĻŦāĻŦāĻ°ā§āϤ⧀ āϧāĻžāĻĒ⧇ āϤ⧈āϰāĻŋ āĻ•āϰāĻž āĻĒā§āϰāĻŽāĻžāĻŖāĻĒāĻ¤ā§āϰ⧇āϰ āϏāĻžāĻĨ⧇ Firebase āϞāĻ—āχāύ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāϟāĻŋ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ•āϰ⧁āύāĨ¤

āϏ⧁āχāĻĢāϟ

Auth.auth().signIn(with: credential) { result, error in

  // At this point, our user is signed in
}
    

āωāĻĻā§āĻĻ⧇āĻļā§āϝ-C

[[FIRAuth auth] signInWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult,
                                       NSError * _Nullable error) {
    if (isMFAEnabled && error && error.code == FIRAuthErrorCodeSecondFactorRequired) {
      FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
      NSMutableString *displayNameString = [NSMutableString string];
      for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
        [displayNameString appendString:tmpFactorInfo.displayName];
        [displayNameString appendString:@" "];
      }
      [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Select factor to sign in\n%@", displayNameString]
                           completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) {
       FIRPhoneMultiFactorInfo* selectedHint;
       for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
         if ([displayName isEqualToString:tmpFactorInfo.displayName]) {
           selectedHint = (FIRPhoneMultiFactorInfo *)tmpFactorInfo;
         }
       }
       [FIRPhoneAuthProvider.provider
        verifyPhoneNumberWithMultiFactorInfo:selectedHint
        UIDelegate:nil
        multiFactorSession:resolver.session
        completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
          if (error) {
            [self showMessagePrompt:error.localizedDescription];
          } else {
            [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Verification code for %@", selectedHint.displayName]
                                 completionBlock:^(BOOL userPressedOK, NSString *_Nullable verificationCode) {
             FIRPhoneAuthCredential *credential =
                 [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID
                                                              verificationCode:verificationCode];
             FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
             [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
               if (error) {
                 [self showMessagePrompt:error.localizedDescription];
               } else {
                 NSLog(@"Multi factor finanlize sign in succeeded.");
               }
             }];
           }];
          }
        }];
     }];
    }
  else if (error) {
    // ...
    return;
  }
  // User successfully signed in. Get user data from the FIRUser object
  if (authResult == nil) { return; }
  FIRUser *user = authResult.user;
  // ...
}];

āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻĒāĻĻāĻ•ā§āώ⧇āĻĒ

āĻāĻ•āϜāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻĒā§āϰāĻĨāĻŽāĻŦāĻžāϰ āϏāĻžāχāύ āχāύ āĻ•āϰāĻžāϰ āĻĒāϰ⧇, āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟ āϤ⧈āϰāĻŋ āĻ•āϰāĻž āĻšāϝāĻŧ āĻāĻŦāĻ‚ āĻļāĻ‚āϏāĻžāĻĒāĻ¤ā§āϰāϗ⧁āϞāĻŋāϰ āϏāĻžāĻĨ⧇ āϞāĻŋāĻ™ā§āĻ• āĻ•āϰāĻž āĻšāϝāĻŧ—āĻ…āĻ°ā§āĻĨāĻžā§Ž, āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āύāĻžāĻŽ āĻāĻŦāĻ‚ āĻĒāĻžāϏāĻ“āϝāĻŧāĻžāĻ°ā§āĻĄ, āĻĢā§‹āύ āύāĻŽā§āĻŦāϰ, āĻŦāĻž āĻĒā§āϰāĻŽāĻžāĻŖ āĻĒā§āϰāĻĻāĻžāύāĻ•āĻžāϰ⧀āϰ āϤāĻĨā§āϝ — āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϏāĻžāχāύ āχāύ āĻ•āϰ⧇āϛ⧇āύāĨ¤ āĻāχ āύāϤ⧁āύ āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āϟāϟāĻŋ āφāĻĒāύāĻžāϰ āĻĢāĻžāϝāĻŧāĻžāϰāĻŦ⧇āϏ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇āϰ āĻ…āĻ‚āĻļ āĻšāĻŋāϏāĻžāĻŦ⧇ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇ āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϕ⧀āĻ­āĻžāĻŦ⧇ āϏāĻžāχāύ āχāύ āĻ•āϰ⧁āύ āύāĻž āϕ⧇āύ, āφāĻĒāύāĻžāϰ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇āϰ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ…ā§āϝāĻžāĻĒ āϜ⧁āĻĄāĻŧ⧇ āĻāĻ•āϜāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϕ⧇ āĻļāύāĻžāĻ•ā§āϤ āĻ•āϰāϤ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤

  • āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ⧇, āφāĻĒāύāĻŋ User āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻĨ⧇āϕ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻŽā§ŒāϞāĻŋāĻ• āĻĒā§āϰ⧋āĻĢāĻžāχāϞ āϤāĻĨā§āϝ āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āĻĻ⧇āϰ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻĻ⧇āϖ⧁āύāĨ¤

  • āφāĻĒāύāĻžāϰ Firebase Realtime Database āĻāĻŦāĻ‚ Cloud Storage āϏ⧁āϰāĻ•ā§āώāĻž āύāĻŋāϝāĻŧāĻŽā§‡ , āφāĻĒāύāĻŋ auth āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āĻĨ⧇āϕ⧇ āϏāĻžāχāύ-āχāύ āĻ•āϰāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻ…āύāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āφāχāĻĄāĻŋ āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύ āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϕ⧋āύ āĻĄā§‡āϟāĻž āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇ āϤāĻž āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāĻŖ āĻ•āϰāϤ⧇ āĻāϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤

āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āĻŸā§‡ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻĒā§āϰāĻĻāĻžāύāĻ•āĻžāϰ⧀āϰ āĻļāĻ‚āϏāĻžāĻĒāĻ¤ā§āϰ āϞāĻŋāĻ™ā§āĻ• āĻ•āϰ⧇ āĻāĻ•āĻžāϧāĻŋāĻ• āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻĒā§āϰāĻĻāĻžāύāĻ•āĻžāϰ⧀ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āĻĻ⧇āϰ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ⧇ āϏāĻžāχāύ āχāύ āĻ•āϰāĻžāϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤

āĻāĻ•āϜāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϕ⧇ āϏāĻžāχāύ āφāωāϟ āĻ•āϰāϤ⧇, signOut:

āϏ⧁āχāĻĢāϟ

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}

āωāĻĻā§āĻĻ⧇āĻļā§āϝ-C

NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

āφāĻĒāύāĻŋ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻ¤ā§āϰ⧁āϟāĻŋāϰ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻĒāϰāĻŋāϏāϰ⧇āϰ āϜāĻ¨ā§āϝ āĻ¤ā§āϰ⧁āϟāĻŋ āĻšā§āϝāĻžāĻ¨ā§āĻĄāϞāĻŋāĻ‚ āϕ⧋āĻĄ āϝ⧋āĻ— āĻ•āϰāϤ⧇ āϚāĻžāχāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻšā§āϝāĻžāĻ¨ā§āĻĄā§‡āϞ āĻ¤ā§āϰ⧁āϟāĻŋ āĻĻ⧇āϖ⧁āύ.