diff --git a/samples/swift/README.md b/samples/swift/README.md index 62e447d8d4d..c3b47a55613 100644 --- a/samples/swift/README.md +++ b/samples/swift/README.md @@ -24,3 +24,8 @@ This sample uses [email/password](https://firebase.google.com/docs/auth/ios/pass and [Facebook](https://firebase.google.com/docs/auth/ios/facebook-login) auth, so make sure those are enabled in Firebase console. +The auth example requires a little more setup (adding url schemes, etc) +since it depends on the various keys and tokens for the different auth +services your app will support. Take a look at the [Auth README](../../FirebaseUI/Auth/README.md) +for more information. + diff --git a/samples/swift/uidemo.xcodeproj/project.pbxproj b/samples/swift/uidemo.xcodeproj/project.pbxproj index e3980f13fc6..fc0819e6826 100644 --- a/samples/swift/uidemo.xcodeproj/project.pbxproj +++ b/samples/swift/uidemo.xcodeproj/project.pbxproj @@ -100,7 +100,7 @@ 8DABC98A1D3D82D600453807 /* MenuViewController.swift */, 8DABC9AA1D3D947300453807 /* SampleCell.swift */, 8DABC9A81D3D872C00453807 /* Sample.swift */, - 8D16073D1D492B200069E4F5 /* AuthViewController.swift */, + 8DD17C951D4BCC6500E850E4 /* AuthSample */, 8D643F0F1D4827F10081F979 /* ChatSample */, 8DABC98C1D3D82D600453807 /* Main.storyboard */, 8DABC98F1D3D82D600453807 /* Assets.xcassets */, @@ -119,6 +119,14 @@ path = uidemoTests; sourceTree = ""; }; + 8DD17C951D4BCC6500E850E4 /* AuthSample */ = { + isa = PBXGroup; + children = ( + 8D16073D1D492B200069E4F5 /* AuthViewController.swift */, + ); + name = AuthSample; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ diff --git a/samples/swift/uidemo/AppDelegate.swift b/samples/swift/uidemo/AppDelegate.swift index e665a0a21ab..622c92f3981 100644 --- a/samples/swift/uidemo/AppDelegate.swift +++ b/samples/swift/uidemo/AppDelegate.swift @@ -16,6 +16,7 @@ import UIKit import Firebase +import FirebaseAuthUI @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { @@ -32,5 +33,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate { FIRApp.configure() return true } + + func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool { + let sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String? + if FIRAuthUI.authUI()?.handleOpenURL(url, sourceApplication: sourceApplication) ?? false { + return true + } + // other URL handling goes here. + return false + } } diff --git a/samples/swift/uidemo/AuthViewController.swift b/samples/swift/uidemo/AuthViewController.swift index 6dcbb79cb71..026ca3dbdee 100644 --- a/samples/swift/uidemo/AuthViewController.swift +++ b/samples/swift/uidemo/AuthViewController.swift @@ -15,8 +15,112 @@ // import UIKit +import Firebase +import FirebaseAuthUI +import FirebaseGoogleAuthUI +import FirebaseFacebookAuthUI +let kFirebaseTermsOfService = NSURL(string: "https://firebase.google.com/terms/")! + +// Your Google app's client ID, which can be found in the GoogleService-Info.plist file +// and is stored in the `clientID` property of your FIRApp options. +// Firebase Google auth is built on top of Google sign-in, so you'll have to add a URL +// scheme to your project as outlined at the bottom of this reference: +// https://developers.google.com/identity/sign-in/ios/start-integrating +let kGoogleAppClientID = (FIRApp.defaultApp()?.options.clientID)! + +// Your Facebook App ID, which can be found on developers.facebook.com. +let kFacebookAppID = "your fb app ID here" + +/// A view controller displaying a basic sign-in flow using FIRAuthUI. class AuthViewController: UIViewController { + // Before running this sample, make sure you've correctly configured + // the appropriate authentication methods in Firebase console. For more + // info, see the Auth README at ../../FirebaseUI/Auth/README.md + // and https://firebase.google.com/docs/auth/ + + private var authStateDidChangeHandle: FIRAuthStateDidChangeListenerHandle? + + private(set) var auth: FIRAuth? = FIRAuth.auth() + private(set) var authUI: FIRAuthUI? = FIRAuthUI.authUI() + + @IBOutlet private var signOutButton: UIButton! + @IBOutlet private var startButton: UIButton! + + @IBOutlet private var signedInLabel: UILabel! + @IBOutlet private var nameLabel: UILabel! + @IBOutlet private var emailLabel: UILabel! + @IBOutlet private var uidLabel: UILabel! + + @IBOutlet var topConstraint: NSLayoutConstraint! + + override func viewWillAppear(animated: Bool) { + super.viewWillAppear(animated) + + // If you haven't set up your authentications correctly these buttons + // will still appear in the UI, but they'll crash the app when tapped. + let providers: [FIRAuthProviderUI] = [ + FIRGoogleAuthUI(clientID: kGoogleAppClientID)!, + FIRFacebookAuthUI(appID: kFacebookAppID)!, + ] + self.authUI?.signInProviders = providers + + // This is listed as `TOSURL` in the objc source, + // but it's `termsOfServiceURL` in the current pod version. + self.authUI?.termsOfServiceURL = kFirebaseTermsOfService + + self.authStateDidChangeHandle = + self.auth?.addAuthStateDidChangeListener(self.updateUI(auth:user:)) + } + + override func viewWillDisappear(animated: Bool) { + super.viewWillDisappear(animated) + if let handle = self.authStateDidChangeHandle { + self.auth?.removeAuthStateDidChangeListener(handle) + } + } + + @IBAction func startPressed(sender: AnyObject) { + let controller = self.authUI!.authViewController() + self.presentViewController(controller, animated: true, completion: nil) + } + + @IBAction func signOutPressed(sender: AnyObject) { + do { + try self.auth?.signOut() + } catch let error { + // Again, fatalError is not a graceful way to handle errors. + // This error is most likely a network error, so retrying here + // makes sense. + fatalError("Could not sign out: \(error)") + } + } + + // Boilerplate + func updateUI(auth auth: FIRAuth, user: FIRUser?) { + if let user = user { + self.signOutButton.enabled = true + self.startButton.enabled = false + + self.signedInLabel.text = "Signed in" + self.nameLabel.text = "Name: " + (user.displayName ?? "(null)") + self.emailLabel.text = "Email: " + (user.email ?? "(null)") + self.uidLabel.text = "UID: " + user.uid + } else { + self.signOutButton.enabled = false + self.startButton.enabled = true + + self.signedInLabel.text = "Not signed in" + self.nameLabel.text = "Name" + self.emailLabel.text = "Email" + self.uidLabel.text = "UID" + } + } + + override func viewWillLayoutSubviews() { + self.topConstraint.constant = self.topLayoutGuide.length + } + static func fromStoryboard(storyboard: UIStoryboard = AppDelegate.mainStoryboard) -> AuthViewController { return storyboard.instantiateViewControllerWithIdentifier("AuthViewController") as! AuthViewController } diff --git a/samples/swift/uidemo/Base.lproj/Main.storyboard b/samples/swift/uidemo/Base.lproj/Main.storyboard index 15671a660b9..59742f0628a 100644 --- a/samples/swift/uidemo/Base.lproj/Main.storyboard +++ b/samples/swift/uidemo/Base.lproj/Main.storyboard @@ -201,12 +201,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/samples/swift/uidemo/Info.plist b/samples/swift/uidemo/Info.plist index 40c6215d906..d320b6fb972 100644 --- a/samples/swift/uidemo/Info.plist +++ b/samples/swift/uidemo/Info.plist @@ -2,6 +2,13 @@ + LSApplicationQueriesSchemes + + fbapi + fb-messenger-api + fbauth2 + fbshareextension + CFBundleDevelopmentRegion en CFBundleExecutable @@ -18,6 +25,25 @@ 1.0 CFBundleSignature ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + REVERSED_CLIENT_ID + + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + FACEBOOK_APP_ID + + + CFBundleVersion 1 LSRequiresIPhoneOS