Example Facebook Login

This is a working example of implementing login and registering of a user using Facebook via the FB SDK to login to the Vouchr server.

Implementation steps:

  1. Implement VOAuthClient.
  2. Login with Facebook and get an access token and userid.
  3. Fetch the rest of the user from Facebook with a Graph request and convert it to a SimpleUser.
  4. Create a Credential with the information from Facebook.
  5. Call login on VouchrEngine‘s UserManager with the Credential.

Source code:

#import "FacebookManager.h"

#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <VouchrSDK/VouchrSDK.h>

@interface FacebookManager () <VOAuthClient>

@property (nonatomic, strong) FBSDKLoginManager *fbSDKLoginManager;
@property (nonatomic, strong) VouchrEngine *vouchrEngineSDK;
@property (nonatomic, strong) SimpleUser *simpleUser;

@end

@implementation FacebookManager

+ (instancetype)instance {
    static FacebookManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup {
    self.vouchrEngineSDK = [VouchrEngine instance];
    self.fbSDKLoginManager = [FBSDKLoginManager new];
}

#pragma mark - VOAuthClient

// Implementation step 1
// pass the simple user in that is set from the result info from Facebook
- (void)userForRegistrationWithCredential:(Credential *)credential onSuccess:(void (^)(Credential *, SimpleUser *))onSuccess onError:(void (^)(NSError *))onError {
    if (onSuccess) {
        onSuccess(credential, self.simpleUser);
    }
}

// Get the credential from FBSDK and callback with it
- (void)refreshTokenOnSuccess:(void(^)(Credential *credentials))onSucceed
                      onError:(void(^)(NSError *error))onError {
    if ([FBSDKAccessToken currentAccessToken]) {
        Credential *cred = [Credential credentialWithNetworkId:[FBSDKAccessToken currentAccessToken].userID network:@"facebook" accessToken:[FBSDKAccessToken currentAccessToken].tokenString];
        onSucceed(cred);
    }else {
        NSError *error = [NSError errorWithDomain:@"com.surpriise.surpriise.FacebookManager" code:0 userInfo:nil];
        onError(error);
    }
}

- (void)logout {
    [self.fbSDKLoginManager logOut];
}

- (void)loginFromViewController:(UIViewController *)viewController
                      onSuccess:(void (^)(void))onSucceed
                        onError:(void (^)(NSError *))onError {
    // Implementation step 2
    [self.fbSDKLoginManager logInWithReadPermissions:@[@"email", @"user_birthday", @"public_profile"]
                                  fromViewController:viewController
                                             handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
                                                 if (result.token) {
                                                     [self fetchMeInfoOnCompletion:^(NSDictionary *result, NSError *error) {
                                                         if (!error) {
                                                             [self loginToVouchrServerWithResult:result onSuccess:onSucceed onError:onError];
                                                         } else if (onError) {
                                                             onError(error);
                                                         }
                                                     }];
                                                 } else if (onError) {
                                                     onError(error);
                                                 }
                                             }];
}

- (void)fetchMeInfoOnCompletion:(void(^)(NSDictionary *result, NSError *error))completion {
    // Implementation step 3
    FBSDKGraphRequest * request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"/me" parameters:@{@"fields":@"id,first_name,last_name,gender,birthday,email"}];
    [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
        completion(result,error);
    }];
}

- (void)loginToVouchrServerWithResult:(NSDictionary *)result
                            onSuccess:(void (^)(void))onSucceed
                              onError:(void (^)(NSError *))onError {
    NSString *facebookId = [result valueForKey:@"id"];
    // Implementation step 4
    Credential *credential = [Credential credentialWithNetworkId:facebookId
                                                         network:@"facebook"
                                                     accessToken:[FBSDKAccessToken currentAccessToken].tokenString];
    NSString *photoUrl = [[NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large&return_ssl_resources=1", facebookId]] absoluteString];
    self.simpleUser = [SimpleUser simpleUserWithFirstName:result[@"first_name"] lastName:result[@"last_name"] email:result[@"email"] profileImageUrl:photoUrl birthday:result[@"birthday"]];

    // Implementation step 5 
    [[self.vouchrEngineSDK userManager] loginWithCredentials:credential
                                                  authClient:self
                                                   onSuccess:^(User *user) {
                                                       if (onSucceed) {
                                                           onSucceed();
                                                       }
                                                   } onError:onError];
}

@end