I'm making an app with Facebook login. I get user profile pics the normal way:
https://graph.facebook.com/[USER_ID]/picture?type=large
but one of my test users only has a facebook page, not a facebook profile. His userID shows up as normal, but I only get the silhouette image for him.
Is there a way, ideally parallel to the above method for users, to get the picture associated with a page, given the userID of the page's owner/admin?
EDIT: To clarify, I want to get the publicly-available picture that's in the 'profile pic' UI section for a page, but which isn't associated with any particular user. See https://www.facebook.com/cajitamusic for example.
No, you'd have to ask for permission to access the user's pages first (which could be an extra unwanted threshold to use your app).
I think you can. You can using the same with
https://graph.facebook.com/[PAGE_ID]/picture?type=large
The problem for you seems is how to get object id of the page. You can try search API as it works for me when I try to get city profile picture.
fbPageInfo = [FBRequestConnection startWithGraphPath:[NSString stringWithFormat:#"search?q=%#&type=page",[cityName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// Sucess! Include your code to handle the results here
NSLog(#"result: %#", result);
NSArray* pages = (NSArray *)[result data];
if (pages.count > 0) {
NSDictionary *firstCityPage = [pages objectAtIndex:0];
for (NSDictionary *page in pages) {
//NSLog(#"user events: %#", page);
if ([[page objectForKey:#"category"] isEqualToString:#"City"]) {
firstCityPage = page;
break;
}
}
NSString *profileImgUrl = [NSString stringWithFormat:#"http://graph.facebook.com/%#/picture?type=large", [firstCityPage objectForKey:#"id"]];
...
}
} else {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
// do nothing - user default image
fbPageInfo = nil;
NSLog(#"Can't get image for %#. Error:%#", cityName, [error description]);
}
}];
Also how to get bigger picture you can find it in this answer:
How to get the bigger profile picture of a facebook page
Related
I have my [PFFacebookUtils logInWithPermissions] like this:
NSArray *permissionsArray = #[#"user_about_me"];
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
} else {
NSLog(#"User logged in through Facebook!");
} }];
The problem is that the method uploads an username similar to "St42o7PejDRh6scvMJylgOxGQ". What i want is to have the real username from Facebook uploaded, as well as the Facebook password and other relevant fields.
EDIT : With username i am specifically meaning First name, last name, and email if possible !
The Graph API uses OAuth as auth mechanism, so there's no way to get the username and password.
See
https://developers.facebook.com/docs/facebook-login/overview/v2.3
https://developers.facebook.com/docs/facebook-login/access-tokens
Not sure if this is still an issue for you, but because Facebook removed this feature from their API you can't access it like you can for, let's say a PFUser
example:
NSString *userName = [[PFUser user] username];
What you CAN do however is open up a Facebook Graph API request in order to retrieve this information like such:
1) First set the parameters of what you want to get from Facebook: (here i just did the FB id, the username, and the email)
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:#"id,name,email" forKey:#"fields"];
2) Just call the Facebook Graph API and request the information that you need like such:
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:nil];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"Facebook Graph API user: %#", result);
}
}];
3) This is what you should get: (I have replaced personal information with generic pointers for security reasons)
2015-11-15 18:52:18.204 YOURAPPNAME[60800:18917239] Facebook Graph API user: {
id = <the user id>;
name = "Full User Facebook Name";
email = "user#email.com";
}
Hopefully this will help you get what you are looking for! If its too late, at maybe this will help someone else in the future
i want to store some data in "EverNote" through our app either (image or text or both).
I googled, i got some guidance like EverNote SDK and i got the EverNoteCounter Sample also(When i run this, when i click getCount button it shows an alert message "Could not authenticate").
I generated the developer token also.
But i unable to create the consumerKey,consumerSecret. And also i did not find how to store our data to evernote from our app.
I got some links like this one
but when i go through that link it says( HTTP method GET is not supported by this URL)
I able to authenticate with the EVERNOTE and i able to get the number of notebooks in that Account.
I am using sqllite in my app. i am using one folder for images. Sqllite have the images links info.
How to store the data.
I used the following code to authenticate and to get the count
- (IBAction)retrieveUserNameAndNoteCount:(id)sender
{
// Create local reference to shared session singleton
EvernoteSession *session = [EvernoteSession sharedSession];
[session authenticateWithViewController:self completionHandler:^(NSError *error) {
// Authentication response is handled in this block
if (error || !session.isAuthenticated) {
// Either we couldn't authenticate or something else went wrong - inform the user
if (error) {
NSLog(#"Error authenticating with Evernote service: %#", error);
}
if (!session.isAuthenticated) {
NSLog(#"User could not be authenticated.");
}
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not authenticate"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] autorelease];
[alert show];
} else {
// We're authenticated!
EvernoteUserStore *userStore = [EvernoteUserStore userStore];
// Retrieve the authenticated user as an EDAMUser instance
[userStore getUserWithSuccess:^(EDAMUser *user) {
// Set usernameField (UILabel) text value to username
[usernameField setText:[user username]];
// Retrieve total note count and display it
[self countAllNotesAndSetTextField];
} failure:^(NSError *error) {
NSLog(#"Error retrieving authenticated user: %#", error);
}];
}
}];
}
- (void)countAllNotesAndSetTextField
{
// Allow access to this variable within the block context below (using __block keyword)
__block int noteCount = 0;
EvernoteNoteStore *noteStore = [EvernoteNoteStore noteStore];
[noteStore listNotebooksWithSuccess:^(NSArray *notebooks) {
for (EDAMNotebook *notebook in notebooks) {
if ([notebook guid]) {
EDAMNoteFilter *filter = [[EDAMNoteFilter alloc] init];
[filter setNotebookGuid:[notebook guid]];
[noteStore findNoteCountsWithFilter:filter withTrash:NO success:^(EDAMNoteCollectionCounts *counts) {
if (counts) {
// Get note count for the current notebook and add it to the displayed total
NSNumber *notebookCount = (NSNumber *)[[counts notebookCounts] objectForKey:[notebook guid]];
noteCount = noteCount + [notebookCount intValue];
NSString *noteCountString = [NSString stringWithFormat:#"%d", noteCount];
[noteCountField setText:noteCountString];
}
} failure:^(NSError *error) {
NSLog(#"Error while retrieving note counts: %#", error);
}];
}
}
} failure:^(NSError *error) {
NSLog(#"Error while retrieving notebooks: %#", error);
}];
}
Please suggest me the links or give me the guidance
Thanks a lot in advance
Developer token is to be used when you only need to access your own account. To get a consumer key/secret, go here : http://dev.evernote.com/documentation/cloud/ .
If you are using iOS, https://github.com/evernote/evernote-sdk-ios has a sample app that you can use once you have a consumer key and secret.
In general, there is a lot of information on dev.evernote.com.
All SDKs are located at https://github.com/evernote
Getting started guide for iOS : http://blog.evernote.com/tech/2012/05/24/evernote-sdk-integration-ios/
Did you solved it? If not, i did the following to get it work:
download and include sdk
get consumerKey and secret (if you want to access notes too, then
instead of basic you should request for full access, http://dev.evernote.com/documentation/cloud/ top right corner)
Add the URLType entry in info.plist ("Modify your application's main
plist file" chapter https://github.com/evernote/evernote-sdk-ios)
Copy the session init code (filled with consumer key and secret, the hostname should be left unchanged) and implement the two application delegate specific code
An (on-screen) viewcontroller should be passed on authenticating the user to authenticateWithViewController method, f.e. the appdelegate's rootViewController
Study this pages to understand the model hierarchy used by Evernote:
http://dev.evernote.com/documentation/cloud/chapters/data_structure.php
http://dev.evernote.com/documentation/reference/Types.html
Image could be stored as EDAMResource (Resource) in the field data and text as EDAMNote (Note) in the field content. Both is handled by Evernote SDK's EvernoteNoteStore object.
Can you help me to understand when should I use UIActivityViewController. I have a button which shares common information about my app (something like "I like this app" with link and image). My old code was:
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setObject:picture forKey:#"picture"];
[params setObject:link forKey:#"link"];
[params setObject:#"I like MY app!" forKey:#"caption"];
[params setObject:#"I am now using MY iPhone app." forKey:#"description"];
[params setObject:linkToTheIcon forKey:#"icon"];
[params setObject:#"including link" forKey:#"type"];
[[FacebookConnection instance] feedLink:params andDelegate:self];
Now I want to use UIActivityViewController but I'm a bit confused how to pass all those parameters to it. Or should I do things in other way?
ADDED:
So I understood that I need silent posting procedure.
Could you please guide me through silent post procedure using iOS 6 features (e.d. using built-in FB account). For now I can't understand how to check if FB account exists on the device and if it is not how to prompt to create it? There is a method in ACAccount store class – requestAccessToAccountsWithType:options:completion: to access an account. But If an account does not exists it returns an error. Many thanks in advance.
In your situation it seems obvious that you should not use UIActivityViewController because you want to post on Facebook and not on twitter or anywhere else, right?
Firstly you need to get access to user's account. You do this like this:
-(void)requestBasicPermissionsForFacebookAccount {
ACAccountType * facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSArray * permissions = #[#"email"];
NSDictionary * options = #{ACFacebookAppIdKey : kFacebookAppId, ACFacebookPermissionsKey : permissions, ACFacebookAudienceKey : ACFacebookAudienceEveryone};
FacebookAccountManager * fbMgr = [[FacebookAccountManager alloc] init];
[self.accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSArray * accounts = [self.accountStore accountsWithAccountType:facebookAccountType];
fbMgr.account = [accounts lastObject];
fbMgr.isBasicPermissionsGranted = YES;
[self.accountManagers addObject:fbMgr];
NSLog(#"granted!");
}
else {
fbMgr.account = nil;
fbMgr.isBasicPermissionsGranted = NO;
switch ([error code]) {
case 1:
[self showErrorAlertWithMessage:#"Unknown error occured, try again later!"];
break;
case 3:
[self showErrorAlertWithMessage:#"Authentication failed, try again later!"];
break;
case 6:
[self showErrorAlertWithMessage:#"Facebook account does not exists. Please create it in Settings and come back!"];
break;
case 7:
[self showErrorAlertWithMessage:#"Permission request failed. You won't be able to share information to Facebook"];
break;
default:
break;
}
NSLog(#"error is: %#", error);
}
}];
}
If an account does not exists you should prompt user to create it in settings and then try to to obtain basic permissions again.
You first need to subclass UIActivity.
Then you need to override certain methods, including activityImage for setting the icon and performActivity for performing the action .
If instead of performing the action silently, you first need further user interaction and info for your custom activity (e.g., like the Twitter post for the standard UIActivity), you should override activityViewController rather than performActivity.
After you have subclassed UIActivity (as, e.g, MyActivity), you should create an instance of MyActivity and make it an element of the applicationActivities array that you pass to initWithActivityItems:applicationActivities:.
Have a look at the documentation for UIActivity for exactly what you need to override when subclassing and for icon requirements.
Hope this helps a little
I'm trying to upload a photo from the camera to a user's Facebook wall. I'm not entirely sure what the correct strategy is, but from reading around it seems the thing to do is upload the photo to an album, and then someone post on the wall a link to that album/photo. Ideally this would involve the dialog, but from what I can tell that's not possible.
I've managed to upload a photo to an album, and get back an ID for that photo, but I'm not sure what to do after that.
Can anyone provide some straightforward code for achieving this?
Bonus question: Is it possible to post the photo to the application wall, as well (or instead)?
Edit: Graph API is preferable, but anything that works at this stage is good.
I did this in three steps
1 post picture to album (returns imageID)
2 use imageID to request metadata for imageID
3 use the 'link' field (not the 'source' field) as a link to the image in a post to the user's wall
The downside is that there are now two posts to the wall, one for the image, and one for the actual post. I haven't figured out yet how to post a picture to an album, without also a wall post appearing (ideally it would just be the 2nd post that appears)
Step 1:
- (void) postImageToFacebook {
appDelegate = (ScorecardAppDelegate *)[[UIApplication sharedApplication] delegate];
currentAPICall = kAPIGraphUserPhotosPost;
UIImage *imgSource = {insert your image here};
NSString *strMessage = #"This is the photo caption";
NSMutableDictionary* photosParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:
imgSource,#"source",
strMessage,#"message",
nil];
[appDelegate.facebook requestWithGraphPath:#"me/photos"
andParams:photosParams
andHttpMethod:#"POST"
andDelegate:self];
// after image is posted, get URL for image and then start feed dialog
// this is done from FBRequestDelegate method
}
Step 2 (kAPIGraphUserPhotosPost) & step 3 (kAPIGraphPhotoData):
- (void)request:(FBRequest *)request didLoad:(id)result {
if ([result isKindOfClass:[NSArray class]] && ([result count] > 0)) {
result = [result objectAtIndex:0];
}
switch (currentAPICall) {
case kAPIGraphPhotoData: // step 3
{
// Facebook doesn't allow linking to images on fbcdn.net. So for now use default thumb stored on Picasa
NSString *thumbURL = kDefaultThumbURL;
NSString *imageLink = [NSString stringWithFormat:[result objectForKey:#"link"]];
currentAPICall = kDialogFeedUser;
appDelegate = (ScorecardAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableDictionary* dialogParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:
kAppId, #"app_id",
imageLink, #"link",
thumbURL, #"picture",
#"Just Played Wizard etc etc", #"name",
nil];
[appDelegate.facebook dialog:#"feed"
andParams:dialogParams
andDelegate:self];
break;
}
case kAPIGraphUserPhotosPost: // step 2
{
NSString *imageID = [NSString stringWithFormat:[result objectForKey:#"id"]];
NSLog(#"id of uploaded screen image %#",imageID);
currentAPICall = kAPIGraphPhotoData;
appDelegate = (Scorecard4AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.facebook requestWithGraphPath:imageID
andDelegate:self];
break;
}
}
}
I've modified the code to show just the Facebook stuff condensed. If you want to check if the post is successful you'll want something like this:
- (void)dialogDidComplete:(FBDialog *)dialog {
switch (currentAPICall) {
case kDialogFeedUser:
{
NSLog(#"Feed published successfully.");
break;
}
}
}
The blue text in the Facebook post is whatever you put in the "name" parameter in Step 3. Clicking on the blue text in Facebook will take you to the photo posted in Step 1, in an album in Facebook (Facebook creates a default album for your app if you don't specify an album). In my app's case it's the full-sized image of the scorecard (but could be any image, e.g. from the camera). Unfortunately I couldn't figure out a way to make the thumb image a live link, but it's not very readable so a default thumb works in my case. The part in the Facebook post (in black font) that says "First game of the year..." is entered by the user.
It's clearer what you wish to do - post a photo to FB, and guarantee that a post goes on the user's wall/stream.
Unfortunately, there are some things in the way.
FB Graph API appears to only allow you to post EITHER a picture to an album, or post to the wall directly, linking to a picture already existing somewhere on the web. In the first case, a post in the stream will probably be made, but FB appears to consolidate multiple posts in some manner so as to keep the user's stream from being bombarded. The mechanism for this is not documented anywhere I could see.
In the second case, you might think you could get away with posting to an album, and then explicitly posting a link to the album. You can add a parameter to the original album post, "no_story" with a value of 1, and suppress the wall post that might be made while you prepare to make an explicit one. However, FB will not have the source URL for a newly posted image for a while, AND, it doesn't appear to like URLs that include its own content delivery network, returning an error. You might think to simply put status update in the stream, talking about the post, However, the Graph API is also limited to 25 such direct feed posts per day per app, to prevent spamming.
One solution would be to post to something like Flickr, get the URL of the image, and then post to the wall. FB's preferred solution appears to be to use the FB dialogs that are part of the mobile toolkit - essentially little web pages much like the OAuth screen.
Personally, I plan to simply post to the album as above, and live with FB's idea of how the user should be notified. Curious how you choose to proceed.
I'm not sure what part isn't working for you, since you are posting and getting an ID back, but here is what I did in a quick and dirty way, in case someone reaches here via Google.
This is an HTTP POST function, and the binary data of the file goes up as multipart mime.
I'm a big fan of the ASIHTTPRequest library available here.
**UPDATE: 10/22/2012 ** - AFNetworking has replaced ASIHTTPRequest in my code in the past few months. Available on GitHub here
Facebooks docs are confusing, partly because they are incomplete and partly because they can be wrong. You'll probably tear some hair out figuring out exactly what post value to set for a caption or something, but this recipe puts a photo into an album, and that goes into the feed.
You still need to set up the Facebook OAuth stuff in the basic way - I happened to do that in the app delegate, so I grab the Facebook object from there to get my access token. I made sure to ask for the "publish_stream" permission when I authenticated, like this:
[facebook authorize:[NSArray arrayWithObjects:#"publish_stream", nil] delegate:self];
This will create or add to an album called "YOUR_APP_NAME Photos", and will appear in the user's feed. You can put it in any album, including the "Wall" album, by getting the ID of that album and changing the URL to http://graph.facebook.com/THE_ID_OF_THE_ALBUM/photos.
Here's the basic method:
-(void) postImageToFB:(UIImage *) image
{
NSData* imageData = UIImageJPEGRepresentation(image, 90);
Facebook* fb = [(uploadPicAppDelegate *)[[UIApplication sharedApplication] delegate] facebook ];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:#"https://graph.facebook.com/me/photos"]];
[request addPostValue:[fb accessToken] forKey:#"access_token"];
[request addPostValue:#"image message" forKey:#"message"];
[request addData:imageData forKey:#"source"];
[request setDelegate:self];
[request startAsynchronous];
}
Using the Facebook provided iOS library looks like this:
-(void) postImageToFB:(UIImage *) image
{
NSData* imageData = UIImageJPEGRepresentation(image, 90);
Facebook* fb = [(uploadPicAppDelegate *)[[UIApplication sharedApplication] delegate] facebook ];
NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:[fb accessToken],#"access_token",
#"message text", #"message",
imageData, #"source",
nil];
[fb requestWithGraphPath:#"me/photos"
andParams:params
andHttpMethod:#"POST"
andDelegate:self];
}
Using Facebook SDK 3.0:
- (void)postPhotoThenOpenGraphAction {
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
// First request uploads the photo.
FBRequest *request1 = [FBRequest
requestForUploadPhoto:self.selectedPhoto];
[connection addRequest:request1
completionHandler:
^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
}
}
batchEntryName:#"photopost"
];
// Second request retrieves photo information for just-created
// photo so we can grab its source.
FBRequest *request2 = [FBRequest
requestForGraphPath:#"{result=photopost:$.id}"];
[connection addRequest:request2
completionHandler:
^(FBRequestConnection *connection, id result, NSError *error) {
if (!error &&
result) {
NSString *source = [result objectForKey:#"source"];
[self postOpenGraphActionWithPhotoURL:source];
}
}
];
[connection start];
}
They follow this post with an OpenGraph action publish ([self postOpenGraphActionWithPhotoURL:source];), but if you just want the image on the user's wall, you wont need that.
More info:
https://developers.facebook.com/docs/tutorials/ios-sdk-tutorial/publish-open-graph-story/#step7
Yay!, FB SDK 3.0 rocks! No more AppDelegate.facebook :)
I searched far and wide for a solution that worked on the latest APIs, until I came across this:
http://xcodenoobies.blogspot.co.uk/2012/09/how-to-upload-photo-and-update-status.html
By far the clearest solution I've come across, simple and works with the latest API.
I am getting an image from facebook by the URL: http://external.ak.fbcdn.net/safe_image.php?d=d282e1e7c86c9270232f97ddc737df39&w=90&h=90&url=http%3A%2F%2Fi52.tinypic.com%2F2q0ixzl.jpg
Now, I want a bigger version, like 200 by 200. Is there a URL for that? If not, how can I convert this image to a larger size?
Generally if you want to collect the profile pic of a user or page, the format for the icon size picture is:
http://graph.facebook.com/[page id/profile id]/picture
and for the large picture:
http://graph.facebook.com/[page id/profile id]/picture?type=large
EDIT Points to note:
If the image stored on the facebook servers is less than the 200*200 dimensions, you would get the image as the highest resolution avaiable eg: 128*160. Either you can resize it using the GD library.
AND ONE MORE THING
Facebook supports 200*600px as the highest resolution for the profile pic. It will resize an image to fit into these dimensions by maintaining the aspect ratio.
*UPDATE as on 19th Feb, 2017 *
We need to use this new URL formation to get a desired profile image.
http://graph.facebook.com/{profile_id}/picture?width={number}&height={number}
[Thank you https://stackoverflow.com/users/2829128/vay]
If you want to get a larger picture you can just set the height and width you want like this:
http://graph.facebook.com/[page id/profile id]/picture?width=[number]&height=[number]
More info and examples here: Pictures - Facebook Developers
this will also work
picture.type(large)
example
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:#{#"fields": #"picture.type(large),name, email"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"fetched user:%#", result);
NSMutableDictionary *data=[[NSMutableDictionary alloc]init];
data=result;
fbId.text=[data valueForKey:#"id"];
userName.text=[data valueForKey:#"name"];
_emailFB.text=[data valueForKey:#"email"];
NSDictionary *dictionary = (NSDictionary *)result;
NSDictionary *data3 = [dictionary objectForKey:#"picture"];
NSDictionary *data2 = [data3 objectForKey:#"data"];
NSString *photoUrl = (NSString *)[data2 objectForKey:#"url"];
NSLog(#"Photo : %#",photoUrl);
}
}];
}
}
YES, there is a way to get the original (most of time bigger) profile picture of a facebook page.
Actually the answer is already in the question. The original image url is already embedded in the save_image url. In your case it is "url=http%3A%2F%2Fi52.tinypic.com%2F2q0ixzl.jpg” which means "http://i52.tinypic.com/2q0ixzl.jpg"
In my case, the page for London is
https://www.facebook.com/pages/London-United-Kingdom/106078429431815?fref=ts
I can easily get its fb object id by search keyword London.
I have tried to use width and height parameter. They work with user profile picture or user shared picture but can’t work with public pages profile picture.
https://graph.facebook.com/106078429431815/picture?width=300&height=300 // can’t work
The largest picture I can get it by following url which is only 180x77
https://graph.facebook.com/106078429431815/picture?type=large
But I can get safe_image.php url by using fb graph api, and the original image url is also inside the parameters' url section
"url": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQCrtKykRotXBuaS&w=180&h=540&url=http%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2Farchive%2F2%2F21%2F20141005220235%2521City_of_London_skyline_at_dusk.jpg%2F720px-City_of_London_skyline_at_dusk.jpg&fallback=hub_city&prefix=d"
Here is code I used.
[FBRequestConnection startWithGraphPath:[NSString stringWithFormat:#"/%#/picture?redirect=false&type=large",[firstCityPage objectForKey:#"id"]]
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSString *profileImgUrl = [NSString stringWithFormat:#"http://graph.facebook.com/%#/picture?type=large", [firstCityPage objectForKey:#"id"]];
if (error==nil) {
NSString *fbSaveImgUrl = [[(NSDictionary*)result objectForKey:#"data"] objectForKey:#"url"];
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:[NSURL URLWithString:fbSaveImgUrl]
resolvingAgainstBaseURL:NO];
for (NSURLQueryItem *queryItem in urlComponents.queryItems) {
if ([queryItem.name isEqualToString:#"url"]) {
profileImgUrl = queryItem.value;
break;
}
}
} else {
NSLog(#"%#",[error description]);
}
NSLog(#"url: %#", profileImgUrl);
...
}];
BUT, there are risks.
No guarantee the external image url will be validate.
Facebook may remove the explicit external url in the safe_image url or hide the safe_image url from developer in future.
Use it at your own risk.