I'm trying to use the new FacebookSdk for Swift3, but I can't figure out how to accomplish a simple Graph request. I definitely have it all wrong. this is what I have below. has anyone figured it out?
import FacebookCore
import FacebookLogin
import FacebookShare
let parameters = ["fields": "id, name, gender, picture.width(300).height(300).type(large).redirect(false)"]
let nextrequest: GraphRequest = GraphRequest(graphPath: "me", parameters: parameters, accessToken: AccessToken.current, httpMethod: GraphRequestHTTPMethod(rawValue: "GET")!)
nextrequest.start({ (response: HTTPURLResponse?, result: GraphRequestResult<GraphRequest>) in
if error != nil {
}
if let name = result["name"] as? String, let id = result["id"] as? String, let gender = result["gender"] as? String {
print(name)
print(id)
print(gender)
}
else {}
})
If you still got the problem, try this
let loginManager = LoginManager()
loginManager.logIn([ .publicProfile, .email, .userFriends ], viewController: self) { loginResult in
switch loginResult {
case .failed(let error):
print(error)
case .cancelled:
print("User cancelled login.")
case .success(let grantedPermissions, let declinedPermissions, let accessToken):
print("Logged in!")
let req = GraphRequest(graphPath: "me", parameters: ["fields":"email,first_name,last_name,gender,picture"], accessToken: accessToken, httpMethod: GraphRequestHTTPMethod(rawValue: "GET")!)
req.start({ (connection, result) in
switch result {
case .failed(let error):
print(error)
case .success(let graphResponse):
if let responseDictionary = graphResponse.dictionaryValue {
print(responseDictionary)
let firstNameFB = responseDictionary["first_name"] as! String
let lastNameFB = responseDictionary["last_name"] as! String
let socialIdFB = responseDictionary["id"] as! String
let genderFB = responseDictionary["gender"] as! String
let pictureUrlFB = responseDictionary["picture"] as! [String:Any]
let photoData = pictureUrlFB["data"] as! [String:Any]
let photoUrl = photoData["url"] as! String
print(firstNameFB, lastNameFB, socialIdFB, genderFB, photoUrl)
}
}
})
}
}
https://github.com/facebook/facebook-sdk-swift/issues/65
let parameters = ["fields":"name,gender,birthday,first_name,last_name,email"]
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)
{
print("graphrequest error :\(error?.localizedDescription)")
return
}
// Transform to dictionary first
if let result = result as? [String: Any]
{
guard let firstname = result["first_name"] as? String else {
return
}
guard let lastname = result["last_name"] as? String else {
return
}
guard let gender = result["gender"] as? String else {
return
}
guard let email = result["email"] as? String else {
return
}
guard let birthday = result["birthday"] as? String else {
return
}
(...)
}
} // End of graph request
Update for > Swift 4:
Facebook SDK Version: 4.33.0
#IBAction func btnLoginWithFacebook(_ sender: Any) {
let loginManager = LoginManager()
loginManager.logIn(readPermissions: [.publicProfile, .email, .userBirthday, .userGender, .userLocation], viewController: self, completion: { loginResult in
switch loginResult {
case .failed(let error):
print(error)
case .cancelled:
print("User cancelled login.")
case .success(let grantedPermissions, let declinedPermissions, let accessToken):
self.getFbId()
print("Logged in! \(grantedPermissions) \(declinedPermissions) \(accessToken)")
}
})
}
func getFbId(){
if(AccessToken.current != nil){
let req = GraphRequest(graphPath: "me", parameters: ["fields": "email,first_name,last_name,gender,picture"], accessToken: AccessToken.current, httpMethod: GraphRequestHTTPMethod(rawValue: "GET")!)
req.start({ (connection, result) in
switch result {
case .failed(let error):
print(error)
case .success(let graphResponse):
if let responseDictionary = graphResponse.dictionaryValue {
print(responseDictionary)
let firstNameFB = responseDictionary["first_name"] as? String
let lastNameFB = responseDictionary["last_name"] as? String
let socialIdFB = responseDictionary["id"] as? String
let genderFB = responseDictionary["gender"] as? String
let pictureUrlFB = responseDictionary["picture"] as? [String:Any]
let photoData = pictureUrlFB!["data"] as? [String:Any]
let photoUrl = photoData!["url"] as? String
print(firstNameFB, lastNameFB, socialIdFB, genderFB, photoUrl)
}
}
})
}
}
Thanks!!!
Related
I am trying to upload image in base64string format. Here i am uploading images with some parameters using alamofire and swift. But my image is not uploading to the server. Please check my code and let me know where i am doing wrong. My code is:
func postRegistrationPlayerProfile(urlExtension: String, callback: #escaping(Bool,String?) -> Void,parameters:[String:Any]) -> Void {
let fullURL = URL(string: urlExtension)!
let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = TimeInterval(Common.sharedInstance().REQUEST_TIME_OUT)
manager.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
}, usingThreshold: UInt64.init(), to: fullURL, method: .post) { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { (response : DataResponse<Any>) in
let responseDataString = Common.sharedInstance().getJSONStringFromData(data: response.data! as NSData)
print(responseDataString)
if let result = response.result.value {
let dictionary = result as! NSDictionary
let status = dictionary["status"] as! String
let message = dictionary["message"] as? String
if status == "success"{
callback(true,message)
return
}
else{
callback(false,message)
return
}
}
else{
callback(false,Common.sharedInstance().FAILED_BANNERIMG_UPLOAD)
return
}
}
case .failure(let encodingError):
print("encodingError: \(encodingError)")
callback(false,Common.sharedInstance().FAILED_BANNERIMG_UPLOAD)
}
}
}
my parameters are:
paramters.updateValue(phone!, forKey: "phone")
paramters.updateValue(state!, forKey: "state")
paramters.updateValue(city!, forKey: "city")
paramters.updateValue(zip!, forKey: "postcode")
paramters.updateValue(travel, forKey: "travel_distance")
paramters.updateValue(base64ImageString!, forKey: "profile_image")
paramters.updateValue(country!, forKey: "country")
I am converting my image to base64 string like:
if let selectedImage = chooseProfileImage.image{
if let data = selectedImage.jpegData(compressionQuality: 1){
base64ImageString = data.base64EncodedString(options: .lineLength64Characters)
}
}
Adding
url('data:image/jpeg;base64,)
to my Base64 converted string worked for me:
if let selectedImage = chooseProfileImage.image{
if let data = selectedImage.jpegData(compressionQuality: 1){
let imageString = selectedImage.jpegData(compressionQuality: 1.0)?.base64EncodedString() ?? ""
base64ImageString = "url('data:image/jpeg;base64,\(imageString)')"
profileData = data
}
}
Why can't I get user mail id for Facebook? I have attached my code below. I have doubt in login and registration using API
func getFacebookUserInfo() {
if(FBSDKAccessToken.current() != nil)
{
//print permissions, such as public_profile
print(FBSDKAccessToken.current().permissions)
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields" : "id, first_name, last_name, email"])
let connection = FBSDKGraphRequestConnection()
connection.add(graphRequest, completionHandler: { (connection, result, error) -> Void in
let data = result as! [String : AnyObject]
self.firstnameLabel.text = data["first_name"] as? String
self.lastnameLabel.text = data["last_name"] as? String
guard let result = result as? NSDictionary else{ return }
let email = result["email"] as? String
self.googleemail = email!
let FBid = data["id"] as? String
let url = NSURL(string: "https://graph.facebook.com/\(FBid)/picture?type=large&return_ssl_resources=1")
self.imageView.image = UIImage(data: NSData(contentsOf: url! as URL)! as Data)
self.validateUserData()
})
connection.start()
}
}
facebook button click
#IBAction func btnFacebookClick(_ sender: Any)
{
// GeneralClass.startProgress()
loginManager.logIn(readPermissions: [ ReadPermission.publicProfile,ReadPermission.email], viewController: self) { (loginResult) in
switch loginResult {
case .failed(let error):
self.loginManager.logOut()
print(error)
case .cancelled:
self.loginManager.logOut()
print("User cancelled login.")
case .success(let grantedPermissions, let declinedPermissions, let accessToken):
print(grantedPermissions)
print(declinedPermissions)
print("Logged in!")
self.getFBUserData(accessToken: accessToken)
}
}
}
get data
func getFBUserData(accessToken: AccessToken)
{
let request = GraphRequest(graphPath: "me",
parameters: ["fields" : "first_name,middle_name,last_name,name,link,email,id,picture" as AnyObject],
accessToken:accessToken,
httpMethod: .GET)
request.start { (httpResponse, result) in
switch result {
case .success(let response):
let responseDictionary = response.dictionaryValue
print("USER DATA:---\(responseDictionary! as NSDictionary))")
let dicData = responseDictionary! as NSDictionary
if ((dicData["email"]) != nil) {
let email = dicData["email"] as! String
let user_firstName = dicData["first_name"] as! String
let imageUrl = (((dicData["picture"] as! NSDictionary)[KEY_DATA] as! NSDictionary)["url"] as! String)
}
case .failed(let error):
self.loginManager.logOut()
print(error)
}
}
}
Seems like the email value is nil. Set nil checking before assigning the value.
if let email = result["email"] as? String {
self.googleemail = email!
}
Hope this will help.
I have taken over a Swift project and need to add Facebook login functionality. I am getting it to mostly work but am having a problem with this sample code here (https://developers.facebook.com/docs/swift/graph):
import FacebookCore
struct MyProfileRequest: GraphRequestProtocol {
struct Response: GraphResponseProtocol {
init(rawResponse: Any?) {
// Decode JSON from rawResponse into other properties here.
}
}
var graphPath = "/me"
var parameters: [String : Any]? = ["fields": "id, name"]
var accessToken = AccessToken.current
var httpMethod: GraphRequestHTTPMethod = .GET
var apiVersion: GraphAPIVersion = .defaultVersion
}
let connection = GraphRequestConnection()
connection.add(MyProfileRequest()) { response, result in
switch result {
case .success(let response):
print("Custom Graph Request Succeeded: \(response)")
print("My facebook id is \(response.dictionaryValue?["id"])")
print("My name is \(response.dictionaryValue?["name"])")
case .failed(let error):
print("Custom Graph Request Failed: \(error)")
}
}
connection.start()
I'm getting an error on compiling the for the line with the dictionaryValue optional saying /Users/jt/a-dev/tabfb/tabfb/LoginViewController.swift:72:31: Value of type 'MyProfileRequest.Response' has no member 'dictionaryValue' . How would I access the user name or id using this?
I faced this problem today as well. I got the user id and name inside MyProfileRequest
struct Response: GraphResponseProtocol {
init(rawResponse: Any?) {
// Decode JSON from rawResponse into other properties here.
guard let response = rawResponse as? Dictionary<String, Any> else {
return
}
if let name = response["name"],
let id = response["id"] {
print(name)
print(id)
}
}
}
EDIT: I redesigned my code like this to use the values in .success(let response) case
struct Response: GraphResponseProtocol {
var name: String?
var id: String?
var gender: String?
var email: String?
var profilePictureUrl: String?
init(rawResponse: Any?) {
// Decode JSON from rawResponse into other properties here.
guard let response = rawResponse as? Dictionary<String, Any> else {
return
}
if let name = response["name"] as? String {
self.name = name
}
if let id = response["id"] as? String {
self.id = id
}
if let gender = response["gender"] as? String {
self.gender = gender
}
if let email = response["email"] as? String {
self.email = email
}
if let picture = response["picture"] as? Dictionary<String, Any> {
if let data = picture["data"] as? Dictionary<String, Any> {
if let url = data["url"] as? String {
self.profilePictureUrl = url
}
}
}
}
}
And in the success case you can get the values like this:
let connection = GraphRequestConnection()
connection.add(MyProfileRequest()) { response, result in
switch result {
case .success(let response):
print("My facebook id is \(response.id!)") //Make sure to safely unwrap these :)
print("My name is \(response.name!)")
case .failed(let error):
print("Custom Graph Request Failed: \(error)")
}
}
connection.start()
import FBSDKLoginKit //FBSDKLoginKit installs automatically when you install FacebookCore through CocoaPods
///Inside your view controller
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
/// DEFAULT
//fired when fb logged in through fb's default login btn
if error != nil {
print(error)
return
}
showDetails()
}
fileprivate func showDetails(){
FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, first_name, last_name, email, gender"]).start { (connection, result, err) in
////use link for more fields:::https://developers.facebook.com/docs/graph-api/reference/user
if err != nil {
print("Failed to start graph request:", err ?? "")
return
}
let dict: NSMutableDictionary = result as! NSMutableDictionary
print("The result dict of fb profile::: \(dict)")
let email = dict["email"] as! String!
print("The result dict[email] of fb profile::: \(email)")
let userID = dict["id"] as! String
print("The result dict[id] of fb profile::: \(userID)")
// self.profileImage.image = UIImage(named: "profile")
let facebookProfileUrl = "http://graph.facebook.com/\(userID)/picture?type=large"
}
}
//make sure you add read permissions for email and public profile
override func viewDidLoad(){
super.viewDidLoad()
loginButtonFromFB.delegate = self //inherit FBSDKLoginButtonDelegate to your class
loginButtonFromFB.readPermissions = ["email", "public_profile"]
}
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.
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
}
}
I am new in iOS . i am trying to convert image or image url into png,or jpg format and failed .plz help me in this matter
#IBAction func FBSignInAct(sender: AnyObject) {
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager .logInWithReadPermissions(["email"], fromViewController: self, handler: { (result, error) -> Void in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result
if result.isCancelled {
return
}
if(fbloginresult.grantedPermissions.contains("email"))
{
self.getFBUserData()
}
}
})
}
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){
print(result)
let url = NSURL(string: result["picture"]!!["data"]!!["url"]!! as! String)
let email:String = result["email"] as! String
let id:String = result["id"] as! String
let name:String = result["name"] as! String
self.signUpFBControl(email , fbID: id , name: name , profile_PicUrl: url!)
}
})
}
}
func signUpFBControl(email:String,fbID:String,name:String,profile_PicUrl:NSURL)
{
let data = NSData(contentsOfURL: profile_PicUrl)
let profilePic : UIImage = UIImage(data: data!)!
let image:NSData = UIImageJPEGRepresentation(profilePic,1)!
let strBase64:String = image.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
print(strBase64)
let dataDecoded:NSData = NSData(base64EncodedString: strBase64, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!
print( dataDecoded)
Alamofire.request(.POST, "\(SERVERURL)fb_login", parameters: ["email": email,"fbid": fbID,"name": name ,"profile_pic": image,"user_type":"business" ]).responseJSON { response in
let json = JSON(data: response.data!)
if json["msg"].string == "User Details" {
let data = json["user_details"][0]
print(data)
LoginValue.sharedInstance.setUserLoginInfo(data)
self.reachNextViewController()
} else {
self.alertView("Sign Up Failed", message: json["error_description"].string!, button: "Close", destructive: false,secondButton: "")
}
print(json["error_description"])
}
}
error says
The profile pic must be a file of type: jpeg, jpg, png.