2
votes

I'm trying to somehow save my Access Token/stay logged in upon app quit/crash. I am able to login to Facebook and retrieve data with the FBSDKGraphRequest but every time I quit the app, I am confronted with yet another login screen asking for my authentication (and saying I've already authorized this application) After doing numerous Google searches pertaining to the specific FBSDK version, I've found close to nothing that can help me with somehow keeping the current user logged into Facebook.

FBSession is deprecated (thus I cannot use it since it's not in the most current SDK anymore) and instead I have to do something with FBSDKAccessToken but I really have no clue as to what I have to do.

Here is the current code I'm using to check if currently logged in:

AppTabBarController (type UITabBarController)

override func viewDidAppear(_ animated: Bool) {
    if FBSDKAccessToken.current() == nil {
        //Go to Facebook Login Screen
        performSegue(withIdentifier: "toFBLogin", sender: self)
    }
}

AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    FBSDKApplicationDelegate.sharedInstance()
    return true
}
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.
    FBSDKAppEvents.activateApp();
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    return FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
...//Plus rest of protocol-required functions.

My problem is that there is no way to save the AccessToken that I know of. (Whenever the app launches, the FBSDKAccessToken.current() is nil)

3
Please post some code where you check about the token.Altimir Antonov

3 Answers

6
votes

With swift in AppDelegate, you can check if the user is logged with this:

if (FBSDKAccessToken.currentAccessToken() != nil) {

}

Just to know, if you use it in

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

}

It's better to call

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

before the if , otherwise FBSDKAccessToken will be nil and you will see the login screen again.

Example:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)

    if (FBSDKAccessToken.currentAccessToken() != nil) {
        //if you are logged
    } else {
    //if you are not logged
    }

    return 0
}
0
votes

So I found my own version of the answer. Basically what I did was that I created a plist file that would store the auth data and upon app launch, I would ask to see if the plist had been initialized beforehand and if it did, I would then ask for all the requirements such as appID and expirationDate etc.

I created a few new files as shown below; It's a fairly lengthy process but it works for now. I'm not sure how safe it is having these values available upon app launch but I don't think it's too bad.

Files:

Plist.swift

UserInfo.plist

UserInfo.plist

Profile.swift

  • Lots in file, only showing code for this problem
  • Used as an access from anywhere class (static)

    import FBSDKCoreKit
    
    class Profile {
    
    static private var name:String!
    static private var birthday:String?
    static private var email:String?
    static private var plist:Plist!
    
    //PlistAuth
    static private var refreshDate:Date!
    static private var expirationDate:Date!
    static private var appID:String!
    static private var declinedPermissions:[AnyObject]!
    static private var permissions:[AnyObject]!
    static private var tokenString:String!
    static private var userID:String!
    
    static func saveAuth(){
        Profile.refreshDate = FBSDKAccessToken.current().refreshDate
        Profile.expirationDate = FBSDKAccessToken.current().expirationDate
        Profile.appID = FBSDKAccessToken.current().appID
        Profile.declinedPermissions = Array(FBSDKAccessToken.current().declinedPermissions)
        Profile.permissions = Array(FBSDKAccessToken.current().permissions)
        Profile.tokenString = FBSDKAccessToken.current().tokenString
        Profile.tokenString = FBSDKAccessToken.current().userID
    
    
        Profile.plist = Plist(name: "UserInfo")
        if Profile.plist != nil{
            let dict = Profile.plist.getMutablePlistFile()!
            dict["refreshDate"] = Profile.refreshDate
            dict["expirationDate"] = Profile.expirationDate
            dict["appID"] = Profile.appID
            dict["declinedPermissions"] = Profile.declinedPermissions
            dict["permissions"] = Profile.permissions
            dict["tokenString"] = Profile.tokenString
            dict["userID"] = Profile.userID
            dict["isReady"] = true
    
            do {
                try Profile.plist.addValuesToPlistFile(dictionary: dict)
            }catch{
                print(error)
            }
            print(plist.getValuesInPlistFile())
        }else{
            print("rip plist")
        }
    }
    
    static func setAuth(){
        Profile.plist = Plist(name: "UserInfo")
        if Profile.plist != nil {
            let dict:NSDictionary = Profile.plist.getValuesInPlistFile()!
            if dict["isReady"] as! Bool{
                Profile.refreshDate = dict["refreshDate"] as! Date
                Profile.expirationDate = dict["expirationDate"] as! Date
                Profile.appID = dict["appID"] as! String
                Profile.declinedPermissions = dict["declinedPermissions"] as! [AnyObject]
                Profile.permissions = dict["permissions"] as! [AnyObject]
                Profile.tokenString = dict["tokenString"] as! String
                //Profile.userID = dict["userID"] as! String
    
                FBSDKAccessToken.setCurrent(FBSDKAccessToken.init(
                    tokenString: Profile.tokenString,
                    permissions: Profile.permissions,
                    declinedPermissions: Profile.declinedPermissions,
                    appID: Profile.appID,
                    userID: Profile.userID,
                    expirationDate: Profile.expirationDate,
                    refreshDate: Profile.refreshDate))
            }else{
                print("No user data found")
            }
        }
    
    }
    ...
    }
    

    Let me know what you guys think and if there's anything I should be aware about when it comes to storing these files safely (or even if they need to be stored safely)

0
votes

I had to downgrade the FBSDKCoreKit and FBSDKLoginKit from 4.18.0 to 4.17.0 to make it work as intended.