Facebook Graph Request using Swift3 -

I am rewriting my graph requests with the latest Swift3. I am following the guide found here - https://developers.facebook.com/docs/swift/graph.

fileprivate struct UserProfileRequest: GraphRequestProtocol {
    struct Response: GraphResponseProtocol {
        init(rawResponse: Any?) {
            // Decode JSON into other properties

        }
    }

    let graphPath: String = "me"
    let parameters: [String: Any]? = ["fields": "email"]
    let accessToken: AccessToken? = AccessToken.current
    let httpMethod: GraphRequestHTTPMethod = .GET
    let apiVersion: GraphAPIVersion = .defaultVersion
}


fileprivate func returnUserData() {


    let connection = GraphRequestConnection()
    connection.add(UserProfileRequest()) {
        (response: HTTPURLResponse?, result: GraphRequestResult<UserProfileRequest.Response>) in
        // Process
    }
    connection.start()

However, I am getting this error in the connection.add method:

Type ViewController.UserProfileRequest.Response does not conform to protocol GraphRequestProtocol.

I can't seem to figure this out what to change here. It seems like the developer guide is not up to date on Swift3, but I am not sure that is the issue.

Is anyone able to see what is wrong here?

Thanks.

Answers


Browsing on the github issues, i found a solution. https://github.com/facebook/facebook-sdk-swift/issues/63

Facebook documentation for Swift 3.0 and SDK 0.2.0 is not yet updated.

This works for me:

    let params = ["fields" : "email, name"]
    let graphRequest = GraphRequest(graphPath: "me", parameters: params)
    graphRequest.start {
        (urlResponse, requestResult) in

        switch requestResult {
        case .failed(let error):
            print("error in graph request:", error)
            break
        case .success(let graphResponse):
            if let responseDictionary = graphResponse.dictionaryValue {
                print(responseDictionary)

                print(responseDictionary["name"])
                print(responseDictionary["email"])
            }
        }
    }

enjoy.


This code works for me, first I make a login with the correct permissions, then I build the GraphRequest for get the user information.

let login: FBSDKLoginManager = FBSDKLoginManager()
    // Make login and request permissions
    login.logIn(withReadPermissions: ["email", "public_profile"], from: self, handler: {(result, error) -> Void in

        if error != nil {
            // Handle Error
            NSLog("Process error")
        } else if (result?.isCancelled)! {
            // If process is cancel
            NSLog("Cancelled")
        }
        else {
            // Parameters for Graph Request without image
            let parameters = ["fields": "email, name"]
            // Parameters for Graph Request with image
            let parameters = ["fields": "email, name, picture.type(large)"]

            FBSDKGraphRequest(graphPath: "me", parameters: parameters).start {(connection, result, error) -> Void in
                if error != nil {
                    NSLog(error.debugDescription)
                    return
                }

                // Result
                print("Result: \(result)")

                // Handle vars
                if let result = result as? [String:String],
                    let email: String = result["email"], 
                    let fbId: String = result["id"], 
                    let name: String = result["name"] as? String, 
                    // Add this lines for get image
                    let picture: NSDictionary = result["picture"] as? NSDictionary,
                    let data: NSDictionary = picture["data"] as? NSDictionary,
                    let url: String = data["url"] as? String {

                    print("Email: \(email)")
                    print("fbID: \(fbId)")
                    print("Name: \(name)")
                    print("URL Picture: \(url)")
                }
            }
        }
    })

Here is my code like. I use Xcode 8, Swift 3 and it works fine for me.

let parameters = ["fields": "email, id, name"]
            let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: parameters)

            _ = graphRequest?.start { [weak self] connection, result, error in
                // If something went wrong, we're logged out
                if (error != nil) {
                    // Clear email, but ignore error for now
                    return
                }

                // Transform to dictionary first
                if let result = result as? [String: Any] {
                    // Got the email; send it to Lucid's server
                    guard let email = result["email"] as? String else {
                        // No email? Fail the login
                        return
                    }
                    guard let username = result["name"] as? String else {
                        // No username? Fail the login
                        return
                    }

                    guard let userId = result["id"] as? String else {
                        // No userId? Fail the login
                        return
                    }                       
                }
            } // End of graph request

Your UserProfileRequest should look like this:

fileprivate struct UserProfileRequest: GraphResponseProtocol {
  fileprivate let rawResponse: Any?

  public init(rawResponse: Any?) {
    self.rawResponse = rawResponse
  }

  public var dictionaryValue: [String : Any]? {
    return rawResponse as? [String : Any]
  }

  public var arrayValue: [Any]? {
    return rawResponse as? [Any]
  }

  public var stringValue: String? {
    return rawResponse as? String
  }
}

Need Your Help

How to combine Celery with asyncio?

python python-3.x asynchronous celery python-asyncio

How can I create a wrapper that makes celery tasks look like asyncio.Task? Or is there a better way to integrate Celery with asyncio?