how to access all images from facebook in swift 5? - ios

I am trying to access all the images form facebook that user uploaded
I try it with user_photos
https://developers.facebook.com/docs/facebook-login/permissions/#reference-user_photos
I also try graph API explore from this
iOS :How to get Facebook Album Photo's Picker
my code
for Login
func btnFbClicked()
{
fbLoginManager.logOut()
fbLoginManager.loginBehavior = .web
fbLoginManager.logIn(withReadPermissions: ["public_profile", "email", "user_friends","user_photos"], from: self) { (result, error) in
if error != nil
{
print("error occured with login \(String(describing: error?.localizedDescription))")
}
else if (result?.isCancelled)!
{
print("login canceled")
}
else
{
if FBSDKAccessToken.current() != nil
{
FBSDKGraphRequest.init(graphPath: "me", parameters: ["fields":"id, name, first_name, last_name, picture.type(normal), email,gender"]).start(completionHandler: { (connection, userResult, error) in
if error != nil {
print("error occured \(String(describing: error?.localizedDescription))")
}
else if userResult != nil {
print("Login with FB is success")
print(userResult as! [String:Any])
self.fbData = (userResult as? NSDictionary)!
let mutableFBDict = NSMutableDictionary(dictionary: self.fbData)
print(mutableFBDict)
if((mutableFBDict["email"] as? String) ?? "") == ""{
// self.showAlertNoHide(title: "", message: "If permission is granted then please set any email as a primary email in facebook general settings, then only facebook will return email to third party application. Sorry for the inconvenience.")
return
}
var gender = Int64()
if(mutableFBDict["gender"] as? String == "male")
{
gender = Int64(1)
}
else if(mutableFBDict["gender"] as? String == "female")
{
gender = Int64(2)
}
else
{
gender = Int64(0)
}
self.fetchListOfUserPhotos()
}
for fetching Photos
func fetchListOfUserPhotos()
{
guard let id = self.fbData["id"] as? String else
{
return
}
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: id + "/photos" , parameters: ["fields":"user_photos"], httpMethod: "GET")
//FBSDKGraphRequest(graphPath: id + "/photos" , parameters: nil, httpMethod: "GET")
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
print("Error: \(error)")
}
else
{
print("fetched user: \(result)")
let fbResult:[String:AnyObject] = result as! [String : AnyObject]
self.userPhotos = fbResult["data"] as! NSArray?
self.myCollectionView.reloadData()
}
})
}
Respons I get
Optional({
data = (
);
})
so my question is can access images that user uploaded on facebook or facebook change policies?

"fields":"user_photos"
user_photos is a permission, not a field for API requests. About the existing fields for photos, check out the API reference: https://developers.facebook.com/docs/graph-api/reference/photo/
If you donĀ“t get any photos, debug your Access Token and make sure it really is a User Token that includes the user_photos permission: https://developers.facebook.com/tools/debug/accesstoken/

Related

Unable to get user info after update to FB API

ERROR MESSAGE:
Invalid Scopes: user_birthday, user_photos, user_gender. This message
is only shown to developers
After Facebook update in their api I get invalid scope messages for user_birthday, user_photos, user_gender. I haven't submitted my app for a login review, however, as an admin of the app I shouldn't be having any errors related to permissions. What could I possibly be doing wrong?
FBSDKLoginManager().logIn(withReadPermissions: ["email", "public_profile", "user_birthday", "user_photos", "user_gender"], from: self) { (result, err) in
print("open facebook safari")
if (err != nil) {
print("Fb Login Failed", err ?? "")
self.dismiss(animated: true, completion: nil)
}
self.handleFirebase()
}
FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, first_name, last_name, gender, birthday, picture.width(400).height(400)"]).start(completionHandler: { (connection, result, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let userData = result as? NSDictionary {
self.firstName = userData.object(forKey: "first_name") as? String
self.gender = userData.object(forKey: "gender") as? String
self.birthday = userData.object(forKey: "birthday") as? String ?? ""
let pictureDictionary = userData.object(forKey: "picture") as! NSDictionary
let pictureSubDictionary = pictureDictionary.object(forKey: "data") as! NSDictionary
self.userProfileUrl = pictureSubDictionary.object(forKey: "url") as! String
}
}

From FBSDKGraphRequest to Storyboard

i'm total beginner in coding, but i have a big question :)
I dont know how to get information to display on Main Storyboard form FBSDKGraphRequest.
What i should do next to get picture to Storyboard? I hope someone can help me :)
Using Swift 3, Xcode 8
Facebook login is working and code is:
func getFBUserData(){
if((FBSDKAccessToken.current()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil){
self.dict = result as? [String : AnyObject]
print(result!)
print(self.dict)
}
})
}
I see it as four steps -- my apologies to you if you already know some of this.
Drag an UIImageView from the object library in interface builder to a view in your storyboard.
Connect the UIImageView to your code as an IBOutlet and name it. Do this by control dragging from your new UIImageView to your code, and then in the popup specify an outlet and name the UIImageView. In my case I named it 'facebookPicture'
Get the URL for the image from the FaceBook result. The following sample code drills down into the result dictionary step by step. There are many ways to shorten this.
#IBOutlet var facebookPicture: UIImageView!
func getFBUserID(){
if((FBSDKAccessToken.current()) != nil) {
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(
completionHandler: {
[weak self] (connection, result, error) -> Void in
guard let strongSelf = self else { return }
if let error = error {
print("Failed to download FB user with error:. \(error)")
}
if (error == nil) {
let resultDictSwift = result as! Dictionary<String, Any>
if let picture = resultDictSwift["picture"] as? Dictionary<String, Any> {
if let pictureData = picture["data"] as? Dictionary<String, Any> {
if let pictureURL = NSURL(string: (pictureData["url"] as? String)! ) {
strongSelf.downloadImage(url: pictureURL as URL)
}
}
}
print(result!)
let FBID = resultDictSwift["id"]
strongSelf.facebookID = FBID as! String?
print("User FB id: \(strongSelf.facebookID!)")
}
})
}
}
Download the image from the URL location. The following does this asynchronously and uses a previous stack overflow answer here When the download is complete, it sets the result of the download to be the image in your UIImageView
func getDataFromUrl(url: URL, completion: #escaping (Data?, URLResponse?, Error?) -> ()) {
URLSession.shared.dataTask(with: url) { data, response, error in
completion(data, response, error)
}.resume()
}
func downloadImage(url: URL) {
print("Download Started")
getDataFromUrl(url: url) { data, response, error in
guard let data = data, error == nil else { return }
print(response?.suggestedFilename ?? url.lastPathComponent)
print("Download Finished")
DispatchQueue.main.async() {
self.facebookPicture.image = UIImage(data: data)
}
}
}
I hope this helps!
In Swift 3
#IBAction func btnFacebookTapped(_ sender: UIButton)
{
let loginManager = FBSDKLoginManager()
loginManager.logIn(withReadPermissions: ["user_about_me", "email" , "user_birthday","user_hometown"], from: self) { (loginResult, error) in
if error != nil
{
self.showalert(strMessage: (error?.localizedDescription)!)
}
else
{
if loginResult?.grantedPermissions == nil
{
self.showalert(strMessage: "Login Permissions not granted")
return
}
if (loginResult?.grantedPermissions.contains("email"))!
{
self.getFBUserData()
}
}
}
}
func getFBUserData()
{
FBSDKGraphRequest.init(graphPath: "me?fields=id,name,email,first_name,last_name,cover,picture.type(large),gender,birthday,hometown", parameters: nil).start(completionHandler: { (connection , result , error ) in
if(error == nil){
DispatchQueue.main.async {
let dictionary = result as! NSDictionary
print(dictionary)
print("Name : \(dictionary.value(forKey: "name")!)")
print("FB ID : \(dictionary.value(forKey: "id")!)")
}
}else{
self.showalert(strMessage: "Somthig Went Wrong..!")
}
})
}

iOS Facebook SDK: FBSDKGraphRequest doesn't return email (Swift)

I've seen similar questions on here but none seem to resolve my issue.
I'm currently creating an iOS app that uses the Facebook SDK to login and return user information.
I've successfully logged into facebook and receive the requested information. However, the request is not returning email despite allowing read permission for email.
/********************
Place Facebook login button
*********************/
let loginButton = FBSDKLoginButton()
view.addSubview(loginButton)
loginButton.delegate = self
loginButton.readPermissions = ["email", "public_profile"]
//add button constraints
loginButton.center = view.center
}
/**
* Functions called when user handed back from facebook login
**/
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
print("Did log out of facebook")
}
/**
* Functions called when user handed back from facebook login
**/
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if error != nil {
print(error)
} else
{
print("Successfully logged in with facebook")
FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, email"]).start
{ (connection, result, err) in
if err != nil{
print("Failed to start graph request: ", err)
return
}
print(result)
}
}
}
Well i pondered on this for a long time and came upon this link which suggested that if you don't have a confirmed email address I won't get it back in the login section of my code.
let request = GraphRequest(graphPath: "me", parameters: ["fields": "id, email, name, first_name, last_name, picture.type(large)"], accessToken: AccessToken.current, httpMethod: .GET, apiVersion: "2.12")
request.start { (response, result) in
switch result {
case .success(let value):
print(value.dictionaryValue!)
self.responseJSON = JSON(value.dictionaryValue!)
let fullName = self.responseJSON["first_name"].stringValue
let firstName = self.responseJSON["first_name"].stringValue
let lastName = self.responseJSON["last_name"].stringValue
let email = self.responseJSON["email"].stringValue
let idFb = self.responseJSON["id"].stringValue
let picture = self.responseJSON["picture"]["data"]["url"].stringValue
print("user id: \(idFb), firstName: \(firstName), fullname: \(fullName), lastname: \(lastName), picture: \(picture), email: \(email)")
print("ALL FIELDS PUBLISHED")
if let delegate = self.responseDelegate {
delegate.responseUpdated(self.responseJSON, forLogin: "FB")
}
case .failed(let error):
print(error)
}
}
}
Hence when I got to it and confirmed my email address it gave me the email in response. Here are some attached snapshots.
This is how i got to it. Later I implemented that if the email is not returned, I showed an alert alerting the user that there is no email associated with that facebook account and either they confirm their email or proceed by giving a separate email address in an TextField Alert. And thats that.
You can't fetch the users email from an FBSDKGraphRequest according to Facebook Graph API tool. Facebook only returns the token used to login. If you used Facebook login with Firebase you could fetch the email with CurrentUser.currentEmail Method.
let login = FBSDKLoginManager()
login.logIn(withReadPermissions: ["email","user_posts","public_profile"], from: self, handler: {
(result: FBSDKLoginManagerLoginResult?, error: Error?) in
if error != nil {
print("Process error")
return
}
else if (result?.isCancelled)! {
print("Cancelled")
}
else {
//Success!
let credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
self.firebaseLogin(credential)
}
})
import FBSDKCoreKit
import FBSDKLoginKit
import FBSDKShareKit
#IBAction func btnFbPressed(_ sender: Any) {
let loginManager = FBSDKLoginManager()
loginManager.logIn(withReadPermissions: ["public_profile", "email"], from: self) { (loginResult, error) in
if error != nil {
print(error!)
}
else {
if (loginResult?.grantedPermissions.contains("email"))! {
self.getFBUserData()
}
}
}
}
func getFBUserData(){
if((FBSDKAccessToken.current()) != nil){
UserDefaults.standard.set(FBSDKAccessToken.current().tokenString, forKey: "fbToken")
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil) {
print(result as Any)
let dictionary = result as! NSDictionary
print(dictionary)
let hud = MBProgressHUD.showAdded(to: self.view, animated: true)
hud.tintColor = .black
hud.mode = .indeterminate
hud.label.text = "Loading"
hud.animationType = .fade
hud.show(animated: true)
let postString = String(format: "login_type=facebook&email=%#&id=%#&device=0", arguments: [dictionary.value(forKey: "email") as! String, dictionary.value(forKey: "id") as! String])
}
})
}
}

Facebook Login not working in IOS SDK

I am struggling with the issue of Facebook login, Yesterday Facebook login working correctly but today when I run my app it's not working don't know why, why it's not working suddenly I already configured all things related to Facebook login in Facebook develop console everything is configured
Please help me out if you have any idea, I already enable Keychain sharing also.
Code for Facebook Login
#IBAction func onClickFacebookLoginAction(_ sender: Any) {
var message = String()
if Reachability.isConnectedToNetwork() == true{
let loginView:FBSDKLoginManager = FBSDKLoginManager()
loginView.loginBehavior = FBSDKLoginBehavior.web
loginView.logIn(withReadPermissions: ["email","public_profile","user_friends"], from: self, handler: { (result, error) in
if(error != nil){
print("Error while try to login with facebook-\(error?.localizedDescription)")
}else if (result?.isCancelled)!{
print("User cancel the facebook login")
}else{
if result?.grantedPermissions != nil{
if (result?.grantedPermissions .contains("email"))!{
self.ShowProgressHUD()
self.fetchUserInfo()
}else{
message = message.appending("Facebook email permission error")
self.showAlertMessage(message: message, title: "")
}
}
}
})
}
}
func fetchUserInfo() -> Void {
if (FBSDKAccessToken.current() != nil) {
let graphRequest:FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "/me", parameters:["fields": "id, first_name, last_name, name, email, picture"])
graphRequest.start(completionHandler: { (connection, result, error) in
if(error != nil){
self.showAlertMessage(message: (error?.localizedDescription)!, title: "")
}
else
{
print("Result is:\(result)")
self.dictionary = result as! [String : AnyObject]
let name = self.dictionary["name"] as!String
let email = self.dictionary["email"] as! String
let token = FBSDKAccessToken.current().tokenString
print("name is -\(name)")
print("email is -\(email)")
print("token is -\(token)")
DispatchQueue.main.async {
let SelectionViewObj = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.navigationController?.pushViewController(SelectionViewObj, animated: true)
}
}
})
}
}
This is the code i am using to authenticate facebook.its working like a charm.Just check or replace with this.
self.fbLoginManager = FBSDKLoginManager.init()
fbLoginManager.loginBehavior = FBSDKLoginBehavior.web
self.fbLoginManager.logIn(withReadPermissions: ["email"], from: self) { (result, error) -> Void in
if (error == nil) {
let fbloginresult : FBSDKLoginManagerLoginResult = result!
if fbloginresult.grantedPermissions != nil && fbloginresult.grantedPermissions.contains("email") {
if((FBSDKAccessToken.current()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"id, first_name, last_name, email, gender, birthday, location"]).start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
print(error?.localizedDescription ?? "error in facebook login...!")
return
}
if let dict = result as? NSDictionary {
print("facebook login result --->\n\(dict)")
guard let id = dict["id"] else {
print("Ooops... id = nil")
return
}
// let firstName: String = dict["first_name"] as? String ?? ""
// let lastName : String = dict["last_name"] as? String ?? ""
// let email : String = dict["email"] as? String ?? ""
self.fbLoginManager.logOut()
}
})
}
} else {
print("facebook ---> login canceled")
}
} else {
print(error?.localizedDescription ?? "facebook login has error")
}
}
This is how I used to log in with Facebook,
#IBAction func act_loginFB(_ sender: UIButton) {
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.logIn(withReadPermissions: ["public_profile", "email",], from: self) { (result, error) -> Void in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result!
if(fbloginresult.grantedPermissions.contains("email"))
{
self.getFBUserData()
}
}
}
}
func getFBUserData(){
if((FBSDKAccessToken.current()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil){
//everything works print the user data
print(result)
let data: [String:AnyObject] = (result as? [String : AnyObject])!
print(data)
let email: String = data["email"]! as! String
print(email)
}
})
}
}
Check you added the correct FacebookAppID and FacebookDisplayName in the info.plist

iOS facebookSDK get user full details

Iam using the last FBSDK (using swift)
// MARK: sign in with facebook
func signInWithFacebook()
{
if (FBSDKAccessToken.currentAccessToken() != nil)
{
// User is already logged in, do work such as go to next view controller.
println("already logged in ")
self.returnUserData()
return
}
var faceBookLoginManger = FBSDKLoginManager()
faceBookLoginManger.logInWithReadPermissions(["public_profile", "email", "user_friends"], handler: { (result, error)-> Void in
//result is FBSDKLoginManagerLoginResult
if (error != nil)
{
println("error is \(error)")
}
if (result.isCancelled)
{
//handle cancelations
}
if result.grantedPermissions.contains("email")
{
self.returnUserData()
}
})
}
func returnUserData()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
println("Error: \(error)")
}
else
{
println("the access token is \(FBSDKAccessToken.currentAccessToken().tokenString)")
var accessToken = FBSDKAccessToken.currentAccessToken().tokenString
var userID = result.valueForKey("id") as! NSString
var facebookProfileUrl = "http://graph.facebook.com/\(userID)/picture?type=large"
println("fetched user: \(result)")
}
when I print the fetched user I get only the id and the name ! ,
but i requested a permission for email and friends and profile ,
what's wrong ???
BTW : I moved this project from my macbook to another macbook ( because I formatted mine) it worked very well when it was at the the macbook which I created the project on , but after moving the project (using bitbucket clone) I got this results .
As per the new Facebook SDK, you must have to pass the parameters with the FBSDKGraphRequest
if((FBSDKAccessToken.currentAccessToken()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
println(result)
}
})
}
Documentations Link : https://developers.facebook.com/docs/facebook-login/permissions/v2.4
User object reference : https://developers.facebook.com/docs/graph-api/reference/user
With public profile you can get gender :
public_profile (Default)
Provides access to a subset of items that are part of a person's public profile. A person's public profile refers to the following properties on the user object by default:
id
name
first_name
last_name
age_range
link
gender
locale
timezone
updated_time
verified
Swift 4
An example in Swift 4 that also shows how to correctly parse out the individual fields from the result:
func fetchFacebookFields() {
//do login with permissions for email and public profile
FBSDKLoginManager().logIn(withReadPermissions: ["email","public_profile"], from: nil) {
(result, error) -> Void in
//if we have an error display it and abort
if let error = error {
log.error(error.localizedDescription)
return
}
//make sure we have a result, otherwise abort
guard let result = result else { return }
//if cancelled nothing todo
if result.isCancelled { return }
else {
//login successfull, now request the fields we like to have in this case first name and last name
FBSDKGraphRequest(graphPath: "me", parameters: ["fields" : "first_name, last_name"]).start() {
(connection, result, error) in
//if we have an error display it and abort
if let error = error {
log.error(error.localizedDescription)
return
}
//parse the fields out of the result
if
let fields = result as? [String:Any],
let firstName = fields["first_name"] as? String,
let lastName = fields["last_name"] as? String
{
log.debug("firstName -> \(firstName)")
log.debug("lastName -> \(lastName)")
}
}
}
}
}
I guess this code should help you get the required details
Swift 2.x
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
print("Error: \(error)")
}
else
{
print("fetched user: \(result)")
let userName : NSString = result.valueForKey("name") as! NSString
print("User Name is: \(userName)")
let userID : NSString = result.valueForKey("id") as! NSString
print("User Email is: \(userID)")
}
})
In Swift 4.2 and Xcode 10.1
#IBAction func onClickFBSign(_ sender: UIButton) {
if let accessToken = AccessToken.current {
// User is logged in, use 'accessToken' here.
print(accessToken.userId!)
print(accessToken.appId)
print(accessToken.authenticationToken)
print(accessToken.grantedPermissions!)
print(accessToken.expirationDate)
print(accessToken.declinedPermissions!)
let request = GraphRequest(graphPath: "me", parameters: ["fields":"id,email,name,first_name,last_name,picture.type(large)"], accessToken: AccessToken.current, httpMethod: .GET, apiVersion: FacebookCore.GraphAPIVersion.defaultVersion)
request.start { (response, result) in
switch result {
case .success(let value):
print(value.dictionaryValue!)
case .failed(let error):
print(error)
}
}
let storyboard = self.storyboard?.instantiateViewController(withIdentifier: "SVC") as! SecondViewController
self.present(storyboard, animated: true, completion: nil)
} else {
let loginManager=LoginManager()
loginManager.logIn(readPermissions: [ReadPermission.publicProfile, .email, .userFriends, .userBirthday], 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 : \(grantedPermissions), \n \(declinedPermissions), \n \(accessToken.appId), \n \(accessToken.authenticationToken), \n \(accessToken.expirationDate), \n \(accessToken.userId!), \n \(accessToken.refreshDate), \n \(accessToken.grantedPermissions!)")
let request = GraphRequest(graphPath: "me", parameters: ["fields": "id, email, name, first_name, last_name, picture.type(large)"], accessToken: AccessToken.current, httpMethod: .GET, apiVersion: FacebookCore.GraphAPIVersion.defaultVersion)
request.start { (response, result) in
switch result {
case .success(let value):
print(value.dictionaryValue!)
case .failed(let error):
print(error)
}
}
let storyboard = self.storyboard?.instantiateViewController(withIdentifier: "SVC") as! SecondViewController
self.navigationController?.pushViewController(storyboard, animated: true)
}
}
}
}
https://developers.facebook.com/docs/graph-api/reference/user

Resources