Facebook Authentication - Blank white screen during authentication - iOS 10 GM, Swift 3 - ios

Since Swift 3 - iOS 10, Xcode 8 GM SDK, I receive blank white screen at the end of the authentication with Facebook SDK.
It worked before. I have some warnings in the AppDelegate:
maybe it has something to do with it.
Edit:
I understood these functions are deprecated, and I tried changing these to the new functions, but the FBSDKApplicationDelegate still requests the older parameters...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: <#T##String!#>, annotation: <#T##Any!#>)
}
As you see, the problem is now with the second function.

Try this!
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(app,open: url,sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}

I understand these functions are deprecated in iOS 9, so that I used the others functions with their own API.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey
.sourceApplication] as! String!, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}

Related

Facebook Login - cannot convert value of type 'URL' to expected argument type 'URL!'

Pod
Using FBSDKCoreKit (4.23.0)
Using FBSDKLoginKit (4.23.0)
I simply cannot go pass through this function because i cannot cast URL to URL!. I did try to cast is with ! but it wont let me through. Did i miss something during the proses ?
Cheers
PS: i did create a github issues for this but it seems they did not check their github repo periodically.
In swift 3.0, the method signature for openURL is:
open url: URL
Check this post here.
In swift 3.0 use this method to open a Resource idetified by a url :
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
<#code#>
}
You are likely using the wrong method.
It's pretty standard stuff for using FBSDK. You should use
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {}
to return
application(app, open: url, sourceApplication: sourceApplication, annotation: nil)
Typically the function should look like below in your AppDelegate-
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let sourceApplication: String? = options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: sourceApplication, annotation: nil)
}
Also, assuming that you have this, in your didFinishLaunchingWithOptions
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
Also, you should be using the Facebook Swift pods-
pod 'FacebookCore'
pod 'FacebookLogin'
pod 'FacebookShare'
See this for more info.
I've encountered the same problem until I figured out that the URL class used in the application method
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
was pointing to an utility class defined by me. I had to rename my URL class to APP_URL and the problem disappeared.
Ruined 2 hours of my life.

Is it possible to support both Facebook and Google login in iOS using swift? [duplicate]

My app use google+ signin and in my appdelegate.swift i have:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
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,
openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return GIDSignIn.sharedInstance().handleURL(url,
sourceApplication: sourceApplication,
annotation: annotation)
}
Now i would like to insert also facebook login, but i have to add in appdelegate.swift this code:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(application: UIApplication,
openURL url: NSURL,
sourceApplication: String?,
annotation: AnyObject?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(
application,
openURL: url,
sourceApplication: sourceApplication,
annotation: annotation)
}
But this return error because the functions 'application' already exist, how can I perform both google+ and facebook same appdelegate.swift
Thank you.
Your application should handle facebook and google links, then return true if one or the other can handle the given link.
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
let googleDidHandle = GIDSignIn.sharedInstance().handleURL(url,
sourceApplication: sourceApplication,
annotation: annotation)
let facebookDidHandle = FBSDKApplicationDelegate.sharedInstance().application(
application,
openURL: url,
sourceApplication: sourceApplication,
annotation: annotation)
return googleDidHandle || facebookDidHandle
}
And in didFinishLaunching :
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
GIDSignIn.sharedInstance().delegate = self
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
In Swift 3, need to do in this way:
Override and implement the next method:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
let sourceApplication = options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String
let annotation = options[UIApplicationOpenURLOptionsKey.annotation]
let googleHandler = GIDSignIn.sharedInstance().handle(
url,
sourceApplication: sourceApplication,
annotation: annotation )
let facebookHandler = FBSDKApplicationDelegate.sharedInstance().application (
app,
open: url,
sourceApplication: sourceApplication,
annotation: annotation )
return googleHandler || facebookHandler
}
Then:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
PFFacebookUtils.initializeFacebook(applicationLaunchOptions: launchOptions)
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(String(describing: configureError))")
return true
}
in Swift 5 you can do it this way:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FBSDKCoreKit.ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
GIDSignIn.sharedInstance().clientID = "your_client_id"
GIDSignIn.sharedInstance().delegate = self
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let handledFB = FBSDKCoreKit.ApplicationDelegate.shared.application(app, open: url, options: options)
let handledGoogle = GIDSignIn.sharedInstance().handle(url)
return handledFB || handledGoogle
}

FB Login using Swift 3 not returning any values and not get back the user to the App after successful login

I'm using iOS 10 Swift 3 to integrate FB Login. I have followed all steps from Facebook documentation. Now the issue is, after successful login it doesn't returning any values and not get back the user to the app.
Note: The same works perfectly in Swift 2.
Hi I raised this issue to facebook developer support and the issue is that I have not implemented the correct delegate methods for iOS10. and you can find the correct delegate implementation here
import UIKit
import CoreData
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// Override point for customization after application launch.
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(
app,
open: url as URL!,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String,
annotation: options[UIApplicationOpenURLOptionsKey.annotation]
)
}
public func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(
application,
open: url as URL!,
sourceApplication: sourceApplication,
annotation: annotation)
}
}
Don't forget to set Keychain Sharing
project targets -> Capabilities -> Keychain Sharing -> Toggle Switch ON
you can follow this
http://ashishkakkad.com/2015/05/facebook-login-swift-language-ios/
for me the "FBSDKApplicationDelegate" doesn't work for the latest Facebook Swift SDK version v0.2.0
You can find my implementation for v0.2.2 here: https://gist.github.com/mbecker/bdbd28cd11394085c01cf442aaa42c72
//
// AppDelegate.swift
//
// Created by Mats Becker on 9/25/16.
// Copyright © 2016 safari.digital. All rights reserved.
//
import UIKit
import FacebookCore
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return SDKApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
// Call the 'activate' method to log an app event for use
// in analytics and advertising reporting.
AppEventsLogger.activate(application)
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return SDKApplicationDelegate.shared.application(
app,
open: url as URL!,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String,
annotation: options[UIApplicationOpenURLOptionsKey.annotation]
)
}
public func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return SDKApplicationDelegate.shared.application(
application,
open: url as URL!,
sourceApplication: sourceApplication,
annotation: annotation
)
}
}
Evn: iOS 10, XCode 8.3.2, Swift 3, facebook-sdk-swift-0.2.0
Tested and worked.
Since above answers are indicated as deprecated code, I have changed the syntax.
https://gist.github.com/jgchoi/097b59d85d6b378a81925be93a62fef9
import UIKit
import FacebookCore
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// Override point for customization after application launch.
return SDKApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
}
public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return SDKApplicationDelegate.shared.application(app, open: url, options: options)
}
public func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return SDKApplicationDelegate.shared.application(application, open: url)
}
}
}
I have experienced the same problem with Facebook and Twitter integration.I have solved it as follows.
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let appname:String = options.first?.value as! String
print(appname)
if appname == "com.facebook.Facebook" {
return FBSDKApplicationDelegate.sharedInstance().application(
app,
open: url as URL!,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String,
annotation: options[UIApplicationOpenURLOptionsKey.annotation]
)
}
return Twitter.sharedInstance().application(app, open: url, options: options)
}
public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return SDKApplicationDelegate.shared.application(app, open: url, options: options)
}
Add this in addition to what you have in AppDelegate
Somehow the below code didn't work for me
public func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return SDKApplicationDelegate.shared.application(application, open: url)
}
So had to change it to
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
let options = [UIApplication.OpenURLOptionsKey.sourceApplication: sourceApplication as Any,
UIApplication.OpenURLOptionsKey.annotation: annotation]
return SDKApplicationDelegate.shared.application(application, open: url, options: options)
}

Integrating Facebook SDK

I'm making an app and i want integrated Facebook, but this error can't continue, attached my problem.
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
// Override point for customization after application launch.
return true
}
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation:annotation) } THIS IS THE PROBLEM -- > ////Use of unresolved identifier "sourceApplication"///
}
}
Your delegate method does not match the one being used by Facebook. What about something like this?
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(app, openURL: url, sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as? String, annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
}

Integration new facebook SDK by swift

Today i tried to integrate facebook SDK to my Swift app but in the quick start on facebook guide page looks a bit different than my old code.
How can i convert OBJ-C code below to swift?
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
Thanks!
It's pretty much the same, except instead of using brackets, you use dots.
func applicationDidBecomeActive(application: UIApplication!) {
FBSDKAppEvents.activateApp()
}
func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String, annotation: AnyObject?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
Swift 3 with Swift FacebookSDK
Podfile
pod 'FacebookCore'
pod 'FacebookLogin'
info.plist
no changes from old sdk
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb$(YOUR_FB_APP_ID)</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
<key>FacebookAppID</key>
<string>$(YOUR_FB_APP_ID)</string>
<key>FacebookDisplayName</key>
<string>$(YOUR_APP_NAME)</string>
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SDKApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
...
}
func applicationDidBecomeActive(_ application: UIApplication) {
AppEventsLogger.activate(application)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let appId = SDKSettings.appId
if url.scheme != nil && url.scheme!.hasPrefix("fb\(appId)") && url.host == "authorize" { // facebook
return SDKApplicationDelegate.shared.application(app, open: url, options: options)
}
return false
}
...
LoginManager (custom login, see docs for default/button implementation)
contains custom code but you get the point
let facebookManager = LoginManager(loginBehavior: .systemAccount, defaultAudience: .everyone)
func loginWithFacebook() {
self.facebookManager.logIn(HAAccountManager.shared.facebookPermissions, viewController: self) { (result) in
switch result {
case .failed(let error):
self.showAlert(forError: error as NSError)
case .cancelled:
print("FB login cancelled")
case .success(let grantedPermissions, let deniedPermissions, let accessToken):
if grantedPermissions.contains(Permission(name: "email")) == true {
ApiClient.shared.facebookSignIn(authToken: accessToken.authenticationToken, completion: { (err, user) in
if err == nil {
// success
}
else {
self.showAlert(forError: err!)
}
})
}
else {
self.showAlert(forError: HAError(title: String(format: String.somethingError, String.signIn), message: grantedPermissions.contains(Permission(name: "email")) == true ? String.noAccountFound : String.missingEmailForSignUp))
}
}
}
}
Analytics
// custom ex
AppEventsLogger.log(AppEvent(name: "open_app", parameters: ["logged_in": NSNumber(value: HAAccountManager.shared.isUserLoggedIn())], valueToSum: nil))
// purchase ex
AppEventsLogger.log(
AppEvent.purchased(
amount: Double(revenue),
currency: currency,
extraParameters: [
AppEventParameterName.contentId : orderId,
AppEventParameterName.itemCount : order.orderItems.count.nsNumber()
])
)
This has been depricated in iOS 10.
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String, annotation: AnyObject?) -> Bool {
For Swift 3.0, you can use:
Swift 3.0
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let isHandled = FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[.sourceApplication] as! String!, annotation: options[.annotation])
return isHandled
}
I know this is a pretty old question here but it seams that it will never be outdated as Facebook hasn't updated their QuickStart guide for a long time.
So here is the solution for Swift 4.x.
In didFinishLaunching:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FBSDKApplicationDelegate.sharedInstance()?.application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
In open Url:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let handled = FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[.sourceApplication] as? String, annotation: options[.annotation])
return handled
}
Swift 5 with FBSDKCoreKit (5.3.0)
Import FBSDKCoreKit in appdelegate
In didFinishLaunching:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FBSDKCoreKit.ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
In open Url:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let handled = FBSDKCoreKit.ApplicationDelegate.shared.application(app, open: url, options: options)
return handled
}
In iOS 9 i use:
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool
{
FBSDKApplicationDelegate.sharedInstance().application(app, openURL: url, sourceApplication: options["UIApplicationOpenURLOptionsSourceApplicationKey"] as! String, annotation: options["UIApplicationOpenURLOptionsAnnotationKey"])
return true
}
On iOS 9 you should be using:
func application(application: UIApplication,openURL url: NSURL, options: [String: AnyObject]) -> Bool {
return ApplicationDelegate.shared.application(application, openURL: url, sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as? String, annotation: annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
}
I found the potential for the Application delegate to break in iOS 9 with the annotation: options[UIApplicationOpenURLOptionsAnnotationKey] as it will not accept nil values. You can set this to a blank string and the application should run fine with facebook after this.
Swift 2.2 docs:
You specify optional chaining by placing a question mark (?) after the optional value on which you wish to call a property, method or subscript if the optional is non-nil. This is very similar to placing an exclamation mark (!) after an optional value to force the unwrapping of its value. The main difference is that optional chaining fails gracefully when the optional is nil, whereas forced unwrapping triggers a runtime error when the optional is nil.
In swift 3.0.1
return GIDSignIn.sharedInstance().handle(url, sourceApplication:
options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation:
options[UIApplicationOpenURLOptionsKey.annotation])
Since I want to support iOS 8, I have modified the function application(_:open:options:) in Whitney Foster's answer to
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let appId = SDKSettings.appId
if url.scheme != nil && url.scheme!.hasPrefix("fb\(appId)") && url.host == "authorize" { // facebook
if #available(iOS 9.0, *) {
return SDKApplicationDelegate.shared.application(app, open: url, options: options)
}
}
return false
}
and implemented additional fallback function
// Fallback on earlier versions
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return SDKApplicationDelegate.shared.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
if let fbSDKAppId = FBSDKSettings.appID(),
url.scheme!.hasPrefix("fb\(fbSDKAppId)"),
url.host == "authorize" { // facebook
return FBSDKApplicationDelegate.sharedInstance().application(application,
open: url,
sourceApplication: sourceApplication,
annotation: annotation)
}
For swift 5 with latest FBSDK (FBSDKCoreKit 5.2.1)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let handled = ApplicationDelegate.shared.application(app, open: url, options: options)
return handled
}
Looks like Facebook gave up on Apple and has stopped updating their docs for years.
As of 2021, this is what works for me with FBSDKCoreKit 9.0.0 and Swift 5.
The pod to use is FBSDKCoreKit/Core (without Core, it will just be basics, and will be missing classes such as AppDelegate).
Import FBSDKCoreKit and setup with ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions).

Resources