I’m trying to create a connection to Facebook however I’m having an issue with the handling of the openUrl.
In the past I’ve been able to add the following in my app delegate class:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [[viewController facebook] handleOpenURL:url];
}
Which has worked as I would expect. However, this time I have a slightly different situation in the sense that the viewController is loaded elsewhere in the app. To get around this problem I came up with an idea of creating a new class that is responsible for handling the connection, but can also be accessed from the class where I create the Facebook post.
To explain further here is the relevant code in my app delegate class
.m
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
FacebookConnectionHandler *fbConnHandler = [[FacebookConnectionHandler alloc] init];
return [[fbConnHandler facebook] handleOpenURL:url];
}
Then here is the code in the FacebookConnectionHandler class:
.h
#import <Foundation/Foundation.h>
#import "Other_ViewController.h"
#import "Facebook.h"
@interface FacebookConnectionHandler : NSObject <FBSessionDelegate>
{
Other_ViewController *otherView;
Facebook *facebook;
}
@property(nonatomic, strong)Other_ViewController *otherView;
@property(nonatomic, strong)Facebook *facebook;
+ (id)sharedManager;
@end
.m
#import "FacebookConnectionHandler.h"
@implementation FacebookConnectionHandler
@synthesize otherView;
@synthesize facebook;
static FacebookConnectionHandler *mySingleton = nil;
+ (id)sharedManager
{
@synchronized(self)
{
if (mySingleton == nil) mySingleton = [[self alloc] init];
}
return mySingleton;
}
- (void)fbDidLogin
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
[defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
[defaults synchronize];
// Allow the user to create a post
[self.otherView createFacebookPost];
}
@end
Finally… here is the relevant code in the Other_ViewController class (where the post is being created):
.h
#import "FBConnect.h"
@interface Other_ViewController : UIViewController <FBSessionDelegate>
{
Facebook *facebook;
}
@property(nonatomic, retain)Facebook *facebook;
- (void)createFacebookPost;
@end
.m
- (void)createFacebookPost
{
// Create the post
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Blah", @"name",
@"", @"caption",
@"", @"description",
@"http://www.xyz.com", @"link",
@"", @"picture",
nil];
// Post it to the users feed
[facebook dialog:@"feed" andParams:params andDelegate:nil];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (buttonIndex)
{
case kFacebookButton:
{
if (facebook == nil || ![facebook isSessionValid])
{
// Setup Facebook connection
facebook = [[Facebook alloc] initWithAppId:@"1111111111" andDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]
&& [defaults objectForKey:@"FBExpirationDateKey"])
{
facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
}
// Set the connection handler
FacebookConnectionHandler *fbConnectionHandler = [[FacebookConnectionHandler alloc] init];
fbConnectionHandler.mapView = self;
fbConnectionHandler.facebook = self.facebook;
if (![facebook isSessionValid])
{
NSArray *permissions = [[NSArray alloc] initWithObjects:@"publish_actions", nil];
[facebook authorize:permissions];
}
}
else
{
// Create the post
[self createFacebookPost];
}
break;
}
default:
break;
}
}
I may be going about this in completely the wrong way and have completely overcomplicated the problem, however I’m new to the whole facebook SDK and at this point I’m really stumped. Please can someone offer a solution?
Note: To be clear, the issue is that the method fbDidLogin is not being called, thus the rest of the code doesn’t get a chance to run.
You’re not using your singleton in the app delegate, you’re creating a new instance of your connect handler class :
Instead of
try
You’re also not using the singleton in your
Other_ViewControllerclass.If you are going to have the singleton architecture pattern you have to remember to always use the
sharedManagerand never alloc/init a new one 🙂I sometimes make
initthrow an exception to remind me that there is a singleton method.PS Using a separate Facebook class is exactly the way I’ve done it in apps I’ve written before – your architecture is fine 🙂 I would also consider making the Facebook connection hander class responsible for making it’s own Facebook instance instead of the view controller having to do it 🙂