Checking If user is logged in or not - ios

I'm new to iOS development and to the AWS Amplify framework. I am currently working my way through the Authentication documentation, but it isn't clear how to check the logged-in status of a given user. I only want to display the login form if the user not already logged in. How do I achieve this? There doesn't seem to be any information listed in the docs, and the only resource I found from google applied to a different platform (react).

You need to listen to Auth events and update the state for a flag Eg:isSignedIn which would be initially signed off.
final class UserData: ObservableObject {
#Published var isSignedIn : Bool = false
}
import UIKit
import Amplify
import AmplifyPlugins
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
public let userData = UserData()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
try Amplify.add(plugin: AWSCognitoAuthPlugin())
try Amplify.configure()
// load data when user is signedin
self.checkUserSignedIn()
// listen to auth events
_ = Amplify.Hub.listen(to: .auth) { (payload) in
switch payload.eventName {
case HubPayload.EventName.Auth.signedIn:
self.updateUI(forSignInStatus: true)
case HubPayload.EventName.Auth.signedOut:
self.updateUI(forSignInStatus: false)
case HubPayload.EventName.Auth.sessionExpired:
self.updateUI(forSignInStatus: false)
default:
break
}
}
} catch {
print("Failed to configure Amplify \(error)")
}
return true
}
func updateUI(forSignInStatus : Bool) {
DispatchQueue.main.async() {
self.userData.isSignedIn = forSignInStatus
}
}
// when user is signed in, fetch its details
func checkUserSignedIn() {
// every time auth status changes, let's check if user is signedIn or not
// updating userData will automatically update the UI
_ = Amplify.Auth.fetchAuthSession { (result) in
do {
let session = try result.get()
self.updateUI(forSignInStatus: session.isSignedIn)
} catch {
print("Fetch auth session failed with error - \(error)")
}
}
}
See the full code here.

Related

iOS applicationWillResignActive task not performed until app becomes active again

I'm trying to use applicationWillResignActive() in order to sync some data to my Firestore database before the application enters the background.
func applicationWillResignActive(_ application: UIApplication) {
self.uploadWantToPlay()
}
When I call my upload function from applicationWillResignActive() it runs but no data is added to Firestore before the next time the application becomes active.
When I for testing purposes instead run the same function from one of my ViewControllers the data is added instantly to Firestore.
I've also tried calling the function from applicationDidEnterBackground(), I've tried running it in it's own DispatchQueue. But it's had the same result.
How can I run this function as the user is about to leave the app and have it perform the database sync properly?
The functions handling the database sync;
func uploadWantToPlay() {
print ("Inside uploadWantToPlay")
if let wantToPlay = User.active.wantToPlayList {
if let listEntries = wantToPlay.list_entries {
let cleanedEntries = listEntries.compactMap({ (entry: ListEntry) -> ListEntry? in
if entry.game?.first_release_date != nil {
return entry
} else {
return nil
}
})
let gamesToUpload = cleanedEntries.filter {
$0.game!.first_release_date! > Int64(NSDate().timeIntervalSince1970 * 1000)
}
DatabaseConnection().writeWantToPlayToDatabase(user: User.active,wantToPlay: gamesToUpload)
}
}
}
func writeWantToPlayToDatabase(user: User, wantToPlay: [ListEntry]) {
firebaseSignIn()
let deviceId = ["\(user.deviceId)": "Device ID"]
for entry in wantToPlay {
let wantToPlayGameRef = fireStore.collection(WANTTOPLAY).document("\(entry.game!.id!)")
wantToPlayGameRef.updateData(deviceId) {(err) in
if err != nil {
wantToPlayGameRef.setData(deviceId) {(err) in
if let err = err {
Events().logException(withError: err, withMsg: "DatabaseConnection-writeWantToPlayToDatabase(user, [ListEntry]) Failed to write to database")
} else {
print("Document successfully written to WantToPlayGames")
}
}
} else {
print("Document successfully updated in WantToPlayGames")
}
}
}
}
According to the Apple documentation
Apps moving to the background are expected to put themselves into a
quiescent state as quickly as possible so that they can be suspended
by the system. If your app is in the middle of a task and needs a
little extra time to complete that task, it can call the
beginBackgroundTaskWithName:expirationHandler: or
beginBackgroundTaskWithExpirationHandler: method of the UIApplication
object to request some additional execution time. Calling either of
these methods delays the suspension of your app temporarily, giving it
a little extra time to finish its work. Upon completion of that work,
your app must call the endBackgroundTask: method to let the system
know that it is finished and can be suspended.
So, what you need to do here is to perform a finite length task while your app is being suspended. This will buy your app enough time to sync your records to the server.
An example snippet:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var backgroundTask: UIBackgroundTaskIdentifier!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
self.registerBackgroundTask()
// Do your background work here
print("Do your background work here")
// end the task when work is completed
self.endBackgroundTask()
}
func registerBackgroundTask() {
self.backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
self?.endBackgroundTask()
}
assert(self.backgroundTask != UIBackgroundTaskInvalid)
}
func endBackgroundTask() {
print("Background task ended.")
UIApplication.shared.endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}
}
For further information refer to this article.

Spotify SDK player not working: Error Domain=com.spotify.ios-sdk.playback Code=1 "The operation failed due to an unspecified issue."

I am currently developing an iOS app to login to my Spotify account and play songs in there.
This is my code:
import UIKit
import AVKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,
SPTAudioStreamingDelegate {
var window: UIWindow?
let kClientId = "hidden------my client ID"
let kRedirectUrl = URL(string: "spotify-study2-login://return-after-login")
var session: SPTSession?
var player: SPTAudioStreamingController?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// set up Spotofy
SPTAuth.defaultInstance().clientID = kClientId
SPTAuth.defaultInstance().redirectURL = kRedirectUrl
SPTAuth.defaultInstance().requestedScopes = [SPTAuthStreamingScope] as [AnyObject]
let loginUrl = SPTAuth.defaultInstance().spotifyAppAuthenticationURL()
application.open(loginUrl!)
return true
}
// handle auth
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
if SPTAuth.defaultInstance().canHandle(url) {
SPTAuth.defaultInstance().handleAuthCallback(withTriggeredAuthURL: url, callback: { error, session in
if error != nil {
print("*** Auth error: \(String(describing: error))")
}
// Call the -loginUsingSession: method to login SDK
self.loginUsingSession(session: session!)
})
return true
}
return false
}
func loginUsingSession(session: SPTSession) {
// Get the player Instance
player = SPTAudioStreamingController.sharedInstance()
if let player = player {
player.delegate = self
// start the player (will start a thread)
try! player.start(withClientId: kClientId)
// Login SDK before we can start playback
player.login(withAccessToken: session.accessToken)
let urlStr = "spotify:track:3yMPqvbPNaL5DUDOmwEr6l" // a song I choose. I already confirmed this song really exsits.
self.player?.playSpotifyURI(urlStr, startingWith: 0, startingWithPosition: 0, callback: { error in
if error != nil {
print("*** failed to play: \(String(describing: error))")
return
} else {
print("play")
}
})
}
}
// MARK: SPTAudioStreamingDelegate.
func audioStreamingDidLogin(audioStreaming: SPTAudioStreamingController!) {
let urlStr = "spotify:track:3yMPqvbPNaL5DUDOmwEr6l" // a song I choose. I already confirmed this song really exsits.
player!.playSpotifyURI(urlStr, startingWith: 0, startingWithPosition: 0, callback: { error in
if error != nil {
print("*** failed to play: \(String(describing: error))")
return
} else {
print("play")
}
})
}
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.
//log
print("func applicationWillResignActive has been called")
}
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.
//log
print("func applicationDidEnterBackground has been called")
}
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.
//log
print("func applicationWillEnterForeground has been called")
}
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.
//log
print("applicationDidBecomeActive")
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
//log
print("func applicationWillTerminate has been called")
}
}
When I run the debugger, I found an error message saying:
Error Domain=com.spotify.ios-sdk.playback Code=1 "The operation failed
due to an unspecified issue." UserInfo={NSLocalizedDescription=The
operation failed due to an unspecified issue.}
This error message came from the part below:
// MARK: SPTAudioStreamingDelegate.
func audioStreamingDidLogin(audioStreaming:
SPTAudioStreamingController!) {
let urlStr = "spotify:track:3yMPqvbPNaL5DUDOmwEr6l" // a song I choose. I already confirmed this song really exsits.
player!.playSpotifyURI(urlStr, startingWith: 0, startingWithPosition: 0, callback: { error in
if error != nil {
print("*** failed to play: \(String(describing: error))")
return
} else {
print("play")
}
})
}
In addition, I also found
2017-11-19 19:31:04.050872+0900 SpotifyStudy2[756:110616] Caching
allowed 1
from the part below:
// Login SDK before we can start playback
player.login(withAccessToken: session.accessToken)
Googling about this problem cost me lots of time but still I haven't found a nice answer to solve this.
If you have any idea what this error specifically means, your answer will help me so much...! Thank you in advance.
I was facing the same issue, and I have resolved using belove code
do {
try SPTAudioStreamingController.sharedInstance()?.start(withClientId: SPTAuth.defaultInstance().clientID, audioController: nil, allowCaching: true)
SPTAudioStreamingController.sharedInstance().delegate = self
SPTAudioStreamingController.sharedInstance().playbackDelegate = self
SPTAudioStreamingController.sharedInstance().diskCache = SPTDiskCache() /* capacity: 1024 * 1024 * 64 */
SPTAudioStreamingController.sharedInstance().login(withAccessToken: "Token here")
} catch _ {
print("catch")
}

Show Facebook Events in Swift 3

How can I store Facebook events in an array using Swift 3? I have the following code which I pretty much copied from The Swift Guy but it doesn't work for this code. The following is in my viewDidLoad() function:
let url = URL(string: "https://www.facebook.com/events/upcoming")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print("ERROR")
} else {
if let content = data {
do {
let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
print(myJson)
} catch {
print("error")
}
}
}
}
task.resume()
How can I get the information from the Facebook Events page? I should mention that I'm good at coding, but I'm a beginner when it comes to Swift so some explanation as to what each line does would be very helpful. Thanks!
The URL you're requesting returns an HTML page that you're trying to parse as if it was a JSON resource. You'll have to use the Facebook Graph API and/or the Facebook Swift SDK to get the information as JSON.
Try reading the Facebook developer documentation for more information:
https://developers.facebook.com/docs/swift
https://developers.facebook.com/docs/graph-api
Also, Swift Error objects contain information that can help you understand what went wrong. You can print them to the console. Try this:
if error != nil {
print(error)
} else {
// ...
The catch statement also sets its own error variable inside its block, so you can use:
} catch {
print(error)
}
Make sure you understand the steps involved in creating a Facebook app: registering the app with Facebook, downloading the SDK, adding the SDK to your project, configuring the SDK for your app, logging in to Facebook in your app and then calling the Facebook Graph API to get the information. These steps are all described in the Facebook documentation mentioned above. I'd start with the iOS SDK (Objective-C) instructions to setup your project and then change your app delegate and view controller to the following:
AppDelegate.swift:
import UIKit
import FacebookCore
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
SDKApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return SDKApplicationDelegate.shared.application(app, open: url, options: options)
}
}
ViewController.swift:
import UIKit
import FacebookCore
import FacebookLogin
class ViewController: UIViewController, LoginButtonDelegate {
override func viewDidLoad() {
super.viewDidLoad()
if let _ = AccessToken.current {
loadEvents()
}
let loginButton = LoginButton(readPermissions: [ .publicProfile, .userEvents ])
loginButton.center = view.center
loginButton.delegate = self
view.addSubview(loginButton)
}
func loginButtonDidCompleteLogin(_ loginButton: LoginButton, result: LoginResult) {
if let _ = AccessToken.current {
loadEvents()
}
}
func loginButtonDidLogOut(_ loginButton: LoginButton) {
// Logout handling code here
}
func loadEvents() {
let connection = GraphRequestConnection()
connection.add(GraphRequest(graphPath: "/me/events")) { httpResponse, result in
switch result {
case .success(let response):
print("Graph Request Succeeded: \(response)")
case .failed(let error):
print("Graph Request Failed: \(error)")
}
}
connection.start()
}
}
The response object will contain the Facebook Events information, already parsed.

Connecting iOS app to Ejabberd Server hosted on Amazon

I hosted Ejabberd chat server on Amazon and added two user there, when I tried to connect Ejabberd server through Adium, it asks for certificate then only it gets connected, now I'm developing chat application in Swift using Ejabberd server and XMPP, I configured all code , passed host name and port no: 5222, but its not connecting to server.
Should I need to write program to fetch server certificate and pass my computer certificate (.p12) file to server?
NOTE: I configured Ejabberd server in localhost and through iOS Swift Code, it's working perfectly when I send message from iOS app then it shows in Adium and when Adium user send message then I go to Ejabberd Web Admin Panel and can check offline Messages.
Here is the code in Swift for connecting Ejabberd hosted on Amazon:
//
// AppDelegate.swift
// Thanks to Process One for this.
import UIKit
import XMPPFramework
protocol ChatDelegate {
func buddyWentOnline(_ name: String)
func buddyWentOffline(_ name: String)
func didDisconnect()
}
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, XMPPRosterDelegate, XMPPStreamDelegate {
var window: UIWindow?
var delegate:ChatDelegate! = nil
let xmppStream = XMPPStream()
let xmppRosterStorage = XMPPRosterCoreDataStorage()
var xmppRoster: XMPPRoster
override init() {
xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage)
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
DDLog.add(DDTTYLogger.sharedInstance())
setupStream()
return true
}
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 throttle down OpenGL ES frame rates. Games should use this method to pause the game.
disconnect()
}
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.
connect()
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
//MARK: Private Methods
func setupStream() {//fileprivate
//xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage)
xmppRoster.activate(xmppStream)
xmppStream?.addDelegate(self, delegateQueue: DispatchQueue.main)
xmppRoster.addDelegate(self, delegateQueue: DispatchQueue.main)
}
func goOnline() { //fileprivate
let presence = XMPPPresence()
let domain = xmppStream?.myJID.domain
if domain == "gmail.com" || domain == "gtalk.com" || domain == "talk.google.com" {
let priority = DDXMLElement.element(withName: "priority", stringValue: "24") as! DDXMLElement
presence?.addChild(priority)
}
xmppStream?.send(presence)
}
func goOffline() { //fileprivate
let presence = XMPPPresence(type: "unavailable")
xmppStream?.send(presence)
}
func connect() -> Bool {
xmppStream.hostName = "amazon hosted ejabber ip address"
xmppStream.hostPort=5222
if !(xmppStream?.isConnected())! {
let jabberID = UserDefaults.standard.string(forKey: "userID")
let myPassword = UserDefaults.standard.string(forKey: "userPassword")
if !(xmppStream?.isDisconnected())! {
return true
}
if jabberID == nil && myPassword == nil {
return false
}
xmppStream?.myJID = XMPPJID.init(string: jabberID)
do {
try xmppStream?.connect(withTimeout: XMPPStreamTimeoutNone)
print("Connection success")
return true
} catch {
print("Something went wrong!")
return false
}
} else {
return true
}
}
func disconnect() {
goOffline()
xmppStream?.disconnect()
}
//MARK: XMPP Delegates
func xmppStreamDidConnect(_ sender: XMPPStream!) {
do {
try xmppStream?.authenticate(withPassword: UserDefaults.standard.string(forKey: "userPassword"))
} catch {
print("Could not authenticate")
}
}
func xmppStreamDidAuthenticate(_ sender: XMPPStream!) {
goOnline()
}
func xmppStream(_ sender: XMPPStream!, didReceive iq: XMPPIQ!) -> Bool {
print("Did receive IQ")
return false
}
func xmppStream(_ sender: XMPPStream!, didReceive message: XMPPMessage!) {
print("Did receive message \(message)")
}
func xmppStream(_ sender: XMPPStream!, didSend message: XMPPMessage!) {
print("Did send message \(message)")
}
func xmppStream(_ sender: XMPPStream!, didReceive presence: XMPPPresence!) {
let presenceType = presence.type()
let myUsername = sender.myJID.user
let presenceFromUser = presence.from().user
if presenceFromUser != myUsername {
print("Did receive presence from \(presenceFromUser)")
if presenceType == "available" {
delegate.buddyWentOnline("\(presenceFromUser)#gmail.com")
} else if presenceType == "unavailable" {
delegate.buddyWentOffline("\(presenceFromUser)#gmail.com")
}
}
}
func xmppRoster(_ sender: XMPPRoster!, didReceiveRosterItem item: DDXMLElement!) {
print("Did receive Roster item")
}
}
Finally i managed to solve this issue and i am really amaze to implement chat application using Ejabberd server hosted on Amazon.
Issue :
1. When i was running my application , it was not connecting ?
Answer : Certificate issue (Server - client side certificate handshake resolves issue)
2. Unable to fetch online buddy ?
Answer : i used Adium to make all user online and then run my application and it works like a charm.
Great learning for me for this application.
If any1 having any issue with chat ,feel free to comment i am looking forward to help. Thanks

Facebook SDK 4.0 stay logged in/Save FBSDKAccessToken in iOS (Swift 3)

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)
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
}
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
Contains instructions on receiving and sending data to and from Plist file types
How to Save and Retrieve Data from a 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)
I had to downgrade the FBSDKCoreKit and FBSDKLoginKit from 4.18.0 to 4.17.0 to make it work as intended.

Resources