| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083 |
- // Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
- //
- // You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
- // copy, modify, and distribute this software in source code or binary form for use
- // in connection with the web services and APIs provided by Facebook.
- //
- // As with any software that integrates with the Facebook platform, your use of
- // this software is subject to the Facebook Developer Principles and Policies
- // [http://developers.facebook.com/policy/]. This copyright notice shall be
- // included in all copies or substantial portions of the software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- #import <SafariServices/SafariServices.h>
- #import <AuthenticationServices/AuthenticationServices.h>
- #import <FBSDKCoreKit/FBSDKCoreKit-Swift.h>
- #import <FBSDKLoginKit/FBSDKLoginKit-Swift.h>
- #import <Foundation/NSJSONSerialization.h>
- #include "FBUnityInterface.h"
- #include "FBUnitySDKDelegate.h"
- #include "FBUnityUtility.h"
- #include "FBSDK+Internal.h"
- static BOOL _fastAppSwitchEnabled = NO;
- @interface FBUnityInterface()
- @property (nonatomic, copy) NSString *openURLString;
- // Declared explicitly so @selector(...) resolves under the Swift Xcode project type, where these
- // are no longer inherited from the AppDelegateListener protocol.
- - (void)didFinishLaunching:(NSNotification *)notification;
- - (void)didBecomeActive:(NSNotification *)notification;
- #if UNITY_XCODE_PROJECT_TYPE_SWIFT
- // Swift-only: no AppDelegateListener counterpart to inherit this from.
- - (void)onSceneOpenURLContexts:(NSNotification *)notification;
- #endif
- @end
- @implementation FBUnityInterface
- #pragma mark Object Initialization
- + (FBUnityInterface *)sharedInstance
- {
- static dispatch_once_t pred;
- static FBUnityInterface *shared = nil;
- dispatch_once(&pred, ^{
- shared = [[FBUnityInterface alloc] init];
- shared.shareDialogMode = ShareDialogMode::AUTOMATIC;
- });
- return shared;
- }
- + (void)load
- {
- #if UNITY_XCODE_PROJECT_TYPE_SWIFT
- [[FBUnityInterface sharedInstance] registerForLifecycleNotifications];
- #else
- UnityRegisterAppDelegateListener([FBUnityInterface sharedInstance]);
- #endif
- }
- #pragma mark - App (Delegate) Lifecycle
- // Under the Objective-C Xcode project type, didBecomeActive: and onOpenURL: are called by Unity's
- // AppController because we implement <AppDelegateListener> and registered via
- // UnityRegisterAppDelegateListener(...) above. The Swift project type has no AppDelegateListener,
- // so the same methods are driven from NotificationCenter instead.
- #if UNITY_XCODE_PROJECT_TYPE_SWIFT
- - (void)registerForLifecycleNotifications
- {
- NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
- [center addObserver:self
- selector:@selector(didFinishLaunching:)
- name:UIApplicationDidFinishLaunchingNotification
- object:nil];
- [center addObserver:self
- selector:@selector(didBecomeActive:)
- name:UIApplicationDidBecomeActiveNotification
- object:nil];
- // Literal names: the UnityNotifications Swift header exists only under the Swift project type.
- [center addObserver:self
- selector:@selector(onSceneOpenURLContexts:)
- name:@"UnitySceneOpenURLContexts"
- object:nil];
- }
- // A scene can be handed several URLs at once, so each context is offered to the SDK in turn.
- - (void)onSceneOpenURLContexts:(NSNotification *)notification
- {
- id contexts = notification.userInfo[@"UnityNotificationsOpenURLContextsKey"];
- if (![contexts isKindOfClass:[NSSet class]]) {
- return;
- }
- for (UIOpenURLContext *context in (NSSet *)contexts) {
- if (![context isKindOfClass:[UIOpenURLContext class]]) {
- continue;
- }
- // sourceApplication and annotation live on context.options here, not the notification userInfo.
- BOOL isHandledByFBSDK = [[FBSDKApplicationDelegate sharedInstance] application:[UIApplication sharedApplication]
- openURL:context.URL
- sourceApplication:context.options.sourceApplication
- annotation:context.options.annotation];
- if (!isHandledByFBSDK) {
- [FBUnityInterface sharedInstance].openURLString = [context.URL absoluteString];
- }
- }
- }
- #endif
- - (void)didFinishLaunching:(NSNotification *)notification
- {
- [[FBSDKApplicationDelegate sharedInstance] application:[UIApplication sharedApplication]
- didFinishLaunchingWithOptions:notification.userInfo];
- }
- - (void)didBecomeActive:(NSNotification *)notification
- {
- }
- - (void)onOpenURL:(NSNotification *)notification
- {
- NSURL *url = notification.userInfo[@"url"];
- BOOL isHandledByFBSDK = [[FBSDKApplicationDelegate sharedInstance] application:[UIApplication sharedApplication]
- openURL:url
- sourceApplication:notification.userInfo[@"sourceApplication"]
- annotation:notification.userInfo[@"annotation"]];
- if (!isHandledByFBSDK) {
- [FBUnityInterface sharedInstance].openURLString = [url absoluteString];
- }
- }
- #pragma mark - Implementation
- - (void)configureAppId:(const char *)appId
- frictionlessRequests:(bool)frictionlessRequests
- urlSuffix:(const char *)urlSuffix
- {
- self.useFrictionlessRequests = frictionlessRequests;
- if(appId) {
- [FBSDKSettings.sharedSettings setAppID:[FBUnityUtility stringFromCString:appId]];
- }
- if(urlSuffix && strlen(urlSuffix) > 0) {
- [FBSDKSettings.sharedSettings setAppURLSchemeSuffix:[FBUnityUtility stringFromCString:urlSuffix]];
- }
- NSDictionary *userData = [self getAccessTokenUserData] ?: @{};
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnInitComplete userData:userData requestId:0];
- }
- - (void)logInWithPublishPermissions:(int) requestId
- scope:(const char *)scope
- {
- [self startLogin:requestId scope:scope isPublishPermLogin:YES];
- }
- - (void)logInWithReadPermissions:(int) requestId
- scope:(const char *)scope
- {
- [self startLogin:requestId scope:scope isPublishPermLogin:NO];
- }
- - (void)startLogin:(int) requestId
- scope:(const char *)scope
- isPublishPermLogin:(BOOL)isPublishPermLogin
- {
- NSString *scopeStr = [FBUnityUtility stringFromCString:scope];
- NSArray *permissions = nil;
- if(scope && strlen(scope) > 0) {
- permissions = [scopeStr componentsSeparatedByString:@","];
- }
- void (^loginHandler)(FBSDKLoginManagerLoginResult *,NSError *) = ^(FBSDKLoginManagerLoginResult *result, NSError *error) {
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnLoginComplete error:error requestId:requestId];
- return;
- } else if (result.isCancelled) {
- [FBUnityUtility sendCancelToUnity:FBUnityMessageName_OnLoginComplete requestId:requestId];
- return;
- }
- if ([self tryCompleteLoginWithRequestId:requestId]) {
- return;
- } else {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnLoginComplete errorMessage:@"Unknown login error" requestId:requestId];
- }
- };
- FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
- [login logInWithPermissions:permissions
- fromViewController:nil
- handler:loginHandler];
- }
- - (void)loginWithTrackingPreference:(int)requestId
- scope:(const char *)scope
- tracking:(const char *)tracking
- nonce:(const char *)nonce
- {
- NSString *scopeStr = [FBUnityUtility stringFromCString:scope];
- NSArray *permissions = nil;
- if(scope && strlen(scope) > 0) {
- permissions = [scopeStr componentsSeparatedByString:@","];
- }
- NSString *trackingStr = [FBUnityUtility stringFromCString:tracking];
- NSString *nonceStr = nil;
- if (nonce) {
- nonceStr = [FBUnityUtility stringFromCString:nonce];
- }
- FBSDKLoginConfiguration *config;
- if (nonce) {
- config = [[FBSDKLoginConfiguration alloc] initWithPermissions:permissions tracking:([trackingStr isEqualToString:@"enabled"] ? FBSDKLoginTrackingEnabled : FBSDKLoginTrackingLimited) nonce:nonceStr appSwitch:_fastAppSwitchEnabled ? FBSDKAppSwitchEnabled : FBSDKAppSwitchDisabled];
- } else {
- config = [[FBSDKLoginConfiguration alloc] initWithPermissions:permissions tracking:([trackingStr isEqualToString:@"enabled"] ? FBSDKLoginTrackingEnabled : FBSDKLoginTrackingLimited) appSwitch:_fastAppSwitchEnabled ? FBSDKAppSwitchEnabled : FBSDKAppSwitchDisabled];
- }
- void (^loginHandler)(FBSDKLoginManagerLoginResult *,NSError *) = ^(FBSDKLoginManagerLoginResult *result, NSError *error) {
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnLoginComplete error:error requestId:requestId];
- return;
- } else if (result.isCancelled) {
- [FBUnityUtility sendCancelToUnity:FBUnityMessageName_OnLoginComplete requestId:requestId];
- return;
- }
- if ([self tryCompleteLoginWithRequestId:requestId]) {
- return;
- } else {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnLoginComplete errorMessage:@"Unknown login error" requestId:requestId];
- }
- };
- FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
- [login logInFromViewController:nil configuration:config completion:loginHandler];
- }
- - (void)logOut
- {
- FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
- [login logOut];
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnLogoutComplete userData:@{} requestId:0];
- }
- - (void)appRequestWithRequestId:(int)requestId
- message:(const char *)message
- actionType:(const char *)actionType
- objectId:(const char *)objectId
- to:(const char **)to
- toLength:(int)toLength
- filters:(const char *)filters
- data:(const char *)data
- title:(const char *)title
- {
- FBSDKGameRequestContent *content = [[FBSDKGameRequestContent alloc] init];
- content.message = [FBUnityUtility stringFromCString:message];
- content.actionType = [FBUnityUtility gameRequestActionTypeFromString:[FBUnityUtility stringFromCString:actionType]];
- content.objectID = [FBUnityUtility stringFromCString:objectId];
- if(to && toLength) {
- NSMutableArray *toArray = [NSMutableArray array];
- for(int i = 0; i < toLength; i++) {
- [toArray addObject:[FBUnityUtility stringFromCString:to[i]]];
- }
- content.recipients = toArray;
- }
- content.filters = [FBUnityUtility gameRequestFilterFromString:[FBUnityUtility stringFromCString:filters]];
- content.data = [FBUnityUtility stringFromCString:data];
- content.title = [FBUnityUtility stringFromCString:title];
- FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:requestId];
- NSError *error;
- FBSDKGameRequestDialog *dialog = [[FBSDKGameRequestDialog alloc] initWithContent:content delegate:delegate];
- dialog.isFrictionlessRequestsEnabled = self.useFrictionlessRequests;
- if (![dialog validateWithError:&error]) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnAppRequestsComplete error:error requestId:requestId];
- }
- if (![dialog show]) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnAppRequestsComplete errorMessage:@"Failed to show request dialog" requestId:requestId];
- }
- }
- - (void)shareLinkWithRequestId:(int)requestId
- contentURL:(const char *)contentURL
- contentTitle:(const char *)contentTitle
- contentDescription:(const char *)contentDescription
- photoURL:(const char *)photoURL
- {
- FBSDKShareLinkContent *linkContent = [[FBSDKShareLinkContent alloc] init];
- NSString *contentUrlStr = [FBUnityUtility stringFromCString:contentURL];
- if (contentUrlStr) {
- linkContent.contentURL = [NSURL URLWithString:contentUrlStr];
- }
- [self shareContentWithRequestId:requestId
- shareContent:linkContent
- dialogMode:[self getDialogMode]];
- }
- - (void)shareFeedWithRequestId:(int)requestId
- toId:(const char *)toID
- link:(const char *)link
- linkName:(const char *)linkName
- linkCaption:(const char *)linkCaption
- linkDescription:(const char *)linkDescription
- picture:(const char *)picture
- mediaSource:(const char *)mediaSource
- {
- FBSDKShareLinkContent *linkContent = [[FBSDKShareLinkContent alloc] init];
- NSString *contentUrlStr = [FBUnityUtility stringFromCString:link];
- if (contentUrlStr) {
- linkContent.contentURL = [NSURL URLWithString:contentUrlStr];
- }
- NSMutableDictionary *feedParameters = [[NSMutableDictionary alloc] init];
- NSString *toStr = [FBUnityUtility stringFromCString:toID];
- if (toStr) {
- [feedParameters setObject:toStr forKey:@"to"];
- }
- NSString *captionStr = [FBUnityUtility stringFromCString:linkCaption];
- if (captionStr) {
- [feedParameters setObject:captionStr forKey:@"caption"];
- }
- NSString *sourceStr = [FBUnityUtility stringFromCString:mediaSource];
- if (sourceStr) {
- [feedParameters setObject:sourceStr forKey:@"source"];
- }
- [linkContent addParameters:feedParameters bridgeOptions:FBSDKShareBridgeOptionsDefault];
- [self shareContentWithRequestId:requestId
- shareContent:linkContent
- dialogMode:FBSDKShareDialogModeFeedWeb];
- }
- - (void)shareContentWithRequestId:(int)requestId
- shareContent:(FBSDKShareLinkContent *)linkContent
- dialogMode:(FBSDKShareDialogMode)dialogMode
- {
- FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:requestId];
- FBSDKShareDialog *dialog = [[FBSDKShareDialog alloc] initWithViewController:nil
- content:linkContent
- delegate:delegate];
- dialog.mode = dialogMode;
- NSError *error;
- if (![dialog validateWithError:&error]) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnShareLinkComplete error:error requestId:requestId];
- }
- if (![dialog show]) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnShareLinkComplete errorMessage:@"Failed to show share dialog" requestId:requestId];
- }
- }
- - (FBSDKShareDialogMode)getDialogMode
- {
- switch (self.shareDialogMode) {
- case ShareDialogMode::AUTOMATIC:
- return FBSDKShareDialogModeAutomatic;
- case ShareDialogMode::NATIVE:
- return FBSDKShareDialogModeNative;
- case ShareDialogMode::WEB:
- return FBSDKShareDialogModeWeb;
- case ShareDialogMode::FEED:
- return FBSDKShareDialogModeFeedWeb;
- default:
- NSLog(@"Unexpected dialog mode: %@", [NSNumber numberWithInt:self.shareDialogMode]);
- return FBSDKShareDialogModeAutomatic;
- }
- }
- - (BOOL)tryCompleteLoginWithRequestId:(int) requestId
- {
- NSMutableDictionary *userData = [[NSMutableDictionary alloc] init];
- NSDictionary *accessTokenUserData = [self getAccessTokenUserData];
- NSDictionary *authenticationTokenUserData = [self getAuthenticationTokenUserData];
- if (accessTokenUserData) {
- [userData addEntriesFromDictionary:accessTokenUserData];
- }
- if (authenticationTokenUserData) {
- [userData addEntriesFromDictionary:authenticationTokenUserData];
- }
- if (userData) {
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnLoginComplete
- userData:[userData copy]
- requestId:requestId];
- return YES;
- } else {
- return NO;
- }
- }
- - (NSDictionary *)getAccessTokenUserData
- {
- FBSDKAccessToken *token = [FBSDKAccessToken currentAccessToken];
- if (token) {
- // Old v3 sdk tokens don't always contain a UserID. If the user ID is null
- // treat the token as bad and clear it. These values are all required
- // on c# side for initlizing a token.
- NSDictionary *userData = [FBUnityUtility getUserDataFromAccessToken:token];
- if (userData) {
- return userData;
- } else {
- // The token is missing a required value. Clear the token
- [[[FBSDKLoginManager alloc] init] logOut];
- }
- }
- return nil;
- }
- - (NSDictionary *)getAuthenticationTokenUserData
- {
- FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken currentAuthenticationToken];
- if (token.tokenString && token.nonce) {
- return @{
- @"auth_token_string": token.tokenString,
- @"auth_nonce": token.nonce
- };
- }
- return nil;
- }
- - (void)refreshLimitedLogin:(int)requestId
- fallbackPolicy:(int)fallbackPolicy
- {
- FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
- [login refreshLimitedLoginFromViewController:nil
- fallbackPolicy:(FBSDKRefreshFallbackPolicy)fallbackPolicy
- completion:^(FBSDKProfile *profile, NSError *error) {
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnRefreshLimitedLoginComplete error:error requestId:requestId];
- return;
- }
- // The refreshed Profile is cached as FBSDKProfile.currentProfile and read on
- // the C# side via FB.Mobile.CurrentProfile(). Send back the refreshed
- // authentication token so LoginResult can update AuthenticationToken.Current.
- NSMutableDictionary *userData = [[NSMutableDictionary alloc] init];
- NSDictionary *authenticationTokenUserData = [self getAuthenticationTokenUserData];
- if (authenticationTokenUserData) {
- [userData addEntriesFromDictionary:authenticationTokenUserData];
- }
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnRefreshLimitedLoginComplete
- userData:[userData copy]
- requestId:requestId];
- }];
- }
- @end
- #pragma mark - Actual Unity C# interface (extern C)
- extern "C" {
- void IOSFBSendViewHierarchy(const char *_tree )
- {
- Class FBUnityUtility = NSClassFromString(@"FBSDKCodelessIndexer");
- [FBUnityUtility performSelector:NSSelectorFromString(@"uploadIndexing:")
- withObject:[NSString stringWithUTF8String:_tree]];
- }
- void IOSFBInit(const char *_appId, bool _frictionlessRequests, const char *_urlSuffix, const char *_userAgentSuffix)
- {
- // Set the user agent before calling init to ensure that calls made during
- // init use the user agent suffix.
- [FBSDKSettings.sharedSettings setUserAgentSuffix:[FBUnityUtility stringFromCString:_userAgentSuffix]];
- [[FBUnityInterface sharedInstance] configureAppId:_appId
- frictionlessRequests:_frictionlessRequests
- urlSuffix:_urlSuffix];
- [[FBSDKAppEvents shared] setIsUnityInitialized:true];
- [[FBSDKAppEvents shared] sendEventBindingsToUnity];
- }
- void IOSFBEnableProfileUpdatesOnAccessTokenChange(bool enable)
- {
- [FBSDKProfile enableUpdatesOnAccessTokenChange:enable];
- }
- void IOSFBLoginWithTrackingPreference(int requestId, const char *scope, const char *tracking, const char *nonce)
- {
- [[FBUnityInterface sharedInstance] loginWithTrackingPreference:requestId scope:scope
- tracking:tracking
- nonce:nonce];
- }
- void IOSFBLogInWithReadPermissions(int requestId,
- const char *scope)
- {
- [[FBUnityInterface sharedInstance] logInWithReadPermissions:requestId scope:scope];
- }
- void IOSFBLogInWithPublishPermissions(int requestId,
- const char *scope)
- {
- [[FBUnityInterface sharedInstance] logInWithPublishPermissions:requestId scope:scope];
- }
- void IOSFBLogOut()
- {
- [[FBUnityInterface sharedInstance] logOut];
- }
- char* IOSFBCurrentAuthenticationToken()
- {
- FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken currentAuthenticationToken];
- NSString *str = @"";
- if (token.tokenString && token.nonce) {
- try {
- NSData *jsonData = [NSJSONSerialization dataWithJSONObject:@{
- @"auth_token_string": token.tokenString,
- @"auth_nonce": token.nonce
- } options:NSJSONWritingPrettyPrinted error:nil];
- if (jsonData) {
- str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
- }
- } catch (NSException *exception) {
- NSLog(@"Fail to parse AuthenticationToken");
- }
- }
- const char* string = [str UTF8String];
- char* res = (char*)malloc(strlen(string) + 1);
- strcpy(res, string);
- return res;
- }
- char* IOSFBCurrentProfile()
- {
- FBSDKProfile *profile = [FBSDKProfile currentProfile];
- NSString *str = @"";
- NSMutableDictionary<NSString *, id> *data = [NSMutableDictionary new];
- if (profile.userID) {
- data[@"userID"] = profile.userID;
- }
- if (profile.firstName) {
- data[@"firstName"] = profile.firstName;
- }
- if (profile.middleName) {
- data[@"middleName"] = profile.middleName;
- }
- if (profile.lastName) {
- data[@"lastName"] = profile.lastName;
- }
- if (profile.name) {
- data[@"name"] = profile.name;
- }
- if (profile.email) {
- data[@"email"] = profile.email;
- }
- if (profile.imageURL) {
- data[@"imageURL"] = profile.imageURL.absoluteString;
- }
- if (profile.linkURL) {
- data[@"linkURL"] = profile.linkURL.absoluteString;
- }
- if (profile.friendIDs) {
- data[@"friendIDs"] = [profile.friendIDs componentsJoinedByString:@","];
- }
- if (profile.birthday) {
- data[@"birthday"] = [NSString stringWithFormat:@"%@", @((time_t)[profile.birthday timeIntervalSince1970])];
- }
- if (profile.ageRange) {
- if (profile.ageRange.min) {
- data[@"ageMin"] = profile.ageRange.min.stringValue;
- }
- if (profile.ageRange.max) {
- data[@"ageMax"] = profile.ageRange.max.stringValue;
- }
- }
- if (profile.hometown) {
- data[@"hometown_id"] = profile.hometown.id;
- data[@"hometown_name"] = profile.hometown.name;
- }
- if (profile.location) {
- data[@"location_id"] = profile.location.id;
- data[@"location_name"] = profile.location.name;
- }
- if (profile.gender) {
- data[@"gender"] = profile.gender;
- }
- try {
- NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:nil];
- if (jsonData) {
- str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
- }
- } catch (NSException *exception) {
- NSLog(@"Fail to parse Profile");
- }
- const char* string = [str UTF8String];
- char* res = (char*)malloc(strlen(string) + 1);
- strcpy(res, string);
- return res;
- }
- void IOSFBSetPushNotificationsDeviceTokenString(const char *token)
- {
- [[FBSDKAppEvents shared] setPushNotificationsDeviceTokenString:[FBUnityUtility stringFromCString:token]];
- }
- void IOSFBSetShareDialogMode(int mode)
- {
- [FBUnityInterface sharedInstance].shareDialogMode = static_cast<ShareDialogMode>(mode);
- }
- void IOSFBAppRequest(int requestId,
- const char *message,
- const char *actionType,
- const char *objectId,
- const char **to,
- int toLength,
- const char *filters,
- const char **excludeIds, //not supported on mobile
- int excludeIdsLength, //not supported on mobile
- bool hasMaxRecipients, //not supported on mobile
- int maxRecipients, //not supported on mobile
- const char *data,
- const char *title)
- {
- [[FBUnityInterface sharedInstance] appRequestWithRequestId: requestId
- message: message
- actionType: actionType
- objectId: objectId
- to: to
- toLength: toLength
- filters: filters
- data: data
- title: title];
- }
- // Swift-only: the cold-start URL arrives via Application.absoluteURL from C#, not a notification.
- #if UNITY_XCODE_PROJECT_TYPE_SWIFT
- void IOSFBHandleLaunchURL(const char *urlString)
- {
- if ([FBUnityInterface sharedInstance].openURLString != nil) {
- return;
- }
- NSString *absoluteString = [FBUnityUtility stringFromCString:urlString];
- if (absoluteString.length == 0) {
- return;
- }
- NSURL *url = [NSURL URLWithString:absoluteString];
- if (url == nil) {
- return;
- }
- // Offered to the SDK first, like the warm path, so a Login redirect is not seen as an app link.
- BOOL isHandledByFBSDK = [[FBSDKApplicationDelegate sharedInstance] application:[UIApplication sharedApplication]
- openURL:url
- sourceApplication:nil
- annotation:nil];
- if (!isHandledByFBSDK) {
- [FBUnityInterface sharedInstance].openURLString = absoluteString;
- }
- }
- #else
- // No-op: onOpenURL: already delivered it, and openURLString is empty when FBSDK claimed the URL.
- void IOSFBHandleLaunchURL(__unused const char *urlString)
- {
- }
- #endif
- void IOSFBGetAppLink(int requestId)
- {
- NSURL *url = [NSURL URLWithString:[FBUnityInterface sharedInstance].openURLString];
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnGetAppLinkComplete
- userData:[FBUnityUtility appLinkDataFromUrl:url]
- requestId:requestId];
- [FBUnityInterface sharedInstance].openURLString = nil;
- }
- void IOSFBShareLink(int requestId,
- const char *contentURL,
- const char *contentTitle,
- const char *contentDescription,
- const char *photoURL)
- {
- [[FBUnityInterface sharedInstance] shareLinkWithRequestId:requestId
- contentURL:contentURL
- contentTitle:contentTitle
- contentDescription:contentDescription
- photoURL:photoURL];
- }
- void IOSFBFeedShare(int requestId,
- const char *toId,
- const char *link,
- const char *linkName,
- const char *linkCaption,
- const char *linkDescription,
- const char *picture,
- const char *mediaSource)
- {
- [[FBUnityInterface sharedInstance] shareFeedWithRequestId:requestId
- toId:toId
- link:link
- linkName:linkName
- linkCaption:linkCaption
- linkDescription:linkDescription
- picture:picture
- mediaSource:mediaSource];
- }
- void IOSFBAppEventsActivateApp()
- {
- [FBSDKAppEvents.shared activateApp];
- }
- void IOSFBAppEventsLogEvent(const char *eventName,
- double valueToSum,
- int numParams,
- const char **paramKeys,
- const char **paramVals)
- {
- NSDictionary *params = [FBUnityUtility dictionaryFromKeys:paramKeys values:paramVals length:numParams];
- [[FBSDKAppEvents shared] logEvent:[FBUnityUtility stringFromCString:eventName] valueToSum:valueToSum parameters:params];
- }
- void IOSFBAppEventsLogPurchase(double amount,
- const char *currency,
- int numParams,
- const char **paramKeys,
- const char **paramVals)
- {
- NSDictionary *params = [FBUnityUtility dictionaryFromKeys:paramKeys values:paramVals length:numParams];
- [[FBSDKAppEvents shared] logPurchase:amount currency:[FBUnityUtility stringFromCString:currency] parameters:params];
- }
- void IOSFBAppEventsSetLimitEventUsage(BOOL limitEventUsage)
- {
- [FBSDKSettings.sharedSettings setIsEventDataUsageLimited:limitEventUsage];
- }
- void IOSFBAutoLogAppEventsEnabled(BOOL autoLogAppEventsEnabledID)
- {
- [FBSDKSettings.sharedSettings setAutoLogAppEventsEnabled:autoLogAppEventsEnabledID];
- }
- void IOSFBAdvertiserIDCollectionEnabled(BOOL advertiserIDCollectionEnabledID)
- {
- [FBSDKSettings.sharedSettings setAdvertiserIDCollectionEnabled:advertiserIDCollectionEnabledID];
- }
- BOOL IOSFBAdvertiserTrackingEnabled(BOOL advertiserTrackingEnabled)
- {
- [FBSDKSettings.sharedSettings setAdvertiserTrackingEnabled:advertiserTrackingEnabled];
- return [FBSDKSettings.sharedSettings isAdvertiserTrackingEnabled];
- }
- BOOL IOSFBDomainErrorEnabled(BOOL domainErrorEnabled)
- {
- [FBSDKSettings.sharedSettings setIsDomainErrorEnabled:domainErrorEnabled];
- return [FBSDKSettings.sharedSettings isDomainErrorEnabled];
- }
- BOOL IOSFBFastAppSwitchEnabled(BOOL fastAppSwitchEnabled)
- {
- _fastAppSwitchEnabled = fastAppSwitchEnabled;
- return _fastAppSwitchEnabled;
- }
- char* IOSFBSdkVersion()
- {
- const char* string = [[FBSDKSettings.sharedSettings sdkVersion] UTF8String];
- char* res = (char*)malloc(strlen(string) + 1);
- strcpy(res, string);
- return res;
- }
- void IOSFBSetUserID(const char *userID)
- {
- [[FBSDKAppEvents shared] setUserID:[FBUnityUtility stringFromCString:userID]];
- }
- void IOSFBOpenGamingServicesFriendFinder(int requestId)
- {
- [FBSDKFriendFinderDialog
- launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError * _Nullable error) {
- if (!success || error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnFriendFinderComplete error:error requestId:requestId];
- } else {
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnFriendFinderComplete
- userData:NULL
- requestId:requestId];
- }
- }];
- }
- void IOSFBCreateGamingContext(int requestID, const char *playerID) {
- NSError *error;
- NSString *playerIDString = [FBUnityUtility stringFromCString:playerID];
- FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:requestID];
- FBSDKCreateContextContent *content = [[FBSDKCreateContextContent alloc] initDialogContentWithPlayerID:playerIDString];
- FBSDKContextDialogPresenter *presenter = [[FBSDKContextDialogPresenter alloc] init];
- [presenter makeAndShowCreateContextDialogWithContent:content delegate:delegate error:&error];
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnGetTournamentsComplete error:error requestId:requestID];
- }
- }
- void IOSFBSwitchGamingContext(
- int requestID,
- const char *contextID) {
- NSError *error;
- NSString *contextIDString = [FBUnityUtility stringFromCString:contextID];
- FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:requestID];
- FBSDKSwitchContextContent *content = [[FBSDKSwitchContextContent alloc] initDialogContentWithContextID:contextIDString];
- FBSDKContextDialogPresenter *presenter = [[FBSDKContextDialogPresenter alloc] init];
- [presenter makeAndShowSwitchContextDialogWithContent:content delegate:delegate error:&error];
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnGetTournamentsComplete error:error requestId:requestID];
- }
- }
- void IOSFBChooseGamingContext(
- int requestID,
- const char *filter,
- int minSize,
- int maxSize)
- {
- FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:requestID];
- FBSDKChooseContextContent *chooseContent = [FBSDKChooseContextContent alloc];
- NSString *filterNSString = [NSString stringWithUTF8String:filter];
- if ([filterNSString length] == 0) {
- chooseContent.filter = FBSDKChooseContextFilterNone;
- } else if ([filterNSString isEqualToString:@"NEW_PLAYERS_ONLY"]) {
- chooseContent.filter = FBSDKChooseContextFilterNewPlayersOnly;
- } else if ([filterNSString isEqualToString:@"INCLUDE_EXISTING_CHALLENGES"]) {
- chooseContent.filter = FBSDKChooseContextFilterExistingChallenges;
- } else if ([filterNSString isEqualToString:@"NEW_CONTEXT_ONLY"]) {
- chooseContent.filter = FBSDKChooseContextFilterNewContextOnly;
- }
- if (minSize > 0) {
- chooseContent.minParticipants = minSize;
- }
- if (maxSize > 0) {
- chooseContent.maxParticipants = maxSize;
- }
- FBSDKContextDialogPresenter *presenter = [[FBSDKContextDialogPresenter alloc] init];
- [presenter makeAndShowChooseContextDialogWithContent:chooseContent delegate:delegate];
- }
- void IOSFBGetCurrentGamingContext(int requestID)
- {
- FBSDKGamingContext *currentContext = [FBSDKGamingContext currentContext];
- if (currentContext) {
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnGetCurrentGamingContextComplete
- userData:@{@"contextId":[currentContext identifier]}
- requestId:requestID];
- } else {
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnGetCurrentGamingContextComplete
- userData:NULL
- requestId:requestID];
- }
- }
- void IOSFBSetDataProcessingOptions(
- const char** options,
- int numOptions,
- int country,
- int state) {
- NSMutableArray<NSString*>* array = [[NSMutableArray alloc] init];
- for (int i = 0; i < numOptions; i++) {
- NSString* option = [FBUnityUtility stringFromCString:options[i]];
- if (option) {
- [array addObject:option];
- }
- }
- [FBSDKSettings.sharedSettings setDataProcessingOptions:array country:country state:state];
- }
- void IOSFBGetTournaments(int requestID)
- {
- FBSDKTournamentFetcher *fetcher = [[FBSDKTournamentFetcher alloc] init];
- [fetcher fetchTournamentsWithCompletionHandler:^(NSArray<FBSDKTournament *> * tournaments, NSError * error) {
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnGetTournamentsComplete error:error requestId:requestID];
- }
- NSMutableDictionary *userData = [NSMutableDictionary new];
- for (FBSDKTournament *tournament in tournaments) {
- userData[tournament.identifier] = [tournament toDictionary];
- }
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnGetTournamentsComplete
- userData:userData
- requestId:requestID];
- }];
- }
- void IOSFBUpdateTournament(const char *tournamentID, int score, int requestID)
- {
- FBSDKTournamentUpdater *updater = [[FBSDKTournamentUpdater alloc] init];
- [updater updateWithTournamentID:[NSString stringWithUTF8String:tournamentID]
- score:score
- completionHandler:^(BOOL success, NSError * _Nullable error) {
- if (!success || error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnUpdateTournamentComplete error:error requestId:requestID];
- } else {
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnUpdateTournamentComplete
- userData:NULL
- requestId:requestID];
- }
- }];
- }
- void IOSFBUpdateAndShareTournament(const char *tournamentID, int score, int requestID)
- {
- NSError *error;
- FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:requestID];
- FBSDKShareTournamentDialog *dialog = [[FBSDKShareTournamentDialog alloc] initWithDelegate: delegate];
- [dialog showWithScore:score tournamentID:[NSString stringWithUTF8String:tournamentID] error:&error];
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnGetTournamentsComplete error:error requestId:requestID];
- }
- }
- void IOSFBCreateAndShareTournament(
- int initialScore,
- const char *title,
- int sortOrder,
- int scoreFormat,
- long endTime,
- const char *payload,
- int requestID)
- {
- NSError *error;
- FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:requestID];
- FBSDKShareTournamentDialog *dialog = [[FBSDKShareTournamentDialog alloc] initWithDelegate: delegate];
- NSString *payloadString;
- if (payload) {
- payloadString = [NSString stringWithUTF8String:payload];
- }
- [dialog showWithInitialScore:initialScore
- title:[NSString stringWithUTF8String:title]
- endTime:[NSDate dateWithTimeIntervalSince1970: endTime]
- scoreType:scoreFormat
- sortOrder:sortOrder
- payload:payloadString
- error: &error];
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnGetTournamentsComplete error:error requestId:requestID];
- }
- }
- void IOSFBUploadImageToMediaLibrary(
- int requestId,
- const char *caption,
- const char *imageUri,
- bool shouldLaunchMediaDialog)
- {
- NSString *captionString = [FBUnityUtility stringFromCString:caption];
- NSString *imageUriString = [FBUnityUtility stringFromCString:imageUri];
- UIImage *image = [UIImage imageWithContentsOfFile:imageUriString];
- FBSDKGamingImageUploaderConfiguration *config =
- [[FBSDKGamingImageUploaderConfiguration alloc]
- initWithImage:image
- caption:captionString
- shouldLaunchMediaDialog:shouldLaunchMediaDialog ? YES: NO];
- [FBSDKGamingImageUploader
- uploadImageWithConfiguration:config
- andResultCompletion:^(BOOL success, id result, NSError * _Nullable error) {
- if (!success || error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnUploadImageToMediaLibraryComplete
- error:error
- requestId:requestId];
- } else {
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnUploadImageToMediaLibraryComplete
- userData:@{@"id":result[@"id"]}
- requestId:requestId];
- }
- }];
- }
- void IOSFBUploadVideoToMediaLibrary(int requestId,
- const char *caption,
- const char *videoUri)
- {
- NSString *captionString = [FBUnityUtility stringFromCString:caption];
- NSString *videoUriString = [FBUnityUtility stringFromCString:videoUri];
- NSURL *videoURL = [NSURL fileURLWithPath:videoUriString];
- FBSDKGamingVideoUploaderConfiguration *config =
- [[FBSDKGamingVideoUploaderConfiguration alloc]
- initWithVideoURL:videoURL
- caption:captionString];
- [FBSDKGamingVideoUploader
- uploadVideoWithConfiguration:config
- andResultCompletion:^(BOOL success, id result, NSError * _Nullable error) {
- if (!success || error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnUploadVideoToMediaLibraryComplete
- error:error
- requestId:requestId];
- } else {
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnUploadVideoToMediaLibraryComplete
- userData:@{@"id":result[@"id"]}
- requestId:requestId];
- }
- }];
- }
- char* IOSFBGetUserID()
- {
- NSString *userID = [[FBSDKAppEvents shared] userID];
- if (!userID) {
- return NULL;
- }
- const char* string = [userID UTF8String];
- char* res = (char*)malloc(strlen(string) + 1);
- strcpy(res, string);
- return res;
- }
- void IOSFBFetchDeferredAppLink(int requestId)
- {
- [FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *url, NSError *error) {
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnFetchDeferredAppLinkComplete error:error requestId:requestId];
- return;
- }
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnFetchDeferredAppLinkComplete
- userData:[FBUnityUtility appLinkDataFromUrl:url]
- requestId:requestId];
- }];
- }
- void IOSFBRefreshCurrentAccessToken(int requestId)
- {
- FBSDKGraphRequestCompletion completion = ^(id<FBSDKGraphRequestConnecting> connection, id result, NSError *error) {
- if (error) {
- [FBUnityUtility sendErrorToUnity:FBUnityMessageName_OnRefreshCurrentAccessTokenComplete error:error requestId:requestId];
- return;
- }
- [FBUnityUtility sendMessageToUnity:FBUnityMessageName_OnRefreshCurrentAccessTokenComplete
- userData:[FBUnityUtility getUserDataFromAccessToken:[FBSDKAccessToken currentAccessToken]]
- requestId:requestId];
- };
- [FBSDKAccessToken refreshCurrentAccessTokenWithCompletion: completion];
- }
- void IOSFBRefreshLimitedLogin(int requestId, int fallbackPolicy)
- {
- [[FBUnityInterface sharedInstance] refreshLimitedLogin:requestId fallbackPolicy:fallbackPolicy];
- }
- }
|