Pulling Facebook profile pic with parse using Swift - facebook

I'm trying to pull the username and profile picture for my apps profile page. I'm using Parse and the Facebook SDK.
I have a UILabel and a UIView connected as outlets.
When I try to set the profileImageView, it gives me the error "Value of type 'UIImageView' has no member 'setImageWithURL'" Is this an upgrade with Swift?
Here is my code...
func setProfilePicture() {
FBSDKGraphRequest(graphPath: "me", parameters: nil).startWithCompletionHandler({ (connection, result, error) -> Void in
if let dict = result as? Dictionary<String, AnyObject> {
let name: String = dict["name"] as! String
let facebookID: String = dict["id"] as! String
let pictureUrl = "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1"
self.profileImageView.setImageWithURL(NSURL(string: pictureUrl)!)
self.nameLabel.text = name
PFUser.currentUser()!.setValue(name, forKey: "name")
PFUser.currentUser()!.saveInBackground()
}
})
}

if let url = NSURL(string: "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1") {
if let data = NSData(contentsOfURL: url){
self.profileImageView.contentMode = UIViewContentMode.ScaleAspectFit
self.profileImageView.image = UIImage(data: data)
}
}

Try creating a function, fbProfilePicURL, that takes a Facebook ID and returns the profile picture URL as an NSURL, then change
self.profileImageView.setImageWithURL(NSURL(string: pictureUrl)!)
to
self.profileImageView.setImageWithURL(NSURL.fbProfilePicURL(facebookID))
Not 100% sure on this, but let me know if it works.

Related

Cannot convert URL to Data(contentsOf: URL) in swift5

I know there are many solutions around related to converting an Image string into data and to set the image in an ImageView. But unfortunately, nothing worked in my case. I have a parsed JSON field which returns an Image as a string. So I'm trying to convert that String as URL and then to get URL data to display the image. But when the error is throwing when I try to get the data from URL like
let testImage = Data(contentsOf: forecastURL! as URL)
Error: "Incorrect argument label in call (have 'contentsOf:', expected
'dictionary:')"
if let url21 = URL(string: brandingLogo) {
do {
let testImage = Data(contentsOf: url21)
self.BrandingBarImage.image = UIImage(data: testImage)
}
catch
{
print("error")
}
}
**Code for brandingLogo:**
guard let url = URL(string: urlJson) else {return}
let task = URLSession.shared.dataTask(with: url) { (data1, response, error) in
do {
let parsedData = try JSONSerialization.jsonObject(with:data1!) as? [String:Any]
let statusList = parsedData?["data"] as? [String:Any]
let anotherData = statusList?["data"] as? [String:Any]
if let players = anotherData?["players"] as? [[String:Any]] {
for logo in players {
self.brandingLogo = logo["logo_app_branding_bar"] as? String
print(self.brandingLogo)
}
brandingLogo is parsed from Json and its value is: https://media.socastsrm.com/wordpress/wp-content/blogs.dir/223/files/2018/01/blank-300x95.png
so, I'm assuming that when this 'brandingLogo' is considered as String, it takes only the actual string like :
https://media.socastsrm.com/wordpress/wp-content/blogs.dir/223/files/2018/01/blank-300x95.png
And so I'm trying to convert that image string to URL and then to get Data
Any help is appreciated. Thank you

Get Facebook profile picture from URL

I want to upload the profile picture from Facebook to Firebase. I tried this answer: Upload Facebook image URL to Firebase Storage
However, Swift is giving me errors on the third line of code of that answer. The code is:
let dictionary = result as? NSDictionary
let data = dictionary?.object(forKey: "data")
let urlPic = (data?.objectForKey("url"))! as! String
Swift is telling me: Cannot call value of non-function type 'Any?!' after I changed the code to what Swift keeps suggesting me:
let urlPic = ((data as AnyObject).object(ForKey: "url"))! as! String
What is the code to use when I want to retrieve the profile picture from Facebook? My goal is to also store it into Firebase, but that will come after I get the profile picture first.
The answer is in Swift 1.2
I took reference here and implemented also
You can do this:
// accessToken is your Facebook id
func returnUserProfileImage(accessToken: NSString)
{
var userID = accessToken as NSString
var facebookProfileUrl = NSURL(string: "http://graph.facebook.com/\(userID)/picture?type=large")
if let data = NSData(contentsOfURL: facebookProfileUrl!) {
imageProfile.image = UIImage(data: data)
}
}
This is the way I got Facebook id:
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("fetched user: \(result)")
if let id: NSString = result.valueForKey("id") as? NSString {
println("ID is: \(id)")
self.returnUserProfileImage(id)
} else {
println("ID es null")
}
}
})
}

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.
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
}
}

Swift. Facebook profile picture returning a question mark?

Okay so when I try to recieve the users profil picture, the picture returns a white box with a question mark in it?
Heres my code:
func getProfilePic(fid: String) -> SKTexture? {
let imgURL = NSURL(string: "http://graph.facebook.com/" + fid + "/picture?type=large")
let imageData = NSData(contentsOfURL: imgURL!)
let imageUI = UIImage(data: imageData!)
let image = SKTexture(image: imageUI!)
return image
}
func getFBUserData() {
if((FBSDKAccessToken.currentAccessToken()) != nil) {
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, email, picture"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
print(result)
if let userData = result as? NSDictionary {
personalUserID = userData["id"] as! String
}
} else {
print("error")
}
})
}
picture.texture = getProfilePic("\(personalUserID)")
How do I get it to show the right picture?
I'm guessing your profile picture is not available for the public. Now you're not providing an access token with the request, so the request is handled as unauthorised - so you see only what the public eye sees.
To fix it:
func getProfilePic(fid: String) -> SKTexture? {
let imgURL = NSURL(string: "http://graph.facebook.com/" + fid + "/picture?type=large&access_token=" + FBSDKAccessToken.currentAccessToken().tokenString)
let imageData = NSData(contentsOfURL: imgURL!)
let imageUI = UIImage(data: imageData!)
let image = SKTexture(image: imageUI!)
return image
}
Also, you'd want to use https and the current API version v2.5 to make the requests, otherwise your code might break in any second when Facebook makes changes. So, with that in mind:
func getProfilePic(fid: String) -> SKTexture? {
let imgURL = NSURL(string: "https://graph.facebook.com/v2.5/" + fid + "/picture?type=large&access_token=" + FBSDKAccessToken.currentAccessToken().tokenString)
let imageData = NSData(contentsOfURL: imgURL!)
let imageUI = UIImage(data: imageData!)
let image = SKTexture(image: imageUI!)
return image
}
That should do the trick.

FBSDKGraphRequest to sign up Parse users is "ambiguous?"

The FBSDKGraphRequest connection handler used in the SignUpViewController of a tutorial app is now outdated. I updated it to a point where it won't error until I try to place the Parse code after the user successfully signs up. Once I put in the Parse code (to sign the user up using the FB SDK results), I get the errors "Type of expression is ambiguous without more context".
Here's what I have so far:
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, gender, email"])
graphRequest.startWithCompletionHandler ({ connection, result, error in
if error != nil {
//onError()
print(error)
return
} else {
let fbResult = result as! Dictionary<String, AnyObject>
print("FbResult \(fbResult)")
PFUser.currentUser()?["gender"] = result["gender"]
PFUser.currentUser()?["name"] = result["name"]
try PFUser.currentUser()?.save()
let userId = result["id"] as! String
let facebookProfilePictureUrl = "https://graph.facebook.com/" + userId + "/picture?type=large"
if let fbpicUrl = NSURL(string: facebookProfilePictureUrl) {
if let data = NSData(contentsOfURL: fbpicUrl) {
self.profilePic.image = UIImage(data: data)
let imageFile:PFFile = PFFile(data: data)!
PFUser.currentUser()?["image"] = imageFile
try PFUser.currentUser()?.save()
}
})
For some reason XCode hates anything after the "print fbresult" line. Here's a pastebin of the working code before the Parse code:
http://pastebin.com/dUyEvYmr
How can I update this to accept the Parse code?
Thanks!!
PS: I can confirm that I have the latest Parse and FB SDK. I'm running the latest version of XCode (7.2.1).
I came across with the same problem when going through the udemy swift class too.
My solution was:
if let fbResult = {
...
let name : NSString = (fbResult.valueForKey("name") as? NSString)!
let gender : NSString = (fbResult.valueForKey("gender") as? NSString)!
...
}
Hope it works for you!