Facebook SDK Setup - ios

I'm trying to add the Facebook SDK to my app, I've followed every step.
the only problem I have is that the the the code that I need to add to the AppDelegate is in Objective C and I'm using Swift. I don't know how to convert the Objective C code to swift, Can you help me?
This is the code:
- (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!

try facebook login code :
Appdelegate.swift
import UIKit
import FBSDKCoreKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func applicationWillResignActive(application: UIApplication) {
FBSDKAppEvents.activateApp()
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
}
ViewController.swift
import UIKit
import FBSDKLoginKit
class ViewController: UIViewController {
var dict : NSDictionary!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func btnFBLoginPressed(sender: AnyObject) {
var fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager .logInWithReadPermissions(["email"], handler: { (result, error) -> Void in
if (error == nil){
var fbloginresult : FBSDKLoginManagerLoginResult = result
if(fbloginresult.grantedPermissions.containsObject("email"))
{
self.getFBUserData()
fbLoginManager.logOut()
}
}
})
}
func getFBUserData(){
if((FBSDKAccessToken.currentAccessToken()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
self.dict = result as NSDictionary
println(result)
println(self.dict)
NSLog(self.dict.objectForKey("picture")?.objectForKey("data")?.objectForKey("url") as String)
}
})
}
}
}

Related

Duplicate method application:openURL [duplicate]

user in my app can login using 2 services : Facebook or Google
everything works fine, however, in the :
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation: (id)annotation {
...
}
i should decide to call the Facebook callback or Google callback
if the user has the apps, its easy, than i decide by the sourceApplication
but when not (no native Facebook account linked in, no FB app, no GooglePlus app), it links to the browser :( and i dont know if it is comming from Facebook or Google
is there a way how to decide what to call? like
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation: (id)annotation {
// how to decide?
if (facebook) {
return [FBSession.activeSession handleOpenURL:url];
} else if (google) {
return [GPPURLHandler handleURL:url sourceApplication:sourceApplication annotation:annotation];
}
}
We don't need to Explicitly check the URL, the code below does it:
- (BOOL)application: (UIApplication *)application openURL: (NSURL *)url sourceApplication: (NSString *)sourceApplication annotation: (id)annotation
{
if ([GPPURLHandler handleURL:url sourceApplication:sourceApplication annotation:annotation]) {
return YES;
}else if([FBAppCall handleOpenURL:url sourceApplication:sourceApplication]){
return YES;
}
return NO;
}
For Swift users, (The idea from user2144179)
Import below frameworks
import Firebase
import GoogleSignIn
import FacebookCore // (FBSDKCore's alternative for swift)
and in your delegate methods
// when your target is under iOS 9.0
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
let isFBOpenUrl = SDKApplicationDelegate.shared.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
let isGoogleOpenUrl = GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation)
if isFBOpenUrl { return true }
if isGoogleOpenUrl { return true }
return false
}
or you can use another 'open url:' method if your target is 9.0+. SDKs include a method for it also.
Firebase Reference : https://firebase.google.com/docs/auth/ios/google-signin
Facebook Reference : https://developers.facebook.com/docs/swift/reference/classes/applicationdelegate.html
You can Try the following :
if ([[url absoluteString] rangeOfString:#"<Your Google Bundle ID>"].location == NSNotFound)
{
// Call FBAppCall's handleOpenURL:sourceApplication to handle Facebook app responses
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
// You can add your app-specific url handling code here if needed
return wasHandled;
}
else
{
return [GPPURLHandler handleURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
return YES;
Call the above method in
(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
in your appDelegeate.m
Basically what this is going to do is examine the url prefix and then call the google+ method if url prefix is ur google+ bundle id , and if not , it'll call the fb method .
Hope this helps
The method "application:openURL:sourceApplication:annotation:" is deprecated from iOS9. so now you can use like.
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary *)options {
// For Google sign in SDK
if ([[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]) {
return YES;
// For Facebook SDK
}else if ( [[FBSDKApplicationDelegate sharedInstance] application:app
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]){
return YES;
//For Google plus SDK
}else if ([GPPURLHandler handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]){
return YES;
}
return NO;
}
The Swift version for iOS 9.0 and above of the accepted answer could be something like this:
import FacebookCore
[...]
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if (GIDSignIn.sharedInstance().handle(url)) {
return true
} else if (ApplicationDelegate.shared.application(app, open: url, options: options)) {
return true
}
return false
}
Try to handle the URL with each SDK, the first one that recognizes it ends execution returning true. If no SDK could handle the URL, return false.
I hope it helps someone,
Xavi
This might be the easiest solution,
import GoogleSignIn
import FBSDKCoreKit
func application(_ application: UIApplication,
open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
if GIDSignIn.sharedInstance().handle(url) {
return true
} else if ApplicationDelegate.shared.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation) {
return true
}
return false
}
#available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
if GIDSignIn.sharedInstance().handle(url) {
return true
} else if ApplicationDelegate.shared.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation]
) {
return true
}
return false
}
You can try this for a Swift 4.2 version:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
{
if (url.scheme?.hasPrefix("fb"))! {
return SDKApplicationDelegate.shared.application(app, open: url, options: options)
}
else
{
return GIDSignIn.sharedInstance().handle(url as URL?, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
}
You can just let either Google SDK or Facebook SDK attempt handling and if the SDK does not handle then allow the other SDK to try:
#available(iOS 9.0, *)
private func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any])
-> Bool {
let handled: Bool = SDKApplicationDelegate.shared.application(application, open: url, options: options)
if handled { return handled }
return GIDSignIn.sharedInstance().handle(url,
sourceApplication:options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
annotation: [:])
}
//deprecated method iOS 8 and older
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
let handled: Bool = SDKApplicationDelegate.shared.application(application,
open: url,
sourceApplication: sourceApplication,
annotation: annotation)
if handled { return handled }
return GIDSignIn.sharedInstance().handle(url,
sourceApplication: sourceApplication,
annotation: annotation)
}
You'll want to use [[UIApplication sharedApplication] canOpenURL:]
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
if( [GPPURLHandler handleURL:url
sourceApplication:sourceApplication
annotation:annotation])
{
return [GPPURLHandler handleURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
else if([[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation])
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
return NO;
}

Implementing Facebook Login IOS

I'm trying to follow the facebook developers website's instructions for implementing their login. Step 5 is telling me to add some code to my AppDelegate class, specifically AppDelegate.m (which I don't have, I only have AppDelegate.swift).
This is the code I'm supposed to add:
// AppDelegate.m
#import <FBSDKCoreKit/FBSDKCoreKit.h>
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
// Add any custom logic here.
return YES;
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
// Add any custom logic here.
return handled;
}
If I try putting it into the AppDelegate.swift file I get all sorts of errors, and I'm not finding any good documentation out there to do this properly. How do I solve this?
That code in objective-c , you should use swift
import FBSDKCoreKit
import FBSDKLoginKit
func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
func application(_ app: UIApplication,open url: URL,options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
{
if #available(iOS 9.0, *) {
let sourceApplication: String? = options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url,sourceApplication: sourceApplication, annotation: nil)
}
return true
}
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)
}

Segue won't trigger after logged into facebook using swift

So I have managed to set it up so the whole login system works. It closes out of the browser once logged in but does not advance to the next viewController.
This is my AppDelegate.swift:
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)
}
}
This is my ViewController.swift:
import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
class ViewController: UIViewController, FBSDKLoginButtonDelegate {
var fbLoginSuccess = false
override func viewDidLoad() {
if (FBSDKAccessToken.current() != nil && fbLoginSuccess == true)
{
print("Logged In...")
} else {
print("Not Logged In...")
}
let loginButton = FBSDKLoginButton()
loginButton.readPermissions = ["public_profile", "email"]
loginButton.center = self.view.center
loginButton.delegate = self
self.view.addSubview(loginButton)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Facebook Login.
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if error != nil
{
print(error)
} else if result.isCancelled {
// Handle
} else {
fbLoginSuccess = true
print("User logged in...")
self.performSegue(withIdentifier: "showNew", sender: self)
}
}
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
print("User logged out...")
}
}
I have a storyboard Identifier 'showNew' and I cannot figure out why it doesn't trigger.

Google sign in issue in Swift

i have installed pod 'Google/SignIn' framework in my project. I have integrated client ID and all the stuffs provided by google Docs, the problem is when i hit google sign in button its takes me to google SignIn page in there i entering my username and password after i hit submit button the page its not redirect to my App its still in google page and its not returning any values from Google page
here my sample code :
#IBAction func socialAction(sender: AnyObject) {
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().clientID = "************.apps.googleusercontent.com"
GIDSignIn.sharedInstance().signIn()
}
func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
withError error: NSError!) {
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 name = user.profile.name
let email = user.profile.email
print("gmail==>\(email)")
// ...
} else {
print("\(error.localizedDescription)")
}
}
in AppDelegate:
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
if #available(iOS 9.0, *) {
var options: [String: AnyObject] = [UIApplicationOpenURLOptionsSourceApplicationKey: sourceApplication!,
UIApplicationOpenURLOptionsAnnotationKey: annotation]
} else {
// Fallback on earlier versions
}
return GIDSignIn.sharedInstance().handleURL(url,
sourceApplication: sourceApplication,
annotation: annotation)
}
r u handling url in app delegate? and try this if you are not handling.
func application(application: UIApplication,
openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return GIDSignIn.sharedInstance().handleURL(url, sourceApplication: sourceApplication!, annotation: annotation) || FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
Add the URL scheme. For more details
https://developers.google.com/+/mobile/ios/getting-started#step_3_add_a_url_type
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
if([[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation])
{
return YES;
}
else if ([[GIDSignIn sharedInstance] handleURL:url sourceApplication:sourceApplication annotation:annotation])
{
return YES;
}
return NO;
}
this code is perfectly working in objective c.

FBSDKGraphRequest does not redirect to app after login

I am using FBSDKGraphRequest to implement Facebook login in my iOS app.
But after the login is done and the user confirms, I am not redirected to my app.
Here is my code:
FBSDKGraphRequest(graphPath: "me", parameters: nil).startWithCompletionHandler({
(connection, result, error: NSError!) -> Void in
if error == nil {
println("\(result)")
} else {
println("\(error)")
self.performSegueWithIdentifier("home", sender: self)
}
})
In your appdelegate :
import UIKit
import FBSDKCoreKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func applicationWillResignActive(application: UIApplication) {
FBSDKAppEvents.activateApp()
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
}
In your view controller :
import UIKit
import FBSDKLoginKit
class ViewController: UIViewController {
var dict : NSDictionary!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func btnFBLoginPressed(sender: AnyObject) {
var fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager .logInWithReadPermissions(["email"], handler: { (result, error) -> Void in
if (error == nil){
var fbloginresult : FBSDKLoginManagerLoginResult = result
if(fbloginresult.grantedPermissions.containsObject("email"))
{
self.getFBUserData()
fbLoginManager.logOut()
}
}
})
}
func getFBUserData(){
if((FBSDKAccessToken.currentAccessToken()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
self.dict = result as NSDictionary
println(result)
println(self.dict)
NSLog(self.dict.objectForKey("picture")?.objectForKey("data")?.objectForKey("url") as String)
}
})
}
}
}
Add properties in your plist.info file.
Add URL Types, FacebookAppID, and FacebookDisplayName Properties
For more you can go through the steps of https://developers.facebook.com/docs/ios/getting-started
You have to add handle URL code in your app delegate like this-
- (BOOL)application: (UIApplication *)application
openURL: (NSURL *)url
sourceApplication: (NSString *)sourceApplication
annotation: (id)annotation
{
if ([[url scheme] isEqualToString:FACEBOOK_SCHEME])
return [FBSession.activeSession handleOpenURL:url];
return NO;
}
And you have to add URL schemes in target settings->Info->Url Types

Resources