Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // FacebookService.m
- // NineSpot
- //
- // Created by Nick Dalton on 11/28/14.
- // Copyright (c) 2014 NineSpot. All rights reserved.
- //
- #import <FacebookSDK/FacebookSDK.h>
- #import <CommonCrypto/CommonCrypto.h>
- #import "FacebookService.h"
- #import "AppDelegate.h"
- #import "EndUser.h"
- NSString *const kNotificationLoginFacebookSuccess = @"NotificationLoginFacebookSuccess";
- @implementation FacebookService
- #pragma mark - AppDelegate handlers
- - (BOOL)handleOpenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
- {
- return [FBAppCall handleOpenURL:url
- sourceApplication:sourceApplication
- fallbackHandler:^(FBAppCall *call) {
- DDLogDebug(@"In fallback handler");
- }];
- }
- - (void)handleApplicationDidBecomeActive
- {
- // Call the 'activateApp' method to log an app event for use in analytics and advertising reporting.
- [FBAppEvents activateApp];
- // We need to properly handle activation of the application with regards to SSO
- // (e.g., returning from iOS 6.0 authorization dialog or from fast app switching).
- [FBAppCall handleDidBecomeActive];
- }
- - (void)handleApplicationWillTerminate
- {
- // If the app is going away, we close the session object.
- [FBSession.activeSession close];
- }
- #pragma mark - Facebook session
- - (BOOL)isSessionOpen
- {
- BOOL isOpen = FBSession.activeSession.isOpen;
- DDLogDebug(@"Facebook Session is %@", isOpen ? @"open" : @"not open");
- DDLogDebug(@"Facebook access token expires: %@", FBSession.activeSession.accessTokenData.expirationDate);
- return isOpen;
- }
- - (void)openSessionFromTokenCache
- {
- DDLogDebug(@"Facebook openSessionFromTokenCache");
- // Try to open a Facebook session from a token cache
- if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
- // Yes, so just open the session (this won't display any UX).
- [FBSession openActiveSessionWithReadPermissions:@[@"public_profile", @"email"]
- allowLoginUI:NO
- completionHandler:^(FBSession *session,
- FBSessionState status,
- NSError *error) {
- // Respond to session state changes
- [self facebookSessionStateChanged:session state:status error:error];
- }];
- }
- }
- - (void)login
- {
- DDLogDebug(@"Facebook login");
- [FBSession openActiveSessionWithReadPermissions:@[@"public_profile", @"email"]
- allowLoginUI:YES
- completionHandler:^(FBSession *session,
- FBSessionState status,
- NSError *error) {
- // Respond to session state changes
- [self facebookSessionStateChanged:session state:status error:error];
- }];
- }
- - (void)logout
- {
- DDLogDebug(@"Facebook logout");
- [FBSession.activeSession closeAndClearTokenInformation];
- }
- - (void)facebookSessionStateChanged:(FBSession *)session
- state:(FBSessionState) state
- error:(NSError *)error
- {
- DDLogDebug(@"FBSessionState changed to: %lu", (unsigned long)state);
- // Capture demographic data
- if ([session isOpen]) {
- [[FBRequest requestForMe] startWithCompletionHandler:
- ^(FBRequestConnection *connection,
- NSDictionary<FBGraphUser> *user,
- NSError *connectionError) {
- if (!connectionError) {
- DDLogDebug(@"FBGraphUser: %@", user);
- EndUser *endUser = [self endUserFromFacebookUser:user];
- [ApplicationDelegate.webService saveEndUser:endUser];
- [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationLoginFacebookSuccess object:endUser];
- } else {
- DDLogError(@"Error in FBRequest requestForMe: %@", [connectionError localizedDescription]);
- }
- }];
- }
- }
- #pragma mark - EndUser helper methods
- - (EndUser *)endUserFromFacebookUser:(id<FBGraphUser>)user
- {
- EndUser *endUser = [[EndUser alloc] init];
- endUser.name = user.name;
- endUser.emailAddress = [user objectForKey:@"email"];
- endUser.userId = user.objectID;
- NSString *genderString = [user objectForKey:@"gender"];
- if (genderString) {
- NSString *genderCharacter = [[genderString substringToIndex:1] uppercaseString];
- endUser.gender = genderCharacter;
- }
- endUser.accessToken = FBSession.activeSession.accessTokenData.accessToken;
- endUser.password = [self generatedPasswordForFacebookUser:user];
- endUser.isFacebookUser = YES;
- // Get profile picture
- [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *FBuser, NSError *error) {
- if (error) {
- DDLogError(@"Error fetching Facebook profile picture: %@", [error localizedDescription]);
- } else {
- NSString *urlString = [NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=normal", [FBuser objectID]];
- if (urlString) {
- @try {
- endUser.mediumThumbnailURL = [NSURL URLWithString:urlString];
- [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationEndUserUpdated object:endUser];
- }
- @catch (NSException *exception) {
- DDLogError(@"Error cretating URL for Facebook thumbnail %@ : %@", urlString, [exception description]);
- }
- }
- }
- }];
- return endUser;
- }
- - (NSString *)generatedPasswordForFacebookUser:(id<FBGraphUser>)user
- {
- NSString *password = nil;
- NSString *userId = user.objectID;
- if (userId) {
- NSString *hash = [self computeSHA256DigestForString:userId withSalt:@"42"];
- NSString *trimmedHash = [hash substringToIndex:16];
- password = [NSString stringWithFormat:@"fb%@.", trimmedHash];
- }
- return password;
- }
- - (NSString *)computeSHA256DigestForString:(NSString *)input
- {
- const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
- NSData *data = [NSData dataWithBytes:cstr length:input.length];
- uint8_t digest[CC_SHA256_DIGEST_LENGTH];
- CC_SHA256(data.bytes, (unsigned int)data.length, digest);
- NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
- for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
- [output appendFormat:@"%02x", digest[i]];
- }
- return output;
- }
- - (NSString *)computeSHA256DigestForString:(NSString *)input withSalt:(NSString *)salt
- {
- const char *cData = [input cStringUsingEncoding:NSUTF8StringEncoding];
- const char *cKey = [salt cStringUsingEncoding:NSUTF8StringEncoding];
- uint8_t cHMAC[CC_SHA256_DIGEST_LENGTH];
- CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
- NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
- for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
- [output appendFormat:@"%02x", cHMAC[i]];
- }
- return output;
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement