Facebook connect from iPhone app
I am trying to integrate Facebook connect to my iPhone app but I have an error (code 10000):
did fail: The operation couldn’t be completed. (facebookErrDomain error 10000.)
When I try to update my wall. The code seems pretty simple (I had to struggle to find some doc though).
- (void)viewDidLoad {
[super viewDidLoad];
// Permissions
NSArray *permissions = [[NSArray arrayWithObjects:@"publish_stream",@"read_stream",@"offline_access",nil] retain];
// Connection
Facebook *facebook = [[Facebook alloc] init];
[facebook authorize:@"MY_APP_ID" permissions:permissions delegate:self];
// Update my wall
NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"MY_API_KEY", @"api_key", @"test", @"message", nil];
[facebook requestWithGraphPath:@"me/home" andParams:params andHttpMethod:开发者_开发技巧@"POST" andDelegate:self];
}
// FBRequestDelegate
- (void)request:(FBRequest*)request didLoad:(id)result {
NSArray* users = result;
NSDictionary* user = [users objectAtIndex:0];
NSString* name = [user objectForKey:@"name"];
NSLog(@"Query returned %@", name);
}
- (void)request:(FBRequest*)request didFailWithError:(NSError*)error {
NSLog(@"did fail: %@", [error localizedDescription]);
}
- (void)request:(FBRequest*)request didReceiveResponse:(NSURLResponse*)response {
NSLog(@"did r response");
}
Cannot really figure out what is wrong.
Thanks a lot,
Luc
I think I figured it out, I used to have the same issue. Your issue should be solved if you authenticate first with the right permissions and make sure you actually get to accept the needed permissions (publish_stream). Make sure you actually get to press the "allow" button. In your current code you won't see it, because you immediately try to post a message after authenticating, yet authentication isn't yet completed. As a result you most likely don't have a valid accessToken, preventing you to post messages to the wall.
// you perform authorization, but you don't wait for the user to accept the publish permission
[facebook authorize:@"MY_APP_ID" permissions:permissions delegate:self];
// you attempt to publish, but you don't have the permission to publish yet ...
NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"MY_API_KEY", @"api_key", @"test", @"message", nil];
[facebook requestWithGraphPath:@"me/home" andParams:params andHttpMethod:@"POST" andDelegate:self];
How to fix this issue?
This is the way I fixed it (please note DLog() is a macro for NSLog()):
/* The operationQueue array is used to keep track of operations that need to be
completed in order (e.g. if we aren't logged in when we want to post, first
log in, then post - this way we'll make sure we always have a valid
accessToken. */
- (id)initWithDelegate:(id <ServiceDelegate>)serviceDelegate
{
self = [super init];
if (self)
{
[self setDelegate:serviceDelegate];
userId = nil;
operationQueue = [[NSMutableArray alloc] init];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
facebook = appDelegate.facebook;
}
return self;
}
- (id)init
{
return [self initWithDelegate:nil];
}
- (void)dealloc
{
[operationQueue release];
[super dealloc];
}
#pragma mark - Instance methods
- (void)login
{
if (![facebook isSessionValid]) {
SEL authorizationSelector = @selector(performAuthorization);
NSValue *selector = [NSValue valueWithPointer:authorizationSelector];
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:selector forKey:@"selector"];
[operationQueue addObject:dictionary];
[self runOperations];
}
}
- (void)logout
{
SEL logoutSelector = @selector(performLogout);
NSValue *selector = [NSValue valueWithPointer:logoutSelector];
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:selector forKey:@"selector"];
[operationQueue addObject:dictionary];
[self runOperations];
}
- (void)postMessage:(NSString *)message
{
NSArray *objects = [NSArray arrayWithObjects:message, nil];
NSArray *keys = [NSArray arrayWithObjects:@"message", nil];
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjects:objects forKeys:keys];
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:parameters forKey:@"parameters"];
SEL postMessageSelector = @selector(performPostMessageWithDictionary:);
NSValue *selector = [NSValue valueWithPointer:postMessageSelector];
NSDictionary *operationDictionary = [NSDictionary dictionaryWithObjectsAndKeys:selector, @"selector", dictionary, @"parameters", nil];
[operationQueue addObject:operationDictionary];
if (![facebook isSessionValid]) {
[self performSelectorOnMainThread:@selector(performAuthorization) withObject:nil waitUntilDone:NO];
} else {
[self runOperations];
}
}
#pragma mark - Private methods
- (void)runOperations
{
DLog(@"running operations ...");
for (NSDictionary *operationDictionary in operationQueue) {
NSValue *value = [operationDictionary objectForKey:@"selector"];
SEL selector = [value pointerValue];
NSDictionary *parameters = [operationDictionary objectForKey:@"parameters"];
[self performSelectorOnMainThread:selector withObject:parameters waitUntilDone:YES];
}
[operationQueue removeAllObjects];
}
- (void)performLogout {
[facebook logout:self];
}
- (void)performAuthorization {
NSArray *permissions = [NSArray arrayWithObject:@"publish_stream"];
[facebook authorize:permissions delegate:self];
}
- (void)performPostMessageWithDictionary:(NSDictionary *)dictionary {
NSMutableDictionary *parameters = [dictionary objectForKey:@"parameters"];
NSString *encodedToken = [facebook.accessToken stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *graphPath = [NSString stringWithFormat:@"me/feed?access_token=%@", encodedToken];
FBRequest *request = [facebook requestWithGraphPath:graphPath
andParams:parameters
andHttpMethod:@"POST"
andDelegate:self];
if (!request) {
DLog(@"error occured when trying to create FBRequest object with graph path : %@", graphPath);
}
}
/* make sure your interface conforms to the FBRequestDelegate protocol for
extra debug information, but this is not required */
#pragma mark - Facebook request delegate
- (void)requestLoading:(FBRequest *)request
{
DLog(@"requestLoading:");
}
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response
{
DLog(@"request:didReceiveResponse:");
}
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error
{
DLog(@"error occured when trying to perform request to Facebook : %@", error);
}
- (void)request:(FBRequest *)request didLoad:(id)result
{
DLog(@"request:didLoad: %@", result);
}
- (void)request:(FBRequest *)request didLoadRawResponse:(NSData *)data
{
DLog(@"request:didLoadRawResponse");
}
/* make sure your interface conforms to the FBSessionDelegate protocol! */
#pragma mark - Facebook session delegate
/* if there are still operations in the queue that need to be completed,
continue executing the operations, otherwise inform out delegate that login
is completed ... */
- (void)fbDidLogin
{
if ([operationQueue count] > 0) {
[self runOperations];
}
if ([self.delegate respondsToSelector:@selector(serviceDidLogin:)])
{
[self.delegate serviceDidLogin:self];
}
}
- (void)fbDidNotLogin:(BOOL)cancelled
{
if ([self.delegate respondsToSelector:@selector(serviceLoginFailed:)])
{
[self.delegate serviceLoginFailed:self];
}
}
- (void)fbDidLogout
{
if ([self.delegate respondsToSelector:@selector(serviceDidLogout:)])
{
[self.delegate serviceDidLogout:self];
}
}
Make sure you have declared your app's API key.
精彩评论