0

I am new to Swift3 . Now, I'm try to do a .swift which can hold on some functions I needed.

For example : I want to get the userName as below , so I make a var to set value string in closure. Everything is okay and have value string before out of the closure , but value is disappear when it out of closure .. What happened !!?? Can someone tell me ? Plz .. Thank u so much T_T

Cold below here :

import UIKit
import FBSDKLoginKit
import FBSDKCoreKit

class CheckStatus: FBSDKLoginButton {

    var userID: String = ""
    var userName: String = ""
    var userLink: String = ""
    var userEmail: String = ""
    var userPictureUrl: String = ""

    func getUserDefault() {
        guard FBSDKAccessToken.current() != nil else {
            return
        }

        let userInfo: FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email, link, picture"])
        userInfo.start(completionHandler: { (_, result, error) -> Void in
            if error == nil {
                self.readPermissions = ["email", "public_profile"] // FBSDKLoginButton's permission
                guard let userDefault: [String:AnyObject] = result as? [String:AnyObject] else {
                    return
                }
                guard let userDefaultID: String = userDefault["id"] as? String else {
                    return
                }
                guard let userDefaultName: String = userDefault["name"] as? String else {
                    return
                }
                guard let userDefaultLink: String = userDefault["link"] as? String else {
                    return
                }
                guard let userDefaultEmail: String = userDefault["email"] as? String else {
                    return
                }
                guard let userDefaultPicture: [String:AnyObject] = userDefault["picture"] as? [String:AnyObject] else {
                    return
                }
                guard let userDefaultData: [String:AnyObject] = userDefaultPicture["data"] as? [String:AnyObject] else {
                    return
                }
                guard let userDefaultUrl: String = userDefaultData["url"] as? String else {
                    return
                }

                self.userID = userDefaultID
                self.userName = userDefaultName
                self.userLink = userDefaultLink
                self.userEmail = userDefaultEmail
                self.userPictureUrl = userDefaultUrl
                print("----- User data below -----\nID: \(userDefaultID)\nName: \(userDefaultName)\nLink: \(userDefaultLink)\nEmail: \(userDefaultEmail)\nPicture: \(userDefaultUrl)\n ----------------------")
                print("Have value : \(self.userName)") // This is work
            }
        })

        print("No value : \(self.userName)") // No value !!
    }
}
Nirav D
  • 71,513
  • 12
  • 161
  • 183
Kevin
  • 195
  • 1
  • 1
  • 11
  • `print("No value : \(self.userName)")` is executed before the completion handler of start, So you need to create completionHandler for getUserDefault method. – Nirav D Feb 22 '17 at 08:54
  • @NiravD Thanks , but I dont actually understand your mean . Should I add some function to handle this or something ? – Kevin Feb 22 '17 at 09:03
  • Where you want to access this detail? Means where you are calling this function. – Nirav D Feb 22 '17 at 09:23
  • @NiravD Actually , I want the function return a Dictionary in the end so that I can call this function ( CheckStatus().getUserDefault ) in my ViewController's viewDidLoad() to get the full information that I want . And that's why I try to print userName first to see there have value or not – Kevin Feb 22 '17 at 09:36
  • That means you want simply `userDefault` dictionary then create completionHandler for that. If you don't know how to create completionHandler then let me know. – Nirav D Feb 22 '17 at 09:38
  • @NiravD I don't know how it works .. can you teach me ? Please T_T – Kevin Feb 22 '17 at 09:57
  • You need to make completion handler like this answer of my http://stackoverflow.com/a/42241226/6433023. Here I'm creating completionHandler with argument bool instead of that you need to create it with dictionary `[String:Any]` So in your case it should like `func getUserDefault(completionHandler: @escaping (_ dictionary: [String:Any]) -> Void) {` inside the completion block of start call this completionHandler and you all set to go, If it still not work let me know. – Nirav D Feb 22 '17 at 09:58
  • @NiravD Thank u so much , I finished it :) – Kevin Feb 23 '17 at 02:40
  • Welcome mate :) Glad it works for you :) – Nirav D Feb 23 '17 at 04:18

0 Answers0