Manfredi6 Manfredi6 - 1 month ago 24
iOS Question

Implementing both Facebook and Google signIn API in swift 3.0

I have been struggling for a whole night and half a day before giving up and asking here for help. I've read several threads here on stackoverflow but any solution seems to work but this even though the app crash on startup

2016-10-26 16:03:58.793 MotivaMe[3997:404331] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MotivaMe.ViewController 0x7ff1a0407700> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key loginButtonFB.'


loginButtonFB was the old name I gave to button which is now labelled as doLoginFB and even though I cleaned the source, this error still appears and I don't why since there's not any name called liked that in the whole source.

This is the first time I try to code for iOS so I'm still not that confident with CocoaTouch that I'm still studying right now.
Any help is appreciated thanks (an explanation over the fix would really be appreciated since I can't get what's wrong, thanks to everyone)

Here is the AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{

FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)

var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")

GIDSignIn.sharedInstance().delegate = self

return true

}

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: AnyObject) -> Bool
{

let googleDidHandle = GIDSignIn.sharedInstance().handle(
url,
sourceApplication: sourceApplication,
annotation: annotation)

let facebookDidHandle = FBSDKApplicationDelegate.sharedInstance().application(
application,
open: url,
sourceApplication: sourceApplication,
annotation: annotation)

return googleDidHandle || facebookDidHandle
}



// The sign-in flow has finished and was successful if |error| is |nil|.
func sign(_ doLoginGoogle: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!)
{
if (error == nil)
{
// Perform any operations on signed in user here.
let userId = user.userID // For client-side use only!
let idToken = user.authentication.idToken // Safe to send to the server
let fullName = user.profile.name
let givenName = user.profile.givenName
let familyName = user.profile.familyName
let email = user.profile.email
// ...
print(userId,idToken,fullName,givenName,familyName,email)
}
else
{
print("\(error.localizedDescription)")
}
}


And here is the ViewController.swift

override func viewDidLoad() {
super.viewDidLoad()


GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().signInSilently()
}

@IBOutlet weak var doLoginFacebook: FBSDKLoginButton!
@IBOutlet weak var doLoginGoogle: GIDSignInButton!

func loginButtonDidLogOut(_ doLoginFacebook: FBSDKLoginButton!)
{
print("Did log out of facebook")
}

func loginButton(_ doLoginFacebook: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!)
{
if error != nil
{
print(error)
return
}
else
{
if(FBSDKAccessToken.current() != nil) //useless check but want to get confident with the api
{
//TODO implement switching pages on login
print("Sucessfully logged into facebook!")
}
}
}

Answer

I strongly suspect, that one of your outlet connection got stuck in your Stroyboard or Nib. This can happen from time to time, so you need to make sure that if you update/delete an outlet connection, you delete from the Interface builder too.

To fix this, go to your interface editor, and select your viewController. Than go here on the panel of the right hand side.

enter image description here

There you should be able to still see the loginButtonFB connected, with a little explanation mark next to it. Delete this connection, it should solve your problem.