I'm attempting to fetch an array of a users facebook albums via the new Facebook SDK 4.1 using the following Swift code:
func getAlbumList()
{
var FBAlbums = [String]()
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me?fields=albums", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
println("Error: \(error)")
}
else
{
println("fetched data: \(result)")
let graphData = result.valueForKey("data") as Array;
for obj:FBGraphObject in graphData{
let desc = obj.description;
println(desc);
let name = obj.valueForKey("name") as String;
println(name);
}
}
})
}
The FB SDK query is working ok as the result value contains all the data from facebook (it prints fine), however any attempt to actually turn this into an array is failling.
Using XCode 6.3 this gives the following errors:
let graphData = result.valueForKey("data") as Array; = 'AnyObject?' is not convertible to 'Array<T>'
for obj:FBGraphObject in graphData{ = Use of undeclared type 'FBGraphObject'
I can't seem to find any information about what has replaced FBGraphObject, or why I can't convert the result to an array.
Articles used as background (but out of date it seems):
Creating an Array of objects from the Facebook SDK in Swift
http://selise.ch/build-a-facebook-album-browser-using-swift/
Just change this line of your code:
let graphData = result.valueForKey("data") as Array;
To:
self.dict = result["data"] as! NSArray
This works for me retrieving user photos from facebook:
FBSDKGraphRequest(graphPath: "me/photos", parameters: ["fields": "id, name, source"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
self.dict = result["data"] as! NSArray
for item in self.dict { // loop through data items
if let urlString = item["source"]! {
let url = NSURL(string: urlString as! String)
let imageData = NSData(contentsOfURL: url!)
let image = UIImage(data: imageData!)
self.socialPhotoCollection.append(image!)
}
}
}
})
This is for getting all albums in a different way
Swift 3x:
FBSDKGraphRequest(graphPath: "/me/albums", parameters: ["fields":"id,name,user_photos"], httpMethod: "GET").start(completionHandler: { (connection, result, error) in
print(result!)
})
Related
I keep getting this error for my graph requests??
Type 'Any?' has no subscript members
the error points at result.... this only happened when I converted to swift 3... anybody????
let nextrequest: FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me/friends", parameters: ["fields": "name, id, gender"], httpMethod: "GET")
nextrequest.start { (connection, result, error) -> Void in
guard let listOfFriends = result["data"] as? [AnyObject] else {
return
}
}
}
Try this
let nextrequest: FBSDKGraphRequest = FBSDKGraphRequest(graphPath:"me/friends", parameters: ["fields": "name, id, gender"], httpMethod: "GET")
nextrequest.start { (connection, result, error) -> Void in
guard let result = result as? [String:[AnyObject]], let listOfFriends = result["data"] else {
return
}
}
}
A little explanation
In Swift 3, the Value type of NSDictionary, NSArray, etc. have been
changed to Any. So the result type of subscript result[key] is Any?,
which cannot be automatically converted to AnyObject.
You have to explicitly cast into [String:[AnyObject]] type before using the result.
Try using,
let tResult = result as? [String:[AnyObject]]
guard let listOfFriends = tResult["data"] else { return; }
as mentioned in the answer of #xhmar
I'm getting the following error when I try to make a data request using the Facebook SDK:
Cannot convert value of type '(_,_,_) throws -> Void' to expected argument type 'FBSDKGraphRequestHandler!'
Here is the relevant code where the error is occurring. I found this in a tutorial but I think it worked with older versions of XCode. I'm using the latest version 7.2.1.
UPDATED
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, gender, email"])
graphRequest.startWithCompletionHandler ({ [weak self] connection, result, error in
if error != nil {
//onError()
print(error)
return
} else {
//get results
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()
}
}
}
})
Thanks!
PICTURE (click on the image to make it larger)
http://imgur.com/skCa1VB
I hope you are using the latest FBSDK in that the completionHandler: has been changed. See the below code:
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: param)
graphRequest.startWithCompletionHandler { [weak self] connection, result, error in
if error != nil {
//onError()
print(error.description)
return
}else{
let fbResult = result as! Dictionary<String, AnyObject>
//Do You rest of the code here
}
})
I am working with iOS 9.2 & Swift 2.1 & FBSDKVersion: 4.7.0.
I tried with Graph API Explorer, at that time I am getting the desired output.
The converted code is in Objective-C and I changed it to Swift.
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "hometown"], HTTPMethod: "GET")
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil){
print("Error: \(error)")
}
else{
print("fetched details: \(result)")
})
See below example and add hometown option into "fields" parameter of FBSDKGraphRequest object and also change:
func fetchUserProfile()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"id, email, name, picture.width(480).height(480)"])
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
print("Error took place: \(error)")
}
else
{
print("Print entire fetched result: \(result)")
let id : NSString = result.valueForKey("id") as! String
print("User ID is: \(id)")
if let userName = result.valueForKey("name") as? String
{
self.userFullName.text = userName
}
if let profilePictureObj = result.valueForKey("picture") as? NSDictionary
{
let data = profilePictureObj.valueForKey("data") as! NSDictionary
let pictureUrlString = data.valueForKey("url") as! String
let pictureUrl = NSURL(string: pictureUrlString)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
let imageData = NSData(contentsOfURL: pictureUrl!)
dispatch_async(dispatch_get_main_queue()) {
if let imageData = imageData
{
let userProfileImage = UIImage(data: imageData)
self.userProfileImage.image = userProfileImage
self.userProfileImage.contentMode = UIViewContentMode.ScaleAspectFit
}
}
}
}
}
})
}
Also refer to this link
Fetching user details from Facebook in iOS
If I call this method to obtain a Facebook profile picture it does not work, response gets printed with the data but when I return it its nil, can anyone help?
func getProfilePicture() -> NSData?{
var response:NSData?
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"picture.type(large)"])
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if error != nil {
print("login error: \(error!.localizedDescription)")
return
}
let json = JSON(result)
let profilePicture = json["picture"]["data"]["url"].stringValue
if let url = NSURL(string: profilePicture) {
if let pictureData = NSData(contentsOfURL: url){
response = pictureData
}
}
})
print(response)
return response
}
The Facebook call is using an async completionblock and your return statement will return nil before the call is done loading. That is why you also should use a completion block in your method.
Here is an example how to do this:
func getProfilePicture(completion: (pictureData: NSData?, error: NSError?) -> Void) {
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"picture.type(large)"])
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
var pictureData: NSData?
let json = JSON(result)
let profilePicture = json["picture"]["data"]["url"].stringValue
if let url = NSURL(string: profilePicture) {
pictureData = NSData(contentsOfURL: url)
}
completion(pictureData: pictureData, error: error)
})
}
You can call this code like this:
self.getProfilePicture {(pictureData, error) -> Void in
if error != nil {
print("login error: \(error!.localizedDescription)")
}
print(pictureData)
}
I use Parse with Facebook login so if I try to get the profile picture of the logged in user I get the error:
unexpectedly found nil while unwrapping an Optional value
I think the version of the SDK must be v4.5.1, and I use the Xcode 7 beta with Swift 2.
I use the code below to get the job done, but it won't run.
let pictureRequest = FBSDKGraphRequest(graphPath: "me/picture?type=large&redirect=false", parameters: ["fields": "url"])
pictureRequest.startWithCompletionHandler({ (connection, result, error: NSError!) -> Void in
if error == nil {
print("\(result)")
if let dictPic = result as? Dictionary<String, AnyObject> {
print(dictPic)
let url: String = dictPic["data{url}"] as AnyObject? as! String // <- this line is causing the error
print(url)
let URLRequest = NSURL(string: url)
let URLRequestNeeded = NSURLRequest(URL: URLRequest!) NSURLSession.sharedSession().dataTaskWithRequest(URLRequestNeeded, completionHandler: { (data, response, error) -> Void in
let picture = self.scaleImageWith(UIImage(data: data!)!, and: CGSizeMake(75, 75))
let pictureData = UIImagePNGRepresentation(picture)
let endPicture = PFFile(data: pictureData!)
PFUser.currentUser()!.setObject(endPicture, forKey: "picture")
PFUser.currentUser()!.saveInBackground()
})
}
} else {
print("\(error)")
}