1

Facebook API を使用して、iOS アプリでユーザーをチェックインしようとしています。

AppDelegate にアクセス許可を設定しているが、ユーザーが別のビュー コントローラーからチェックインできるようにしたい場合、FBRequestDelegate、FBSessionDelegate、FBDialogDelegate デリゲート メソッドと共にすべてのビュー コントローラーで Facebook インスタンスを宣言する必要がありますか? それともAppDelegateで一度だけですか?

助けてくれてありがとう。

4

1 に答える 1

2

まったく同じ問題に対処しました。これが私の解決策です:

基本的に次のメソッドを含む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 のものは、このシングルトン クラスで管理されます。

私の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 スペースに保存していることがわかります。Web サービスへの認証として accessToken を使用しているためです。

私の 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
于 2012-04-12T14:58:40.910 に答える