FacebookAgent update: Now upload a photo and then change status in a single call using Facebook connect for iPhone

1 Star2 Stars3 Stars4 Stars5 Stars (6 votes, average: 4.17 out of 5)
Loading ... Loading ...

In my previous post I shared a FacebookAgent to simplify integrating Facebook connect in iPhone and using common actions without
handling login, permission check etc but in a single method call like:

  • Publish feed
  • Change status
  • Upload photo
Scotopia from iphonedevsdk.com shared an excellent idea of implementing a method which would upload a photo and then update status.
I have updated the FacebookAgent according to that. Now it has few more functions:
/**
 * Upload photo
 */
- (void) uploadPhoto:(NSString*)imageurl;
- (void) uploadPhotoAtURL:(NSString*)imageurl withCaption:(NSString*)captionOrNil toAlbum:(NSString*)aidOrNil;
- (void) uploadPhotoAsData:(NSData*)imagedata withCaption:(NSString*)captionOrNil toAlbum:(NSString*)aidOrNil;

/**
 * Upload photo with status
 */
- (void) uploadPhoto:(NSString*)imageurl withStatus:(NSString*)status;
- (void) uploadPhotoAtURL:(NSString*)imageurl withStatus:(NSString*)status caption:(NSString*)captionOrNil toAlbum:(NSString*)aidOrNil;
- (void) uploadPhotoAsData:(NSData*)imagedata withStatus:(NSString*)status caption:(NSString*)captionOrNil toAlbum:(NSString*)aidOrNil;

/**
 * Ask permission to auto approve uploaded photo and add photo to an album.
 */
- (void) askUplaoadPhotoToAlbumPermission;



Add to Google Reader or Homepage


  • Fawad
    Hi,
    I would like to appreciate your efforts for writing this wrapper class. It helped me a lot.

    I have one question, can we upload an image as NSData or you can say in binary format along with the feed, instead of passing an image URL. I actually want to upload my feed with an image, any useful pointers on this will be appreciated.

    Thanks
  • hey Fawad, glad to hear that it helped you.

    To post NSData use the following method of FacebookAgent:

    - (void) uploadPhotoAsData:(NSData*)imagedata withCaption:(NSString*)captionOrNil toAlbum:(NSString*)aidOrNil;


    btw, this code is not fully tested.. shooting me any bug you encounter is highly appreciated :)
  • Fawad
    I have tested it (uploadPhotoAsData), and it is successful, but what i want is, when we publish the feed, say for example using facebookAgent method

    - (void) publishFeedWithName:(NSString*)name
    captionText:(NSString*)caption
    imageurl:(NSString*)url
    linkurl:(NSString*)href
    userMessagePrompt:(NSString*)prompt
    actionLabel:(NSString*)label
    actionText:(NSString*)text
    actionLink:(NSString*)link
    targetId:(NSString*)target

    here, in ImageURL, can we upload the image as NSData, is it possible, is there any possible workaround for this, or do i have to upload the image first on facebook, then retrieve its URL and then upload the feed with the image URL.

    Thanks for your time :)
  • nope.. till now its not possible to upload image data to facebook while publishing feed as stated in their wiki. We have to put some valid image url.
  • Fawad
    i see, ok then i ll use some alternate approach, like first uploadin it on facebook and then retrieving its url, and use it as an extra link to the feed.
  • yep, probably u got to run a fql also.
  • Me
    I'm seeing two errors:

    1) Getting EXC_BAD_ACCESS when calling uploadPhotoAsData and uploadPhotoAsData withStatus. I've confirmed that the image data is valid.

    2) I present the FacebookAgent view from another view. When I log in to Facebook, leave the FacebookAgent view, then go back to the FacebookAgent view and do setStatus I get the Extended Permission window with the message "An invalid next or cancel parameter was specified". Pressing the okay button does not dismiss this permission window.
  • Me
    1) I'm still seeing this error, even after changing uploadImage to use NSMutableDictionary near line 202 in FacebookAgent.m

    2) It looks like I've solved this problem. The Facebook developers mentioned in the iPhone forum that logging in/out across view changes can cause the FB Connect _session variable to get out of sync. The solution is to always use initWithSession when asking permission.

    In FacebookAgent.m in askPermission near line 121 change:

    FBPermissionDialog* dialog = [[[FBPermissionDialog alloc] init] autorelease];

    to

    FBPermissionDialog* dialog = [[[FBPermissionDialog alloc] initWithSession:_session] autorelease];
  • sorry pal.. I had to move to actionscript development... learning it... hardly getting any time on iphone development :(
  • dev
    General security question folks, I notice here the facebook app API key and secret is being hard coded, which I also noticed was what looked to be the recommended way in facebooks 'integrate facebook connect in 5 minutes' video.

    Is this a security issue? Presumably someone downloading an app with a hardcoded key/secret would be able to dig that out with a 'jail broken' phone. They can then spoof FBConnect use as though it were coming from your application. This could lead to facebook pulling your facebook app from their site, if they spammed for example, making all those copies of your app no longer work.

    With key/secret hard-coding you are relying on facebook keeping the facebook app side of your iphone app running, or your iphone app is dead in the water.

    Is there a better way to set the key/secret?
  • One way can be:

    1. Store the keys in a server.
    2. Iphone request the keys
    3. server encrypts the keys with a random key(ekey)
    4. server sends the keys and the ekey
    5. iphone decrypts the fb keys with the ekey.


    any better idea? Please share..
  • The last version is very useful ! Great Work! But I have a little problem, when I get the pid of the uploaded photo, this is not the pid of the photo, it's a long int different of the pid. Do you have an idea how can I retrieve the correct pid ?
  • yea, I also found this. To retrieve the photo id a fql has to be executed.. i could not find any other easy solution for this. Please share if you solve this. Thanks.
  • Transton
    Damn you are good, I must say you are a star developing such excellent stuff and releasing it here on your site. There are two problems though, one regarding the FacebookAgent and one regarding the TwitterAgent.

    Problem 1.)
    The fbagent photo upload works flawlessly in the Simulator 3.1.2 | Debug, but when I try it on the Device 3.1.2 | Debug it crashes with EXC_BAD_ACCESS in [FacebookAgent uploadImage] in the else case on line 213:
    else {
    if(uploadImageAlbum){
    [params setValue:uploadImageAlbum forKey:@"aid"];
    }
    }
    I have tried all uploading-methods, and problem exists on all of them, the publishfeed-stuff works though.
    Does it work on your device?

    Problem 2.)
    The TwitterAgent should save username and password and fill the fields the next time, and I can see in the code that it writes to file and saves them. This also works flawlessly in the Simulator 3.1.2 | Debug, but not on the Device 3.1.2 | Debug. On the device, nothing is filled into the fields the next time the app runs.

    I will let you know if I find any solutions, but I haven't managed to find any the last two hours.
  • danbaumbach
    I found some problems where he declared an NSDictionary and then tried to add to it. I changed it to NSMutableDictionary and that fixed it.
  • dev
    I may be seeing the same issue. Whereabouts in the source do I need to change from NSDictionary to NSMutableDictionary?
  • its near line 202 in FacebookAgent.m.

    -(void)uploadImage{
    NSDictionary *params;
    ---
    change NSDictionary to NSMutableDictionary.

    -----
  • danbaumbach
    I don't remember and I took out the code because I couldn't get it to do what I wanted. It's Facebook Connect and not FBAgent that doesn't allow me to do what I want.

    You'll have to trace through the code and see where the crash occurs. It's where they are trying to add an entry to an NSDictionary rather than an NSMutableDictionary.

    BTW, it doesn't matter what you call the photo album, if any, because FB ends up using the name of your registered Facebook app and not the name you entered.

    - Dan.
  • Transton
    I took a closer look now danbaumbach and you are absolutely right, good work! The problem lies within the uploadImage method in FacebookAgent.m. As we can see he is trying to set values in a NSDictionary. You can keep the NSDictionary with some slight modifications or you can switch to NSMutableDictionary also with some slight modifications. Problem solved!
  • U guys rock! thanks all for helping :)
  • hey danbaumbach! Thanks a lot!! After writing these classes, I could not test these agents on iphone/ipod yet.
  • Dan Baumbach
    I'm using uploadPhotoAsData and a photo gets uploaded to an album and my status is updated. However in Facebook they appear in two separate posts. If I were to just go to facebook and in the add a comment plus upload a photo, they get posted in the same status post.

    Is there a way to do this with FBAgent or even with Facebook Connect?

    Thanks.

    - Dan.
  • Dan Baumbach
    I've been looking more carefully at the Facebook API and there doesn't appear a way to do this. You can upload a photo and you can change status but you can't post a photo as part of a status update even though you can do it on Facebook on the web.
  • yea, u r right. Please share if you get any clue to do so. Thanks.
  • danbaumbach
    You can't do upload a photo with status on Facebook's iPhone app either. When you do it through Facebook on the web, the photo get's put in a Wall Photos album. However when you do it with Facebook Connect, it gets put in an album named after the app that you registered with Facebook. The API apparently ignores the albumName parameter.
  • Also whenever I click the 'x' or 'cancel' button on the fbconnect login screen it just keeps re-opening the login.
  • I could not reproduce this... Please download again, I've uploaded the latest code.

    is it still happening?
  • I already had my own FBConnect files, so I replaced them with the ones you had in the project, same thing. It keeps reopenning if you click cancel. and I have the latest version
  • What about a session resume method?
  • before calling, add this line.

    fbAgent.shouldResumeSession = YES;
  • It crashes

    -[FacebookAgent setShouldResumeSession:]: unrecognized selector sent to instance 0x4a13d10'
  • I did before, the funny thing is i see the method for it in the facebookagent.h and I guess its not working when I call it?
  • Have you tried and used every method?
  • yea, but still full testing was not done.

    Please check this project. http://www.amanpages.com/wordpress/wp-content/u...

    Here I published a feed with no problem.

    I first removed/deleted any Fbconnect sources. and then adde the FaceBook Agent folder to the project. It has fbconnect inside with some editing.

    However, now when i want to change status getting this error:
    "Error(102) Session key invalid or no longer valid"
    Googling revealed it was a bug : http://forum.developers.facebook.com/viewtopic....

    any idea?
  • Well I was using it without your FacebookAgent class's before to publish status's etc. I just liked how your Project was set up so I wanted to use it.
  • I really appreciate your support. Can you publish feed now? is the login screen is appearing again and again?

    I share the code because I also like to use other piece of work if suits my need. So, just wanted to contribute to the community.
  • Ok well first off, I really appreciate everything you've tried to help me with. And I fixed one Problem. So since I had FBConnect before, I had the header search paths, etc. I took them out, replaced all my FB Connect Files, and it finally worked. Now the only thing that doesn't work is that the Cancel button reopens the Login. So I'm trying to fix that as we speak :)
  • Thanks a lot. Now I am at my day job, so can't work on it by next 6 hours.. so I will really appreciate if you share your fix or suggestion :)
  • No but if you press Login you go to the publish feed page, its just when you click cancel.
blog comments powered by Disqus