2

I tried to implement Facebook login with a custom login button, I've completed all the setup steps and when I tap the button, the web view present and ask me to provide the permission.

However, if I tap Done(on top left of web view controller), the completion block is called but when I tap Cancel or OK, the web view controller dismissed but the completion block is never get called? enter image description here Here's the code I used:

    let fbLoginManager = FBSDKLoginManager()
    fbLoginManager.loginBehavior = .Native
    fbLoginManager.logInWithReadPermissions(["email"], fromViewController: self) { (result, error) in
        // put a breakpoint here but it won't stop here if I tap OK
        if error != nil {
            print(error.localizedFailureReason)
        } else if result.isCancelled {
            // dismiss view
        } else {
            let token = result.token.tokenString
            // do something with the token
        }
    }

EDIT 1

Here's the open url method in AppDelegate:

func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
    return application(app, openURL: url, sourceApplication: nil, annotation: [:])
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    if url.scheme == Key.FACEBOOK_URL_SCHEME {
        let handled = FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
        return handled
    }
    let dynamicLink = FIRDynamicLinks.dynamicLinks()?.dynamicLinkFromCustomSchemeURL(url)
    if let dynamicLink = dynamicLink {
        if let url = dynamicLink.url {
            if let paths = url.pathComponents{
                if paths.count > 2 {
                    let slug = paths[2]
                    if let book = AppManager.instance.findBookBySlug(slug) {
                        // Open detail book
                        self.openDetailBook(book)
                    } else {
                        self.openDetailBookWithSlug(slug)
                    }
                }
            }
        }
    }
    if url.scheme == Key.DEEP_LINK_URL_SCHEME {
        if let paths = url.pathComponents, host = url.host {
            if host == "truyen" {
                if paths.count > 1 {
                    let slug = paths[1]
                    if let book = AppManager.instance.findBookBySlug(slug) {
                        // Open detail book
                        self.openDetailBook(book)
                    } else {
                        self.openDetailBookWithSlug(slug)
                    }
                }
            }
        }
    }
    return true
}
JozackOverFlow
  • 267
  • 4
  • 19

3 Answers3

2

If you ever face these situation, debug it yourself as Facebook SDK is open source. The window you are seeing is the SFSafariViewController. When you tap on any of those buttons, the call back will be handled by the SFSafariViewController. Look for the SFSafariViewController delegate methods in the Facebook sdk.

Put a breakpoint after you call the login code, and go step by step, it will take you to the class that uses SFSafariViewController.

In one of those delegate methods, you will find a call to the open url method. Implement the same open URL method in the app delegate method.

In your case the issue would be using wrong openURL method. The correct one shud be

func application(application: UIApplication,openURL url: NSURL, options: [String: AnyObject]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, 
     openURL: url, 
     sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String,
     annotation: options [UIApplicationOpenURLOptionsAnnotationKey])
}
Teja Nandamuri
  • 11,045
  • 6
  • 57
  • 109
2

Swift 3,Removing this method worked for me,

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    return application(app, open: url, sourceApplication: nil, annotation: [:])
}
Mohammad Zaid Pathan
  • 16,304
  • 7
  • 99
  • 130
0

Add Open url method in your AppDelegate.m file and put breakpoint in that method

- (BOOL)application:(UIApplication *)application openURL:( NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
  return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication  annotation:annotation];
}
Monika Patel
  • 2,287
  • 3
  • 20
  • 45
  • Thanks for your answer but I did add the method, I have multiple scheme so there's an if clause for Facebook scheme, but it did jump into it if url.scheme == Key.FACEBOOK_URL_SCHEME { let handled = FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation) return handled } – JozackOverFlow Jul 28 '16 at 11:06