我正在寻找使用 Facebook Api 在 iOS 应用程序中签入用户。
我想知道我是否在 AppDelegate 中设置了权限,但希望用户从不同的视图控制器签入,我是否必须在每个视图控制器中声明 Facebook 实例以及 FBRequestDelegate、FBSessionDelegate、FBDialogDelegate 委托方法?还是 AppDelegate 中的一次性事情?
谢谢你的帮助。
我正在寻找使用 Facebook Api 在 iOS 应用程序中签入用户。
我想知道我是否在 AppDelegate 中设置了权限,但希望用户从不同的视图控制器签入,我是否必须在每个视图控制器中声明 Facebook 实例以及 FBRequestDelegate、FBSessionDelegate、FBDialogDelegate 委托方法?还是 AppDelegate 中的一次性事情?
谢谢你的帮助。
我刚刚处理了完全相同的问题。这是我的解决方案:
我创建了一个FBRequestWrapper,它基本上包含以下方法:
#import <Foundation/Foundation.h>
#import "Facebook.h"
#define FB_APP_ID @"xx"
#define FB_APP_SECRET @"xx"
@interface FBRequestWrapper : NSObject <FBRequestDelegate, FBSessionDelegate>
{
Facebook *facebook;
BOOL isLoggedIn;
}
@property (nonatomic, retain) Facebook *facebook;
@property (nonatomic, assign) BOOL isLoggedIn;
+ (id) defaultManager;
- (void) setIsLoggedIn:(BOOL) _loggedIn;
- (void) FBSessionBegin:(id) _delegate;
- (void) FBLogout;
- (void) getFBRequestWithGraphPath:(NSString*) _path andDelegate:(id) _delegate;
- (void) sendFBRequestWithGraphPath:(NSString*) _path params:(NSMutableDictionary*) _params andDelegate:(id) _delegate;
@end
所以所有 Facebook 的东西都在这个 Singleton 类中管理。
在我的AppDelegate 中,我调用了 authentication。因为在我看来,必须在加载所有控制器之前完成身份验证。
// FACEBOOK
requestWrapper = [FBRequestWrapper defaultManager];
BOOL loggedIn = [requestWrapper isLoggedIn];
// if the user is not currently logged in begin the session
if (!loggedIn) {
[requestWrapper FBSessionBegin:(id)self];
} else {
NSLog(@"Is already logged in!");
}
// Check if the access token is already there. In that case the user is already authenticated with facebook.
// Directly load the controllers and do not wait till facebook has returned back the access_token
if([[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"] != nil &&
[[NSUserDefaults standardUserDefaults] objectForKey:@"exp_date"] != nil) {
[self loadControllers];
}
可以看到我也将 accessToken 存储在 NSUserDefaults 空间中。因为我们使用 accessToken 作为我们的 web 服务的身份验证。
我的 AppDelegate 方法委托 FBSessionDelegate 方法:
@interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate, FBSessionDelegate>
这是最重要的方法fbDidLogin的实现:
- (void) fbDidLogin {
NSLog(@"AccessToken: %@", requestWrapper.facebook.accessToken);
[[NSUserDefaults standardUserDefaults] setObject:requestWrapper.facebook.accessToken forKey:@"access_token"];
[[NSUserDefaults standardUserDefaults] setObject:requestWrapper.facebook.expirationDate forKey:@"exp_date"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self loadControllers];
}
在这里,我将 accesstoken 存储在 NSUserDefaults 中,如果一切正常,则加载所有控制器。
现在,如果您想从 AppDelegate 之外的任何控制器访问 Facebook Graph Api,您也可以像这样使用 FBRequestWrapper:
- (IBAction)test:(id)sender {
// FBRequestWrapper
NSString *graphPath = @"me/friends";
[[FBRequestWrapper defaultManager] getFBRequestWithGraphPath:graphPath andDelegate:self];
}
这里是来自 FBRequestWrapper.m 的代码:
#import "FBRequestWrapper.h"
static FBRequestWrapper *defaultWrapper = nil;
@implementation FBRequestWrapper
@synthesize isLoggedIn, facebook;
+ (id) defaultManager {
if (!defaultWrapper)
defaultWrapper = [[FBRequestWrapper alloc] init];
return defaultWrapper;
}
- (void) setIsLoggedIn:(BOOL) _loggedIn {
isLoggedIn = _loggedIn;
if (isLoggedIn) {
[[NSUserDefaults standardUserDefaults] setObject:facebook.accessToken forKey:@"access_token"];
[[NSUserDefaults standardUserDefaults] setObject:facebook.expirationDate forKey:@"exp_date"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else {
[[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"access_token"];
[[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"exp_date"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
- (void) FBSessionBegin:(id) _delegate {
if (facebook == nil) {
facebook = [[Facebook alloc] initWithAppId:FB_APP_ID andDelegate:_delegate];
[facebook setSessionDelegate:_delegate];
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"];
NSDate *exp = [[NSUserDefaults standardUserDefaults] objectForKey:@"exp_date"];
if (token != nil && exp != nil && [token length] > 2) {
isLoggedIn = YES;
facebook.accessToken = token;
facebook.expirationDate = [NSDate distantFuture];
[self setIsLoggedIn:isLoggedIn];
NSLog(@"Access token: %@", facebook.accessToken);
}
}
if(![facebook isSessionValid]) {
NSArray *permissions = [NSArray arrayWithObjects:@"offline_access", @"read_friendlists", @"user_about_me", nil];
// if no session is available login
[facebook authorize:permissions];
}
}
- (void) FBLogout {
[[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"access_token"];
[[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"exp_date"];
[[NSUserDefaults standardUserDefaults] synchronize];
[facebook logout:self];
}
// Make simple requests
- (void) getFBRequestWithGraphPath:(NSString*) _path andDelegate:(id) _delegate {
if (_path != nil) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
if (_delegate == nil)
_delegate = self;
if(isLoggedIn) {
NSLog(@"is logged in in the get method");
} else {
NSLog(@"Is NOT logged in the get metthod");
}
[facebook requestWithGraphPath:_path andDelegate:_delegate];
}
}
// Used for publishing
- (void) sendFBRequestWithGraphPath:(NSString*) _path params:(NSMutableDictionary*) _params andDelegate:(id) _delegate {
if (_delegate == nil)
_delegate = self;
if (_params != nil && _path != nil) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[facebook requestWithGraphPath:_path andParams:_params andHttpMethod:@"POST" andDelegate:_delegate];
}
}
#pragma mark -
#pragma mark FacebookSessionDelegate
- (void)fbDidLogin {
isLoggedIn = YES;
[[NSUserDefaults standardUserDefaults] setObject:facebook.accessToken forKey:@"access_token"];
[[NSUserDefaults standardUserDefaults] setObject:facebook.expirationDate forKey:@"exp_date"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)fbDidNotLogin:(BOOL)cancelled {
isLoggedIn = NO;
}
- (void)fbDidLogout {
[[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"access_token"];
[[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"exp_date"];
[[NSUserDefaults standardUserDefaults] synchronize];
isLoggedIn = NO;
}
#pragma mark -
#pragma mark FBRequestDelegate
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
//NSLog(@"ResponseFailed: %@", error);
}
- (void)request:(FBRequest *)request didLoad:(id)result {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
//NSLog(@"Parsed Response: %@", result);
}
/**
* Called after the access token was extended. If your application has any
* references to the previous access token (for example, if your application
* stores the previous access token in persistent storage), your application
* should overwrite the old access token with the new one in this method.
* See extendAccessToken for more details.
*/
- (void)fbDidExtendToken:(NSString*)accessToken expiresAt:(NSDate*)expiresAt {
NSLog(@"Fb did extend token.. NOT IMPLEMENTED YET!");
}
/**
* Called when the current session has expired. This might happen when:
* - the access token expired
* - the app has been disabled
* - the user revoked the app's permissions
* - the user changed his or her password
*/
- (void)fbSessionInvalidated {
NSLog(@"Fb session invalidated.. NOT IMPLEMENTED YET!");
}
@end