- Fix array population when arrive dictionary from webservices

This commit is contained in:
Giuseppe Nucifora 2019-01-25 11:57:53 +01:00
parent 10e81534c7
commit 451fc6aa7f
37 changed files with 914 additions and 627 deletions

View File

@ -37,13 +37,13 @@ PODS:
- Bolts (~> 1.9) - Bolts (~> 1.9)
- FacebookSDK/CoreKit - FacebookSDK/CoreKit
- FBSDKMarketingKit - FBSDKMarketingKit
- FBSDKCoreKit (4.39.0): - FBSDKCoreKit (4.40.0):
- Bolts (~> 1.9) - Bolts (~> 1.9)
- FBSDKLoginKit (4.39.0): - FBSDKLoginKit (4.40.0):
- FBSDKCoreKit - FBSDKCoreKit
- FBSDKMarketingKit (4.38.0): - FBSDKMarketingKit (4.38.0):
- FBSDKCoreKit - FBSDKCoreKit
- FBSDKShareKit (4.39.0): - FBSDKShareKit (4.40.0):
- FBSDKCoreKit - FBSDKCoreKit
- NSDataAES (0.2.2) - NSDataAES (0.2.2)
- NSDate_Utils (1.1.0): - NSDate_Utils (1.1.0):
@ -51,7 +51,7 @@ PODS:
- NSString-Helper (1.2.0) - NSString-Helper (1.2.0)
- nv-ios-http-status (0.0.1) - nv-ios-http-status (0.0.1)
- PEAR-FileManager-iOS (1.3.1) - PEAR-FileManager-iOS (1.3.1)
- PNObject (2.6.1): - PNObject (2.6.3):
- AFNetworking - AFNetworking
- CodFis-Helper - CodFis-Helper
- DDDKeychainWrapper - DDDKeychainWrapper
@ -115,16 +115,16 @@ SPEC CHECKSUMS:
DJLocalization: 0c84029af375647d4104a42ae36be87194c46c47 DJLocalization: 0c84029af375647d4104a42ae36be87194c46c47
Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5
FacebookSDK: 73f54b8b94e09b05647cdef0af147f470cd3edc6 FacebookSDK: 73f54b8b94e09b05647cdef0af147f470cd3edc6
FBSDKCoreKit: 1e3981faefab8c88edfaa9eecd94aab02d99a9bc FBSDKCoreKit: ae214474b25033399c131dc81d258e412582a2ba
FBSDKLoginKit: 30ba5039a2c53d65a75103889bc2deebdacd5a1f FBSDKLoginKit: 7a1e411d46acc8834588eca437daf34de42e1d52
FBSDKMarketingKit: e609f39d74ab273cf52e2f8b7e8829ed412b2827 FBSDKMarketingKit: e609f39d74ab273cf52e2f8b7e8829ed412b2827
FBSDKShareKit: 5a0021c30abb64df9eeba87351dd8a627874543b FBSDKShareKit: 0e45916f4150da485928ae2a17ca021950b194f5
NSDataAES: 967ea3337476a80e9838a533c25d570a06855ed0 NSDataAES: 967ea3337476a80e9838a533c25d570a06855ed0
NSDate_Utils: c858a89da6e204ecf53aca48dbccb4da4d25bc9e NSDate_Utils: c858a89da6e204ecf53aca48dbccb4da4d25bc9e
NSString-Helper: 1c259caa6c845e79e0bb45ee25e34f95d86d2317 NSString-Helper: 1c259caa6c845e79e0bb45ee25e34f95d86d2317
nv-ios-http-status: b6c2b5fc8656cc19e0d3000dadce2080b99d0e2f nv-ios-http-status: b6c2b5fc8656cc19e0d3000dadce2080b99d0e2f
PEAR-FileManager-iOS: 3bc403f68a53483f5629aa822f4649e40275c4d3 PEAR-FileManager-iOS: 3bc403f68a53483f5629aa822f4649e40275c4d3
PNObject: 4dd707682a5933f247091a23e39bf9688ea7e367 PNObject: b70db2cba56df79ddf5b2df096afad403cc5d041
PureLayout: f08c01b8dec00bb14a1fefa3de4c7d9c265df85e PureLayout: f08c01b8dec00bb14a1fefa3de4c7d9c265df85e
RZDataBinding: 289e2fbdce8b9585afef69def83425c5d380ffbd RZDataBinding: 289e2fbdce8b9585afef69def83425c5d380ffbd
Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66 Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66

View File

@ -659,23 +659,6 @@ static NSString *g_overrideAppID = nil;
if ([FBSDKAppEvents flushBehavior] != FBSDKAppEventsFlushBehaviorExplicitOnly) { if ([FBSDKAppEvents flushBehavior] != FBSDKAppEventsFlushBehaviorExplicitOnly) {
[[FBSDKAppEvents singleton] flushForReason:FBSDKAppEventsFlushReasonEagerlyFlushingEvent]; [[FBSDKAppEvents singleton] flushForReason:FBSDKAppEventsFlushReasonEagerlyFlushingEvent];
} }
// Update device push token for uninstall tracking
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *error) {
if (serverConfiguration.uninstallTrackingEnabled) {
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:[NSString stringWithFormat:@"%@/%@",
[FBSDKSettings appID], UNINSTALL_TRACKING_TOKEN_ENDPOINT]
parameters:@{
UNINSTALL_TRACKING_DEVICE_TOKEN_KEY: deviceTokenString,
UNINSTALL_TRACKING_PLATFORM_KEY: @"ios",
// advertiserID could be 0s if user select limit ad tracking
UNINSTALL_TRACKING_DEVICE_ID_KEY: [FBSDKAppEventsUtility advertiserID] ?: @""
}
HTTPMethod:@"POST"];
[request startWithCompletionHandler:nil];
}
}];
} }
} }
@ -1177,7 +1160,7 @@ static NSString *g_overrideAppID = nil;
} }
NSString *loggingEntry = nil; NSString *loggingEntry = nil;
if ([[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorAppEvents]) { if ([FBSDKSettings.loggingBehaviors containsObject:FBSDKLoggingBehaviorAppEvents]) {
NSData *prettyJSONData = [NSJSONSerialization dataWithJSONObject:appEventsState.events NSData *prettyJSONData = [NSJSONSerialization dataWithJSONObject:appEventsState.events
options:NSJSONWritingPrettyPrinted options:NSJSONWritingPrettyPrinted
error:NULL]; error:NULL];

View File

@ -102,8 +102,10 @@ static Class g_BFTaskClass;
appLinks[url] = self.cachedFBSDKAppLinks[url]; appLinks[url] = self.cachedFBSDKAppLinks[url];
} else { } else {
[toFind addObject:url]; [toFind addObject:url];
NSCharacterSet *urlAllowedSet = [NSCharacterSet URLQueryAllowedCharacterSet]; #pragma clang diagnostic push
NSString *toFindString = [url.absoluteString stringByAddingPercentEncodingWithAllowedCharacters:urlAllowedSet]; #pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSString *toFindString = [url.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
#pragma clang diagnostic pop
if (toFindString) { if (toFindString) {
[toFindStrings addObject:toFindString]; [toFindStrings addObject:toFindString];
} }
@ -196,8 +198,13 @@ static Class g_BFTaskClass;
appLinks[url] = self.cachedBFAppLinks[url]; appLinks[url] = self.cachedBFAppLinks[url];
} else { } else {
[toFind addObject:url]; [toFind addObject:url];
NSCharacterSet *urlAllowedSet = [NSCharacterSet URLQueryAllowedCharacterSet]; #pragma clang diagnostic push
[toFindStrings addObject:[url.absoluteString stringByAddingPercentEncodingWithAllowedCharacters:urlAllowedSet]]; #pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSString *toFindString = [url.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
#pragma clang diagnostic pop
if (toFindString) {
[toFindStrings addObject:toFindString];
}
} }
} }
} }

View File

@ -58,88 +58,98 @@ NSString *const FBSDKApplicationDidBecomeActiveNotification = @"com.facebook.sdk
static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound"; static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error);
@protocol FBSDKAuthenticationSession <NSObject>
- (instancetype)initWithURL:(NSURL *)URL callbackURLScheme:(nullable NSString *)callbackURLScheme completionHandler:(FBSDKAuthenticationCompletionHandler)completionHandler;
- (BOOL)start;
- (void)cancel;
@end
@implementation FBSDKApplicationDelegate @implementation FBSDKApplicationDelegate
{ {
#if !TARGET_OS_TV #if !TARGET_OS_TV
FBSDKBridgeAPIRequest *_pendingRequest; FBSDKBridgeAPIRequest *_pendingRequest;
FBSDKBridgeAPICallbackBlock _pendingRequestCompletionBlock; FBSDKBridgeAPICallbackBlock _pendingRequestCompletionBlock;
id<FBSDKURLOpening> _pendingURLOpen; id<FBSDKURLOpening> _pendingURLOpen;
SFAuthenticationSession *_authenticationSession NS_AVAILABLE_IOS(11_0); id<FBSDKAuthenticationSession> _authenticationSession NS_AVAILABLE_IOS(11_0);
SFAuthenticationCompletionHandler _authenticationSessionCompletionHandler NS_AVAILABLE_IOS(11_0); FBSDKAuthenticationCompletionHandler _authenticationSessionCompletionHandler NS_AVAILABLE_IOS(11_0);
#endif #endif
BOOL _expectingBackground; BOOL _expectingBackground;
BOOL _isRequestingSFAuthenticationSession; BOOL _isRequestingSFAuthenticationSession;
UIViewController *_safariViewController; UIViewController *_safariViewController;
BOOL _isDismissingSafariViewController; BOOL _isDismissingSafariViewController;
BOOL _isAppLaunched; BOOL _isAppLaunched;
} }
#pragma mark - Class Methods #pragma mark - Class Methods
+ (void)load + (void)load
{ {
// when the app becomes active by any means, kick off the initialization. // when the app becomes active by any means, kick off the initialization.
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(initializeWithLaunchData:) selector:@selector(initializeWithLaunchData:)
name:UIApplicationDidFinishLaunchingNotification name:UIApplicationDidFinishLaunchingNotification
object:nil]; object:nil];
} }
// Initialize SDK listeners // Initialize SDK listeners
// Don't call this function in any place else. It should only be called when the class is loaded. // Don't call this function in any place else. It should only be called when the class is loaded.
+ (void)initializeWithLaunchData:(NSNotification *)note + (void)initializeWithLaunchData:(NSNotification *)note
{ {
NSDictionary *launchData = note.userInfo; NSDictionary *launchData = note.userInfo;
[[self sharedInstance] application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:launchData]; [[self sharedInstance] application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:launchData];
#if !TARGET_OS_TV #if !TARGET_OS_TV
// Register Listener for Bolts measurement events // Register Listener for Bolts measurement events
[FBSDKBoltsMeasurementEventListener defaultListener]; [FBSDKBoltsMeasurementEventListener defaultListener];
#endif #endif
// Set the SourceApplication for time spent data. This is not going to update the value if the app has already launched. // Set the SourceApplication for time spent data. This is not going to update the value if the app has already launched.
[FBSDKTimeSpentData setSourceApplication:launchData[UIApplicationLaunchOptionsSourceApplicationKey] [FBSDKTimeSpentData setSourceApplication:launchData[UIApplicationLaunchOptionsSourceApplicationKey]
openURL:launchData[UIApplicationLaunchOptionsURLKey]]; openURL:launchData[UIApplicationLaunchOptionsURLKey]];
// Register on UIApplicationDidEnterBackgroundNotification events to reset source application data when app backgrounds. // Register on UIApplicationDidEnterBackgroundNotification events to reset source application data when app backgrounds.
[FBSDKTimeSpentData registerAutoResetSourceApplication]; [FBSDKTimeSpentData registerAutoResetSourceApplication];
[FBSDKInternalUtility validateFacebookReservedURLSchemes]; [FBSDKInternalUtility validateFacebookReservedURLSchemes];
// Remove the observer // Remove the observer
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
+ (instancetype)sharedInstance + (instancetype)sharedInstance
{ {
static FBSDKApplicationDelegate *_sharedInstance; static FBSDKApplicationDelegate *_sharedInstance;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] _init]; _sharedInstance = [[self alloc] _init];
}); });
return _sharedInstance; return _sharedInstance;
} }
#pragma mark - Object Lifecycle #pragma mark - Object Lifecycle
- (instancetype)_init - (instancetype)_init
{ {
if ((self = [super init]) != nil) { if ((self = [super init]) != nil) {
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; [defaultCenter addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[defaultCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; [defaultCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[FBSDKAppEvents singleton] registerNotifications]; [[FBSDKAppEvents singleton] registerNotifications];
} }
return self; return self;
} }
- (instancetype)init - (instancetype)init
{ {
return nil; return nil;
} }
- (void)dealloc - (void)dealloc
{ {
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
#pragma mark - UIApplicationDelegate #pragma mark - UIApplicationDelegate
@ -149,14 +159,14 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
openURL:(NSURL *)url openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{ {
if (@available(iOS 9.0, *)) { if (@available(iOS 9.0, *)) {
return [self application:application return [self application:application
openURL:url openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
} }
return NO; return NO;
} }
#endif #endif
@ -165,127 +175,127 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
sourceApplication:(NSString *)sourceApplication sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation annotation:(id)annotation
{ {
if (sourceApplication != nil && ![sourceApplication isKindOfClass:[NSString class]]) { if (sourceApplication != nil && ![sourceApplication isKindOfClass:[NSString class]]) {
@throw [NSException exceptionWithName:NSInvalidArgumentException @throw [NSException exceptionWithName:NSInvalidArgumentException
reason:@"Expected 'sourceApplication' to be NSString. Please verify you are passing in 'sourceApplication' from your app delegate (not the UIApplication* parameter). If your app delegate implements iOS 9's application:openURL:options:, you should pass in options[UIApplicationOpenURLOptionsSourceApplicationKey]. " reason:@"Expected 'sourceApplication' to be NSString. Please verify you are passing in 'sourceApplication' from your app delegate (not the UIApplication* parameter). If your app delegate implements iOS 9's application:openURL:options:, you should pass in options[UIApplicationOpenURLOptionsSourceApplicationKey]. "
userInfo:nil]; userInfo:nil];
} }
[FBSDKTimeSpentData setSourceApplication:sourceApplication openURL:url]; [FBSDKTimeSpentData setSourceApplication:sourceApplication openURL:url];
#if !TARGET_OS_TV #if !TARGET_OS_TV
id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen; id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen;
void (^completePendingOpenURLBlock)(void) = ^{ void (^completePendingOpenURLBlock)(void) = ^{
self->_pendingURLOpen = nil; self->_pendingURLOpen = nil;
[pendingURLOpen application:application [pendingURLOpen application:application
openURL:url openURL:url
sourceApplication:sourceApplication sourceApplication:sourceApplication
annotation:annotation]; annotation:annotation];
self->_isDismissingSafariViewController = NO; self->_isDismissingSafariViewController = NO;
}; };
// if they completed a SFVC flow, dismiss it. // if they completed a SFVC flow, dismiss it.
if (_safariViewController) { if (_safariViewController) {
_isDismissingSafariViewController = YES; _isDismissingSafariViewController = YES;
[_safariViewController.presentingViewController dismissViewControllerAnimated:YES [_safariViewController.presentingViewController dismissViewControllerAnimated:YES
completion:completePendingOpenURLBlock]; completion:completePendingOpenURLBlock];
_safariViewController = nil; _safariViewController = nil;
} else { } else if (@available(iOS 11.0, *)) {
if (@available(iOS 11.0, *)) { if (_authenticationSession != nil) {
if (_authenticationSession != nil) { [_authenticationSession cancel];
[_authenticationSession cancel]; _authenticationSession = nil;
_authenticationSession = nil; }
} completePendingOpenURLBlock();
} }
completePendingOpenURLBlock();
}
if ([pendingURLOpen canOpenURL:url
forApplication:application
sourceApplication:sourceApplication
annotation:annotation]) {
return YES;
}
if ([self _handleBridgeAPIResponseURL:url sourceApplication:sourceApplication]) {
return YES;
}
#endif
[self _logIfAppLinkEvent:url];
return NO; if ([pendingURLOpen canOpenURL:url
forApplication:application
sourceApplication:sourceApplication
annotation:annotation]) {
return YES;
}
if ([self _handleBridgeAPIResponseURL:url sourceApplication:sourceApplication]) {
return YES;
}
#endif
[self _logIfAppLinkEvent:url];
return NO;
} }
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ {
if (_isAppLaunched) { if (_isAppLaunched) {
return NO; return NO;
} }
_isAppLaunched = YES; _isAppLaunched = YES;
FBSDKAccessToken *cachedToken = [FBSDKSettings accessTokenCache].accessToken; FBSDKAccessToken *cachedToken = [FBSDKSettings accessTokenCache].accessToken;
[FBSDKAccessToken setCurrentAccessToken:cachedToken]; [FBSDKAccessToken setCurrentAccessToken:cachedToken];
// fetch app settings // fetch app settings
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
// fetch gate keepers // fetch gate keepers
[FBSDKGateKeeperManager loadGateKeepers]; [FBSDKGateKeeperManager loadGateKeepers];
if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) { if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) {
[self _logSDKInitialize]; [self _logSDKInitialize];
} }
#if !TARGET_OS_TV #if !TARGET_OS_TV
FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile]; FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile];
[FBSDKProfile setCurrentProfile:cachedProfile]; [FBSDKProfile setCurrentProfile:cachedProfile];
NSURL *launchedURL = launchOptions[UIApplicationLaunchOptionsURLKey]; NSURL *launchedURL = launchOptions[UIApplicationLaunchOptionsURLKey];
NSString *sourceApplication = launchOptions[UIApplicationLaunchOptionsSourceApplicationKey]; NSString *sourceApplication = launchOptions[UIApplicationLaunchOptionsSourceApplicationKey];
if (launchedURL && if (launchedURL &&
sourceApplication) { sourceApplication) {
Class loginManagerClass = NSClassFromString(@"FBSDKLoginManager"); Class loginManagerClass = NSClassFromString(@"FBSDKLoginManager");
if (loginManagerClass) { if (loginManagerClass) {
id annotation = launchOptions[UIApplicationLaunchOptionsAnnotationKey]; id annotation = launchOptions[UIApplicationLaunchOptionsAnnotationKey];
id<FBSDKURLOpening> loginManager = [[loginManagerClass alloc] init]; id<FBSDKURLOpening> loginManager = [[loginManagerClass alloc] init];
return [loginManager application:application return [loginManager application:application
openURL:launchedURL openURL:launchedURL
sourceApplication:sourceApplication sourceApplication:sourceApplication
annotation:annotation]; annotation:annotation];
}
} }
}
#endif #endif
return NO; return NO;
} }
- (void)applicationDidEnterBackground:(NSNotification *)notification - (void)applicationDidEnterBackground:(NSNotification *)notification
{ {
_isRequestingSFAuthenticationSession = NO; _isRequestingSFAuthenticationSession = NO;
_active = NO; _active = NO;
_expectingBackground = NO; _expectingBackground = NO;
} }
- (void)applicationDidBecomeActive:(NSNotification *)notification - (void)applicationDidBecomeActive:(NSNotification *)notification
{ {
// Auto log basic events in case autoLogAppEventsEnabled is set // Auto log basic events in case autoLogAppEventsEnabled is set
if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) { if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) {
[FBSDKAppEvents activateApp]; [FBSDKAppEvents activateApp];
}
// _expectingBackground can be YES if the caller started doing work (like login)
// within the app delegate's lifecycle like openURL, in which case there
// might have been a "didBecomeActive" event pending that we want to ignore.
BOOL notExpectingBackground = !_expectingBackground && !_safariViewController && !_isDismissingSafariViewController && !_isRequestingSFAuthenticationSession;
#if !TARGET_OS_TV
if (@available(iOS 11.0, *)) {
if (notExpectingBackground && _authenticationSessionCompletionHandler != nil) {
_authenticationSessionCompletionHandler(nil, nil);
} }
notExpectingBackground = notExpectingBackground && !_authenticationSession; // _expectingBackground can be YES if the caller started doing work (like login)
} // within the app delegate's lifecycle like openURL, in which case there
#endif // might have been a "didBecomeActive" event pending that we want to ignore.
if (notExpectingBackground) { BOOL notExpectingBackground = !_expectingBackground && !_safariViewController && !_isDismissingSafariViewController && !_isRequestingSFAuthenticationSession;
_active = YES;
#if !TARGET_OS_TV #if !TARGET_OS_TV
[_pendingURLOpen applicationDidBecomeActive:notification.object]; if (@available(iOS 11.0, *)) {
[self _cancelBridgeRequest]; if (notExpectingBackground && _authenticationSessionCompletionHandler != nil) {
_authenticationSessionCompletionHandler(nil, nil);
}
notExpectingBackground = notExpectingBackground && !_authenticationSession;
}
#endif #endif
[[NSNotificationCenter defaultCenter] postNotificationName:FBSDKApplicationDidBecomeActiveNotification object:self]; if (notExpectingBackground) {
} _active = YES;
#if !TARGET_OS_TV
[_pendingURLOpen applicationDidBecomeActive:notification.object];
[self _cancelBridgeRequest];
#endif
[[NSNotificationCenter defaultCenter] postNotificationName:FBSDKApplicationDidBecomeActiveNotification object:self];
}
} }
#pragma mark - Internal Methods #pragma mark - Internal Methods
@ -296,33 +306,33 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
- (void)openURL:(NSURL *)url sender:(id<FBSDKURLOpening>)sender handler:(void(^)(BOOL, NSError *))handler - (void)openURL:(NSURL *)url sender:(id<FBSDKURLOpening>)sender handler:(void(^)(BOOL, NSError *))handler
{ {
_expectingBackground = YES; _expectingBackground = YES;
_pendingURLOpen = sender; _pendingURLOpen = sender;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
// Dispatch openURL calls to prevent hangs if we're inside the current app delegate's openURL flow already // Dispatch openURL calls to prevent hangs if we're inside the current app delegate's openURL flow already
NSOperatingSystemVersion iOS10Version = { .majorVersion = 10, .minorVersion = 0, .patchVersion = 0 }; NSOperatingSystemVersion iOS10Version = { .majorVersion = 10, .minorVersion = 0, .patchVersion = 0 };
if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS10Version]) { if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS10Version]) {
if (@available(iOS 10.0, *)) { if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) { [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
handler(success, nil); handler(success, nil);
}]; }];
} }
} else { } else {
BOOL opened = [[UIApplication sharedApplication] openURL:url]; BOOL opened = [[UIApplication sharedApplication] openURL:url];
if ([url.scheme hasPrefix:@"http"] && !opened) { if ([url.scheme hasPrefix:@"http"] && !opened) {
NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 };
if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) {
// Safari openURL calls can wrongly return NO on iOS 7 so manually overwrite that case to YES. // Safari openURL calls can wrongly return NO on iOS 7 so manually overwrite that case to YES.
// Otherwise we would rather trust in the actual result of openURL // Otherwise we would rather trust in the actual result of openURL
opened = YES; opened = YES;
}
}
if (handler) {
handler(opened, nil);
}
} }
} });
if (handler) {
handler(opened, nil);
}
}
});
} }
- (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request - (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request
@ -330,41 +340,41 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
completionBlock:(FBSDKBridgeAPICallbackBlock)completionBlock completionBlock:(FBSDKBridgeAPICallbackBlock)completionBlock
{ {
if (!request) { if (!request) {
return; return;
} }
NSError *error; NSError *error;
NSURL *requestURL = [request requestURL:&error]; NSURL *requestURL = [request requestURL:&error];
if (!requestURL) { if (!requestURL) {
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error]; FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error];
completionBlock(response); completionBlock(response);
return; return;
} }
_pendingRequest = request; _pendingRequest = request;
_pendingRequestCompletionBlock = [completionBlock copy]; _pendingRequestCompletionBlock = [completionBlock copy];
void (^handler)(BOOL, NSError *) = ^(BOOL openedURL, NSError *anError) { void (^handler)(BOOL, NSError *) = ^(BOOL openedURL, NSError *anError) {
if (!openedURL) { if (!openedURL) {
self->_pendingRequest = nil; self->_pendingRequest = nil;
self->_pendingRequestCompletionBlock = nil; self->_pendingRequestCompletionBlock = nil;
NSError *openedURLError; NSError *openedURLError;
if ([request.scheme hasPrefix:@"http"]) { if ([request.scheme hasPrefix:@"http"]) {
openedURLError = [NSError fbErrorWithCode:FBSDKErrorBrowserUnavailable openedURLError = [NSError fbErrorWithCode:FBSDKErrorBrowserUnavailable
message:@"the app switch failed because the browser is unavailable"]; message:@"the app switch failed because the browser is unavailable"];
} else { } else {
openedURLError = [NSError fbErrorWithCode:FBSDKErrorAppVersionUnsupported openedURLError = [NSError fbErrorWithCode:FBSDKErrorAppVersionUnsupported
message:@"the app switch failed because the destination app is out of date"]; message:@"the app switch failed because the destination app is out of date"];
} }
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request
error:openedURLError]; error:openedURLError];
completionBlock(response); completionBlock(response);
return; return;
}
};
if (useSafariViewController) {
[self openURLWithSafariViewController:requestURL sender:nil fromViewController:fromViewController handler:handler];
} else {
[self openURL:requestURL sender:nil handler:handler];
} }
};
if (useSafariViewController) {
[self openURLWithSafariViewController:requestURL sender:nil fromViewController:fromViewController handler:handler];
} else {
[self openURL:requestURL sender:nil handler:handler];
}
} }
- (void)openURLWithSafariViewController:(NSURL *)url - (void)openURLWithSafariViewController:(NSURL *)url
@ -372,90 +382,105 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
handler:(void(^)(BOOL, NSError *))handler handler:(void(^)(BOOL, NSError *))handler
{ {
if (![url.scheme hasPrefix:@"http"]) { if (![url.scheme hasPrefix:@"http"]) {
[self openURL:url sender:sender handler:handler]; [self openURL:url sender:sender handler:handler];
return; return;
} }
_expectingBackground = NO; _expectingBackground = NO;
_pendingURLOpen = sender; _pendingURLOpen = sender;
if (@available(iOS 11.0, *)) { if (@available(iOS 11.0, *)) {
if ([sender isAuthenticationURL:url]) { if ([sender isAuthenticationURL:url]) {
Class SFAuthenticationSessionClass = fbsdkdfl_SFAuthenticationSessionClass(); [self _setSessionCompletionHandlerFromHandler:handler];
if (SFAuthenticationSessionClass != nil) { [self _openURLWithAuthenticationSession:url];
if (_authenticationSession != nil) { return;
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
formatString:@"There is already a request for authenticated session. Cancelling active SFAuthenticationSession before starting the new one.", nil];
[_authenticationSession cancel];
} }
__weak typeof(self) weakSelf = self; }
_authenticationSessionCompletionHandler = ^ (NSURL *aURL, NSError *error) {
typeof(self) strongSelf = weakSelf; // trying to dynamically load SFSafariViewController class
strongSelf->_isRequestingSFAuthenticationSession = NO; // so for the cases when it is available we can send users through Safari View Controller flow
handler(error == nil, error); // in cases it is not available regular flow will be selected
if (error == nil) { Class SFSafariViewControllerClass = fbsdkdfl_SFSafariViewControllerClass();
[strongSelf application:[UIApplication sharedApplication] openURL:aURL sourceApplication:@"com.apple" annotation:nil];
} if (SFSafariViewControllerClass) {
strongSelf->_authenticationSession = nil; UIViewController *parent = fromViewController ?: [FBSDKInternalUtility topMostViewController];
strongSelf->_authenticationSessionCompletionHandler = nil; if (parent == nil) {
}; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
_authenticationSession = [[SFAuthenticationSessionClass alloc] initWithURL:url formatString:@"There are no valid ViewController to present SafariViewController with", nil];
callbackURLScheme:[FBSDKInternalUtility appURLScheme] return;
completionHandler:_authenticationSessionCompletionHandler]; }
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSURLQueryItem *sfvcQueryItem = [[NSURLQueryItem alloc] initWithName:@"sfvc" value:@"1"];
components.queryItems = [components.queryItems arrayByAddingObject:sfvcQueryItem];
url = components.URL;
FBSDKContainerViewController *container = [[FBSDKContainerViewController alloc] init];
container.delegate = self;
if (parent.transitionCoordinator != nil) {
// Wait until the transition is finished before presenting SafariVC to avoid a blank screen.
[parent.transitionCoordinator animateAlongsideTransition:NULL completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Note SFVC init must occur inside block to avoid blank screen.
self->_safariViewController = [[SFSafariViewControllerClass alloc] initWithURL:url];
// Disable dismissing with edge pan gesture
self->_safariViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self->_safariViewController performSelector:@selector(setDelegate:) withObject:self];
[container displayChildController:self->_safariViewController];
[parent presentViewController:container animated:YES completion:nil];
}];
} else {
_safariViewController = [[SFSafariViewControllerClass alloc] initWithURL:url];
// Disable dismissing with edge pan gesture
_safariViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
[_safariViewController performSelector:@selector(setDelegate:) withObject:self];
[container displayChildController:_safariViewController];
[parent presentViewController:container animated:YES completion:nil];
}
// Assuming Safari View Controller always opens
if (handler) {
handler(YES, nil);
}
} else {
[self openURL:url sender:sender handler:handler];
}
}
- (void)_openURLWithAuthenticationSession:(NSURL *)url
{
Class AuthenticationSessionClass = fbsdkdfl_ASWebAuthenticationSessionClass();
if (!AuthenticationSessionClass) {
AuthenticationSessionClass = fbsdkdfl_SFAuthenticationSessionClass();
}
if (AuthenticationSessionClass != nil) {
if (_authenticationSession != nil) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
formatString:@"There is already a request for authenticated session. Cancelling active SFAuthenticationSession before starting the new one.", nil];
[_authenticationSession cancel];
}
_authenticationSession = [[AuthenticationSessionClass alloc] initWithURL:url
callbackURLScheme:[FBSDKInternalUtility appURLScheme]
completionHandler:_authenticationSessionCompletionHandler];
_isRequestingSFAuthenticationSession = YES; _isRequestingSFAuthenticationSession = YES;
[_authenticationSession start]; [_authenticationSession start];
return;
}
} }
} }
// trying to dynamically load SFSafariViewController class - (void)_setSessionCompletionHandlerFromHandler:(void(^)(BOOL, NSError *))handler
// so for the cases when it is available we can send users through Safari View Controller flow {
// in cases it is not available regular flow will be selected __weak typeof(self) weakSelf = self;
Class SFSafariViewControllerClass = fbsdkdfl_SFSafariViewControllerClass(); _authenticationSessionCompletionHandler = ^ (NSURL *aURL, NSError *error) {
typeof(self) strongSelf = weakSelf;
if (SFSafariViewControllerClass) { strongSelf->_isRequestingSFAuthenticationSession = NO;
UIViewController *parent = fromViewController ?: [FBSDKInternalUtility topMostViewController]; handler(error == nil, error);
if (parent == nil) { if (error == nil) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors [strongSelf application:[UIApplication sharedApplication] openURL:aURL sourceApplication:@"com.apple" annotation:nil];
formatString:@"There are no valid ViewController to present SafariViewController with", nil]; }
return; strongSelf->_authenticationSession = nil;
} strongSelf->_authenticationSessionCompletionHandler = nil;
};
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSURLQueryItem *sfvcQueryItem = [[NSURLQueryItem alloc] initWithName:@"sfvc" value:@"1"];
components.queryItems = [components.queryItems arrayByAddingObject:sfvcQueryItem];
url = components.URL;
FBSDKContainerViewController *container = [[FBSDKContainerViewController alloc] init];
container.delegate = self;
if (parent.transitionCoordinator != nil) {
// Wait until the transition is finished before presenting SafariVC to avoid a blank screen.
[parent.transitionCoordinator animateAlongsideTransition:NULL completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Note SFVC init must occur inside block to avoid blank screen.
self->_safariViewController = [[SFSafariViewControllerClass alloc] initWithURL:url];
// Disable dismissing with edge pan gesture
self->_safariViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self->_safariViewController performSelector:@selector(setDelegate:) withObject:self];
[container displayChildController:self->_safariViewController];
[parent presentViewController:container animated:YES completion:nil];
}];
} else {
_safariViewController = [[SFSafariViewControllerClass alloc] initWithURL:url];
// Disable dismissing with edge pan gesture
_safariViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
[_safariViewController performSelector:@selector(setDelegate:) withObject:self];
[container displayChildController:_safariViewController];
[parent presentViewController:container animated:YES completion:nil];
}
// Assuming Safari View Controller always opens
if (handler) {
handler(YES, nil);
}
} else {
[self openURL:url sender:sender handler:handler];
}
} }
#pragma mark -- SFSafariViewControllerDelegate #pragma mark -- SFSafariViewControllerDelegate
@ -463,32 +488,32 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
// This means the user tapped "Done" which we should treat as a cancellation. // This means the user tapped "Done" which we should treat as a cancellation.
- (void)safariViewControllerDidFinish:(UIViewController *)safariViewController - (void)safariViewControllerDidFinish:(UIViewController *)safariViewController
{ {
if (_pendingURLOpen) { if (_pendingURLOpen) {
id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen; id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen;
_pendingURLOpen = nil; _pendingURLOpen = nil;
[pendingURLOpen application:nil [pendingURLOpen application:nil
openURL:nil openURL:nil
sourceApplication:nil sourceApplication:nil
annotation:nil]; annotation:nil];
} }
[self _cancelBridgeRequest]; [self _cancelBridgeRequest];
_safariViewController = nil; _safariViewController = nil;
} }
#pragma mark -- FBSDKContainerViewControllerDelegate #pragma mark -- FBSDKContainerViewControllerDelegate
- (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated - (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated
{ {
if (_safariViewController) { if (_safariViewController) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
logEntry:@"**ERROR**:\n The SFSafariViewController's parent view controller was dismissed.\n" logEntry:@"**ERROR**:\n The SFSafariViewController's parent view controller was dismissed.\n"
"This can happen if you are triggering login from a UIAlertController. Instead, make sure your top most view " "This can happen if you are triggering login from a UIAlertController. Instead, make sure your top most view "
"controller will not be prematurely dismissed."]; "controller will not be prematurely dismissed."];
[self safariViewControllerDidFinish:_safariViewController]; [self safariViewControllerDidFinish:_safariViewController];
} }
} }
#endif #endif
@ -497,113 +522,113 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
- (void)_logIfAppLinkEvent:(NSURL *)url - (void)_logIfAppLinkEvent:(NSURL *)url
{ {
if (!url) { if (!url) {
return; return;
} }
NSDictionary *params = [FBSDKUtility dictionaryWithQueryString:url.query]; NSDictionary *params = [FBSDKUtility dictionaryWithQueryString:url.query];
NSString *applinkDataString = params[@"al_applink_data"]; NSString *applinkDataString = params[@"al_applink_data"];
if (!applinkDataString) { if (!applinkDataString) {
return; return;
} }
NSDictionary *applinkData = [FBSDKInternalUtility objectForJSONString:applinkDataString error:NULL]; NSDictionary *applinkData = [FBSDKInternalUtility objectForJSONString:applinkDataString error:NULL];
if (!applinkData) { if (!applinkData) {
return; return;
} }
NSString *targetURLString = applinkData[@"target_url"]; NSString *targetURLString = applinkData[@"target_url"];
NSURL *targetURL = [targetURLString isKindOfClass:[NSString class]] ? [NSURL URLWithString:targetURLString] : nil; NSURL *targetURL = [targetURLString isKindOfClass:[NSString class]] ? [NSURL URLWithString:targetURLString] : nil;
NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; NSMutableDictionary *logData = [[NSMutableDictionary alloc] init];
[FBSDKInternalUtility dictionary:logData setObject:targetURL.absoluteString forKey:@"targetURL"]; [FBSDKInternalUtility dictionary:logData setObject:targetURL.absoluteString forKey:@"targetURL"];
[FBSDKInternalUtility dictionary:logData setObject:targetURL.host forKey:@"targetURLHost"]; [FBSDKInternalUtility dictionary:logData setObject:targetURL.host forKey:@"targetURLHost"];
NSDictionary *refererData = applinkData[@"referer_data"]; NSDictionary *refererData = applinkData[@"referer_data"];
if (refererData) { if (refererData) {
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"target_url"] forKey:@"referralTargetURL"]; [FBSDKInternalUtility dictionary:logData setObject:refererData[@"target_url"] forKey:@"referralTargetURL"];
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"url"] forKey:@"referralURL"]; [FBSDKInternalUtility dictionary:logData setObject:refererData[@"url"] forKey:@"referralURL"];
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"app_name"] forKey:@"referralAppName"]; [FBSDKInternalUtility dictionary:logData setObject:refererData[@"app_name"] forKey:@"referralAppName"];
} }
[FBSDKInternalUtility dictionary:logData setObject:url.absoluteString forKey:@"inputURL"]; [FBSDKInternalUtility dictionary:logData setObject:url.absoluteString forKey:@"inputURL"];
[FBSDKInternalUtility dictionary:logData setObject:url.scheme forKey:@"inputURLScheme"]; [FBSDKInternalUtility dictionary:logData setObject:url.scheme forKey:@"inputURLScheme"];
[FBSDKAppEvents logImplicitEvent:FBSDKAppLinkInboundEvent [FBSDKAppEvents logImplicitEvent:FBSDKAppLinkInboundEvent
valueToSum:nil valueToSum:nil
parameters:logData parameters:logData
accessToken:nil]; accessToken:nil];
} }
- (void)_logSDKInitialize - (void)_logSDKInitialize
{ {
NSMutableDictionary *params = [NSMutableDictionary new]; NSMutableDictionary *params = [NSMutableDictionary new];
params[@"core_lib_included"] = @1; params[@"core_lib_included"] = @1;
if (objc_lookUpClass("FBSDKShareDialog") != nil) { if (objc_lookUpClass("FBSDKShareDialog") != nil) {
params[@"share_lib_included"] = @1; params[@"share_lib_included"] = @1;
} }
if (objc_lookUpClass("FBSDKLoginManager") != nil) { if (objc_lookUpClass("FBSDKLoginManager") != nil) {
params[@"login_lib_included"] = @1; params[@"login_lib_included"] = @1;
} }
if (objc_lookUpClass("FBSDKPlacesManager") != nil) { if (objc_lookUpClass("FBSDKPlacesManager") != nil) {
params[@"places_lib_included"] = @1; params[@"places_lib_included"] = @1;
} }
if (objc_lookUpClass("FBSDKMessengerButton") != nil) { if (objc_lookUpClass("FBSDKMessengerButton") != nil) {
params[@"messenger_lib_included"] = @1; params[@"messenger_lib_included"] = @1;
} }
if (objc_lookUpClass("FBSDKMessengerButton") != nil) { if (objc_lookUpClass("FBSDKMessengerButton") != nil) {
params[@"messenger_lib_included"] = @1; params[@"messenger_lib_included"] = @1;
} }
if (objc_lookUpClass("FBSDKTVInterfaceFactory.m") != nil) { if (objc_lookUpClass("FBSDKTVInterfaceFactory.m") != nil) {
params[@"tv_lib_included"] = @1; params[@"tv_lib_included"] = @1;
} }
if (objc_lookUpClass("FBSDKAutoLog") != nil) { if (objc_lookUpClass("FBSDKAutoLog") != nil) {
params[@"marketing_lib_included"] = @1; params[@"marketing_lib_included"] = @1;
} }
[FBSDKAppEvents logEvent:@"fb_sdk_initialize" parameters:params]; [FBSDKAppEvents logEvent:@"fb_sdk_initialize" parameters:params];
} }
#pragma mark -- (non-tvos) #pragma mark -- (non-tvos)
#if !TARGET_OS_TV #if !TARGET_OS_TV
- (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication - (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication
{ {
FBSDKBridgeAPIRequest *request = _pendingRequest; FBSDKBridgeAPIRequest *request = _pendingRequest;
FBSDKBridgeAPICallbackBlock completionBlock = _pendingRequestCompletionBlock; FBSDKBridgeAPICallbackBlock completionBlock = _pendingRequestCompletionBlock;
_pendingRequest = nil; _pendingRequest = nil;
_pendingRequestCompletionBlock = NULL; _pendingRequestCompletionBlock = NULL;
if (![responseURL.scheme isEqualToString:[FBSDKInternalUtility appURLScheme]]) { if (![responseURL.scheme isEqualToString:[FBSDKInternalUtility appURLScheme]]) {
return NO; return NO;
} }
if (![responseURL.host isEqualToString:@"bridge"]) { if (![responseURL.host isEqualToString:@"bridge"]) {
return NO; return NO;
} }
if (!request) { if (!request) {
return NO; return NO;
} }
if (!completionBlock) { if (!completionBlock) {
return YES; return YES;
} }
NSError *error; NSError *error;
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request
responseURL:responseURL responseURL:responseURL
sourceApplication:sourceApplication sourceApplication:sourceApplication
error:&error]; error:&error];
if (response) { if (response) {
completionBlock(response); completionBlock(response);
return YES; return YES;
} else if (error) { } else if (error) {
completionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error]); completionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error]);
return YES; return YES;
} else { } else {
return NO; return NO;
} }
} }
- (void)_cancelBridgeRequest - (void)_cancelBridgeRequest
{ {
if (_pendingRequest && _pendingRequestCompletionBlock) { if (_pendingRequest && _pendingRequestCompletionBlock) {
_pendingRequestCompletionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseCancelledWithRequest:_pendingRequest]); _pendingRequestCompletionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseCancelledWithRequest:_pendingRequest]);
} }
_pendingRequest = nil; _pendingRequest = nil;
_pendingRequestCompletionBlock = NULL; _pendingRequestCompletionBlock = NULL;
} }
#endif #endif

View File

@ -185,10 +185,10 @@
- (void)configureButton - (void)configureButton
{ {
[self configureWithIcon:[[self class] defaultIcon] [self configureWithIcon:[self defaultIcon]
title:nil title:nil
backgroundColor:[[self class] defaultBackgroundColor] backgroundColor:[self defaultBackgroundColor]
highlightedColor:[[self class] defaultHighlightedColor]]; highlightedColor:[self defaultHighlightedColor]];
} }
- (void)configureWithIcon:(FBSDKIcon *)icon - (void)configureWithIcon:(FBSDKIcon *)icon
@ -215,12 +215,6 @@
selectedColor:(UIColor *)selectedColor selectedColor:(UIColor *)selectedColor
selectedHighlightedColor:(UIColor *)selectedHighlightedColor selectedHighlightedColor:(UIColor *)selectedHighlightedColor
{ {
if (!selectedColor) {
selectedColor = [self defaultSelectedColor];
}
if (!selectedHighlightedColor) {
selectedHighlightedColor = highlightedColor;
}
[self _configureWithIcon:icon [self _configureWithIcon:icon
title:title title:title
backgroundColor:backgroundColor backgroundColor:backgroundColor
@ -339,6 +333,12 @@
if (!highlightedColor) { if (!highlightedColor) {
highlightedColor = [self defaultHighlightedColor]; highlightedColor = [self defaultHighlightedColor];
} }
if (!selectedColor) {
selectedColor = [self defaultSelectedColor];
}
if (!selectedHighlightedColor) {
selectedHighlightedColor = highlightedColor;
}
self.adjustsImageWhenDisabled = NO; self.adjustsImageWhenDisabled = NO;
self.adjustsImageWhenHighlighted = NO; self.adjustsImageWhenHighlighted = NO;

View File

@ -53,5 +53,5 @@
#import <FBSDKCoreKit/FBSDKDeviceViewControllerBase.h> #import <FBSDKCoreKit/FBSDKDeviceViewControllerBase.h>
#endif #endif
#define FBSDK_VERSION_STRING @"4.39.0" #define FBSDK_VERSION_STRING @"4.40.0"
#define FBSDK_TARGET_PLATFORM_VERSION @"v3.2" #define FBSDK_TARGET_PLATFORM_VERSION @"v3.2"

View File

@ -149,8 +149,10 @@ static NSString *const kPostHTTPMethod = @"POST";
forBatch:(BOOL)forBatch { forBatch:(BOOL)forBatch {
params = [self preprocessParams: params]; params = [self preprocessParams: params];
NSCharacterSet *urlAllowedSet = [NSCharacterSet URLFragmentAllowedCharacterSet]; #pragma clang diagnostic push
NSURL *parsedURL = [NSURL URLWithString:[baseUrl stringByAddingPercentEncodingWithAllowedCharacters:urlAllowedSet]]; #pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSURL *parsedURL = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
#pragma clang pop
if ([httpMethod isEqualToString:kPostHTTPMethod] && !forBatch) { if ([httpMethod isEqualToString:kPostHTTPMethod] && !forBatch) {
return baseUrl; return baseUrl;

View File

@ -980,7 +980,7 @@ NSURLSessionDataDelegate
- (void)registerTokenToOmitFromLog:(NSString *)token - (void)registerTokenToOmitFromLog:(NSString *)token
{ {
if (![[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorAccessTokens]) { if (![FBSDKSettings.loggingBehaviors containsObject:FBSDKLoggingBehaviorAccessTokens]) {
[FBSDKLogger registerStringToReplace:token replaceWith:@"ACCESS_TOKEN_REMOVED"]; [FBSDKLogger registerStringToReplace:token replaceWith:@"ACCESS_TOKEN_REMOVED"];
} }
} }

View File

@ -208,9 +208,12 @@ FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorDeveloperErrors;
+ (NSString *)sdkVersion; + (NSString *)sdkVersion;
/** /**
Retrieve the current Facebook SDK logging behavior. The current Facebook SDK logging behavior.
*/ */
+ (NSSet *)loggingBehavior; @property (class, nonatomic, copy) NSSet<NSString *> *loggingBehaviors;
+ (NSSet *)loggingBehavior
DEPRECATED_MSG_ATTRIBUTE("Renamed `loggingBehaviors`");
/** /**
Set the current Facebook SDK logging behavior. This should consist of strings defined as Set the current Facebook SDK logging behavior. This should consist of strings defined as

View File

@ -35,6 +35,9 @@ static TYPE *g_##PLIST_KEY = nil; \
g_##PLIST_KEY = [value copy]; \ g_##PLIST_KEY = [value copy]; \
} }
#define FBSDKSETTINGS_AUTOLOG_APPEVENTS_ENABLED_USER_DEFAULTS_KEY @"com.facebook.sdk:autoLogAppEventsEnabled%@"
#define FBSDKSETTINGS_ADVERTISERID_COLLECTION_ENABLED_USER_DEFAULTS_KEY @"com.facebook.sdk:advertiserIDCollectionEnabled%@"
NSString *const FBSDKLoggingBehaviorAccessTokens = @"include_access_tokens"; NSString *const FBSDKLoggingBehaviorAccessTokens = @"include_access_tokens";
NSString *const FBSDKLoggingBehaviorPerformanceCharacteristics = @"perf_characteristics"; NSString *const FBSDKLoggingBehaviorPerformanceCharacteristics = @"perf_characteristics";
NSString *const FBSDKLoggingBehaviorAppEvents = @"app_events"; NSString *const FBSDKLoggingBehaviorAppEvents = @"app_events";
@ -47,21 +50,33 @@ NSString *const FBSDKLoggingBehaviorGraphAPIDebugInfo = @"graph_api_debug_info";
NSString *const FBSDKLoggingBehaviorNetworkRequests = @"network_requests"; NSString *const FBSDKLoggingBehaviorNetworkRequests = @"network_requests";
static NSObject<FBSDKAccessTokenCaching> *g_tokenCache; static NSObject<FBSDKAccessTokenCaching> *g_tokenCache;
static NSMutableSet *g_loggingBehavior; static NSMutableSet *g_loggingBehaviors;
static NSString *g_legacyUserDefaultTokenInformationKeyName = @"FBAccessTokenInformationKey"; static NSString *g_legacyUserDefaultTokenInformationKeyName = @"FBAccessTokenInformationKey";
static NSString *const FBSDKSettingsLimitEventAndDataUsage = @"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage"; static NSString *const FBSDKSettingsLimitEventAndDataUsage = @"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage";
static BOOL g_disableErrorRecovery; static BOOL g_disableErrorRecovery;
static NSString *g_userAgentSuffix; static NSString *g_userAgentSuffix;
static NSString *g_defaultGraphAPIVersion; static NSString *g_defaultGraphAPIVersion;
static FBSDKAccessTokenExpirer *g_accessTokenExpirer; static FBSDKAccessTokenExpirer *g_accessTokenExpirer;
static NSString *const FBSDKSettingsAutoLogAppEventsEnabled = @"FacebookAutoLogAppEventsEnabled";
static NSString *const FBSDKSettingsAdvertiserIDCollectionEnabled = @"FacebookAdvertiserIDCollectionEnabled";
static NSNumber *g_autoLogAppEventsEnabled;
static NSNumber *g_advertiserIDCollectionEnabled;
@implementation FBSDKSettings @implementation FBSDKSettings
+ (void)initialize + (void)initialize
{ {
if (self == [FBSDKSettings class]) { if (self == [FBSDKSettings class]) {
NSString *appID = [self appID];
g_tokenCache = [[FBSDKAccessTokenCache alloc] init]; g_tokenCache = [[FBSDKAccessTokenCache alloc] init];
g_accessTokenExpirer = [[FBSDKAccessTokenExpirer alloc] init]; g_accessTokenExpirer = [[FBSDKAccessTokenExpirer alloc] init];
// Fetch meta data from plist and overwrite the value with NSUserDefaults if possible
g_autoLogAppEventsEnabled = [self appEventSettingsForPlistKey:FBSDKSettingsAutoLogAppEventsEnabled defaultValue:@YES];
g_autoLogAppEventsEnabled = [self appEventSettingsForUserDefaultsKey:[NSString stringWithFormat:FBSDKSETTINGS_AUTOLOG_APPEVENTS_ENABLED_USER_DEFAULTS_KEY, appID] defaultValue:g_autoLogAppEventsEnabled];
[[NSUserDefaults standardUserDefaults] setObject:g_autoLogAppEventsEnabled forKey:[NSString stringWithFormat:FBSDKSETTINGS_AUTOLOG_APPEVENTS_ENABLED_USER_DEFAULTS_KEY, appID]];
g_advertiserIDCollectionEnabled = [self appEventSettingsForPlistKey:FBSDKSettingsAdvertiserIDCollectionEnabled defaultValue:@YES];
g_advertiserIDCollectionEnabled = [self appEventSettingsForUserDefaultsKey:[NSString stringWithFormat:FBSDKSETTINGS_ADVERTISERID_COLLECTION_ENABLED_USER_DEFAULTS_KEY, appID] defaultValue:g_advertiserIDCollectionEnabled];
[[NSUserDefaults standardUserDefaults] setObject:g_advertiserIDCollectionEnabled forKey:[NSString stringWithFormat:FBSDKSETTINGS_ADVERTISERID_COLLECTION_ENABLED_USER_DEFAULTS_KEY, appID]];
} }
} }
@ -73,12 +88,8 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookClientToken, cl
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDisplayName, displayName, setDisplayName, nil); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDisplayName, displayName, setDisplayName, nil);
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDomainPart, facebookDomainPart, setFacebookDomainPart, nil); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDomainPart, facebookDomainPart, setFacebookDomainPart, nil);
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookJpegCompressionQuality, _JPEGCompressionQualityNumber, _setJPEGCompressionQualityNumber, @0.9); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookJpegCompressionQuality, _JPEGCompressionQualityNumber, _setJPEGCompressionQualityNumber, @0.9);
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAutoLogAppEventsEnabled, autoLogAppEventsEnabled,
setAutoLogAppEventsEnabled, @1);
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLogEnabled, codelessDebugLogEnabled, FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLogEnabled, codelessDebugLogEnabled,
setCodelessDebugLogEnabled, @0); setCodelessDebugLogEnabled, @0);
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCollectionEnabled, advertiserIDCollectionEnabled,
setAdvertiserIDCollectionEnabled, @1);
+ (void)setGraphErrorRecoveryDisabled:(BOOL)disableGraphErrorRecovery { + (void)setGraphErrorRecoveryDisabled:(BOOL)disableGraphErrorRecovery {
g_disableErrorRecovery = disableGraphErrorRecovery; g_disableErrorRecovery = disableGraphErrorRecovery;
@ -114,45 +125,55 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCol
[defaults synchronize]; [defaults synchronize];
} }
+ (NSSet *)loggingBehavior + (NSSet<NSString *> *)loggingBehaviors
{ {
if (!g_loggingBehavior) { if (!g_loggingBehaviors) {
NSArray *bundleLoggingBehaviors = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FacebookLoggingBehavior"]; NSArray *bundleLoggingBehaviors = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FacebookLoggingBehavior"];
if (bundleLoggingBehaviors) { if (bundleLoggingBehaviors) {
g_loggingBehavior = [[NSMutableSet alloc] initWithArray:bundleLoggingBehaviors]; g_loggingBehaviors = [[NSMutableSet alloc] initWithArray:bundleLoggingBehaviors];
} else { } else {
// Establish set of default enabled logging behaviors. You can completely disable logging by // Establish set of default enabled logging behaviors. You can completely disable logging by
// specifying an empty array for FacebookLoggingBehavior in your Info.plist. // specifying an empty array for FacebookLoggingBehavior in your Info.plist.
g_loggingBehavior = [[NSMutableSet alloc] initWithObjects:FBSDKLoggingBehaviorDeveloperErrors, nil]; g_loggingBehaviors = [[NSMutableSet alloc] initWithObjects:FBSDKLoggingBehaviorDeveloperErrors, nil];
} }
} }
return [g_loggingBehavior copy]; return [g_loggingBehaviors copy];
} }
+ (void)setLoggingBehavior:(NSSet *)loggingBehavior + (void)setLoggingBehaviors:(NSSet<NSString *> *)loggingBehaviors
{ {
if (![g_loggingBehavior isEqualToSet:loggingBehavior]) { if (![g_loggingBehaviors isEqualToSet:loggingBehaviors]) {
g_loggingBehavior = [loggingBehavior mutableCopy]; g_loggingBehaviors = [loggingBehaviors mutableCopy];
[self updateGraphAPIDebugBehavior]; [self updateGraphAPIDebugBehavior];
} }
} }
+ (NSSet *)loggingBehavior
{
return [self loggingBehaviors];
}
+ (void)setLoggingBehavior:(NSSet *)loggingBehavior
{
[self setLoggingBehaviors:loggingBehavior];
}
+ (void)enableLoggingBehavior:(NSString *)loggingBehavior + (void)enableLoggingBehavior:(NSString *)loggingBehavior
{ {
if (!g_loggingBehavior) { if (!g_loggingBehaviors) {
[self loggingBehavior]; [self loggingBehaviors];
} }
[g_loggingBehavior addObject:loggingBehavior]; [g_loggingBehaviors addObject:loggingBehavior];
[self updateGraphAPIDebugBehavior]; [self updateGraphAPIDebugBehavior];
} }
+ (void)disableLoggingBehavior:(NSString *)loggingBehavior + (void)disableLoggingBehavior:(NSString *)loggingBehavior
{ {
if (!g_loggingBehavior) { if (!g_loggingBehaviors) {
[self loggingBehavior]; [self loggingBehaviors];
} }
[g_loggingBehavior removeObject:loggingBehavior]; [g_loggingBehaviors removeObject:loggingBehavior];
[self updateGraphAPIDebugBehavior]; [self updateGraphAPIDebugBehavior];
} }
@ -214,22 +235,68 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCol
return g_defaultGraphAPIVersion ?: FBSDK_TARGET_PLATFORM_VERSION; return g_defaultGraphAPIVersion ?: FBSDK_TARGET_PLATFORM_VERSION;
} }
+ (NSNumber *)appEventSettingsForPlistKey:(NSString *)plistKey
defaultValue:(NSNumber *)defaultValue
{
return [[[NSBundle mainBundle] objectForInfoDictionaryKey:plistKey] copy] ?: defaultValue;
}
+ (NSNumber *)appEventSettingsForUserDefaultsKey:(NSString *)userDefaultsKey
defaultValue:(NSNumber *)defaultValue
{
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:userDefaultsKey];
if ([data isKindOfClass:[NSNumber class]]) {
return (NSNumber *)data;
}
return defaultValue;
}
+ (NSNumber *)autoLogAppEventsEnabled
{
return g_autoLogAppEventsEnabled;
}
+ (void)setAutoLogAppEventsEnabled:(NSNumber *)autoLogAppEventsEnabled
{
if (autoLogAppEventsEnabled == nil || [g_autoLogAppEventsEnabled isEqual:autoLogAppEventsEnabled]) {
return;
}
g_autoLogAppEventsEnabled = [autoLogAppEventsEnabled copy];
[[NSUserDefaults standardUserDefaults] setObject:g_autoLogAppEventsEnabled forKey:[NSString stringWithFormat:FBSDKSETTINGS_AUTOLOG_APPEVENTS_ENABLED_USER_DEFAULTS_KEY, [self appID]]];
}
+ (NSNumber *)advertiserIDCollectionEnabled
{
return g_advertiserIDCollectionEnabled;
}
+ (void)setAdvertiserIDCollectionEnabled:(NSNumber *)advertiserIDCollectionEnabled
{
if (advertiserIDCollectionEnabled == nil || [g_advertiserIDCollectionEnabled isEqual:advertiserIDCollectionEnabled]) {
return;
}
g_advertiserIDCollectionEnabled = [advertiserIDCollectionEnabled copy];
[[NSUserDefaults standardUserDefaults] setObject:g_advertiserIDCollectionEnabled forKey:[NSString stringWithFormat:FBSDKSETTINGS_ADVERTISERID_COLLECTION_ENABLED_USER_DEFAULTS_KEY, [self appID]]];
}
#pragma mark - Internal - Graph API Debug #pragma mark - Internal - Graph API Debug
+ (void)updateGraphAPIDebugBehavior + (void)updateGraphAPIDebugBehavior
{ {
// Enable Warnings everytime Info is enabled // Enable Warnings everytime Info is enabled
if ([g_loggingBehavior containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo] if ([g_loggingBehaviors containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]
&& ![g_loggingBehavior containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) { && ![g_loggingBehaviors containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) {
[g_loggingBehavior addObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]; [g_loggingBehaviors addObject:FBSDKLoggingBehaviorGraphAPIDebugWarning];
} }
} }
+ (NSString *)graphAPIDebugParamValue + (NSString *)graphAPIDebugParamValue
{ {
if ([[self loggingBehavior] containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]) { if ([[self loggingBehaviors] containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]) {
return @"info"; return @"info";
} else if ([[self loggingBehavior] containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) { } else if ([[self loggingBehaviors] containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) {
return @"warning"; return @"warning";
} }

View File

@ -62,18 +62,23 @@
+ (NSString *)URLDecode:(NSString *)value + (NSString *)URLDecode:(NSString *)value
{ {
return [value value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "];
stringByReplacingOccurrencesOfString:@"+" #pragma clang diagnostic push
withString:@" "].stringByRemovingPercentEncoding; #pragma clang diagnostic ignored "-Wdeprecated-declarations"
value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
#pragma clang diagnostic pop
return value;
} }
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ (NSString *)URLEncode:(NSString *)value + (NSString *)URLEncode:(NSString *)value
{ {
NSCharacterSet *urlAllowedSet = [NSCharacterSet return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
characterSetWithCharactersInString:@" !*();:'@&=+$,/?%#[]\""].invertedSet; (CFStringRef)value,
return [value stringByAddingPercentEncodingWithAllowedCharacters:urlAllowedSet]; NULL, // characters to leave unescaped
CFSTR(":!*();@/&?+$,='"),
kCFStringEncodingUTF8);
} }
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -18,6 +18,8 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
typedef void(^FBSDKCodelessSettingLoadBlock)(BOOL isCodelessSetupEnabled, NSError *error);
@interface FBSDKCodelessIndexer : NSObject @interface FBSDKCodelessIndexer : NSObject
+ (NSString *)extInfo; + (NSString *)extInfo;

View File

@ -35,6 +35,9 @@ static BOOL _isCodelessIndexing;
static BOOL _isCheckingSession; static BOOL _isCheckingSession;
static BOOL _isCodelessIndexingEnabled; static BOOL _isCodelessIndexingEnabled;
static NSMutableDictionary<NSString *, id> *_codelessSetting;
static const NSTimeInterval kTimeout = 4.0;
static NSString *_deviceSessionID; static NSString *_deviceSessionID;
static NSTimer *_appIndexingTimer; static NSTimer *_appIndexingTimer;
static NSString *_lastTreeHash; static NSString *_lastTreeHash;
@ -44,14 +47,95 @@ static NSString *_lastTreeHash;
#if TARGET_OS_SIMULATOR #if TARGET_OS_SIMULATOR
[self setupGesture]; [self setupGesture];
#else #else
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *error) { [self loadCodelessSettingWithCompletionBlock:^(BOOL isCodelessSetupEnabled, NSError *error) {
if (serverConfiguration.codelessSetupEnabled) { if (isCodelessSetupEnabled) {
[self setupGesture]; [self setupGesture];
} }
}]; }];
#endif #endif
} }
// DO NOT call this function, it is only called once in the load function
+ (void)loadCodelessSettingWithCompletionBlock:(FBSDKCodelessSettingLoadBlock)completionBlock
{
NSString *appID = [FBSDKSettings appID];
if (appID == nil) {
return;
}
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *serverConfigurationLoadingError) {
if (!serverConfiguration.codelessEventsEnabled) {
return;
}
// load the defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *defaultKey = [NSString stringWithFormat:CODELESS_SETTING_KEY, appID];
NSData *data = [defaults objectForKey:defaultKey];
if ([data isKindOfClass:[NSData class]]) {
NSMutableDictionary<NSString *, id> *codelessSetting = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if (codelessSetting) {
_codelessSetting = codelessSetting;
}
}
if (!_codelessSetting) {
_codelessSetting = [[NSMutableDictionary alloc] init];
}
if (![self _codelessSetupTimestampIsValid:[_codelessSetting objectForKey:CODELESS_SETTING_TIMESTAMP_KEY]]) {
FBSDKGraphRequest *request = [self requestToLoadCodelessSetup:appID];
if (request == nil) {
return;
}
FBSDKGraphRequestConnection *requestConnection = [[FBSDKGraphRequestConnection alloc] init];
requestConnection.timeout = kTimeout;
[requestConnection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *codelessLoadingError) {
if (codelessLoadingError) {
return;
}
NSDictionary<NSString *, id> *resultDictionary = [FBSDKTypeUtility dictionaryValue:result];
if (resultDictionary) {
BOOL isCodelessSetupEnabled = [FBSDKTypeUtility boolValue:resultDictionary[CODELESS_SETUP_ENABLED_FIELD]];
[_codelessSetting setObject:@(isCodelessSetupEnabled) forKey:CODELESS_SETUP_ENABLED_KEY];
[_codelessSetting setObject:[NSDate date] forKey:CODELESS_SETTING_TIMESTAMP_KEY];
// update the cached copy in user defaults
[defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:_codelessSetting] forKey:defaultKey];
completionBlock(isCodelessSetupEnabled, codelessLoadingError);
}
}];
[requestConnection start];
} else {
completionBlock([FBSDKTypeUtility boolValue:[_codelessSetting objectForKey:CODELESS_SETUP_ENABLED_KEY]], nil);
}
}];
}
+ (FBSDKGraphRequest *)requestToLoadCodelessSetup:(NSString *)appID
{
NSString *advertiserID = [FBSDKAppEventsUtility advertiserID];
if (!advertiserID) {
return nil;
}
NSDictionary<NSString *, NSString *> *parameters = @{
@"fields": CODELESS_SETUP_ENABLED_FIELD,
@"advertiser_id": advertiserID
};
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:appID
parameters:parameters
tokenString:nil
HTTPMethod:nil
flags:FBSDKGraphRequestFlagSkipClientToken | FBSDKGraphRequestFlagDisableErrorRecovery];
return request;
}
+ (BOOL)_codelessSetupTimestampIsValid:(NSDate *)timestamp
{
return (timestamp != nil && [[NSDate date] timeIntervalSinceDate:timestamp] < CODELESS_SETTING_CACHE_TIMEOUT);
}
+ (void)setupGesture + (void)setupGesture
{ {
[UIApplication sharedApplication].applicationSupportsShakeToEdit = YES; [UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;
@ -64,8 +148,6 @@ static NSString *_lastTreeHash;
} named:@"motionBegan"]; } named:@"motionBegan"];
} }
+ (void)checkCodelessIndexingSession + (void)checkCodelessIndexingSession
{ {
if (_isCheckingSession) return; if (_isCheckingSession) return;

View File

@ -58,6 +58,12 @@
#define CODELESS_INDEXING_ENDPOINT @"app_indexing" #define CODELESS_INDEXING_ENDPOINT @"app_indexing"
#define CODELESS_INDEXING_SESSION_ENDPOINT @"app_indexing_session" #define CODELESS_INDEXING_SESSION_ENDPOINT @"app_indexing_session"
#define CODELESS_SETUP_ENABLED_FIELD @"auto_event_setup_enabled"
#define CODELESS_SETUP_ENABLED_KEY @"codeless_setup_enabled"
#define CODELESS_SETTING_KEY @"com.facebook.sdk:codelessSetting%@"
#define CODELESS_SETTING_TIMESTAMP_KEY @"codeless_setting_timestamp"
#define CODELESS_SETTING_CACHE_TIMEOUT (7 * 24 * 60 * 60)
// keys for view tree // keys for view tree
#define CODELESS_VIEW_TREE_CLASS_NAME_KEY @"classname" #define CODELESS_VIEW_TREE_CLASS_NAME_KEY @"classname"
#define CODELESS_VIEW_TREE_CLASS_TYPE_BIT_MASK_KEY @"classtypebitmask" #define CODELESS_VIEW_TREE_CLASS_TYPE_BIT_MASK_KEY @"classtypebitmask"

View File

@ -30,12 +30,12 @@
#import "FBSDKViewHierarchy.h" #import "FBSDKViewHierarchy.h"
#define ReactNativeTargetKey @"target" #define ReactNativeTargetKey @"target"
#define ReactNativeTouchEndEventName @"topTouchEnd" #define ReactNativeTouchEndEventName @"touchEnd"
#define ReactNativeClassRCTTextView "RCTTextView" #define ReactNativeClassRCTTextView "RCTTextView"
#define ReactNativeClassRCTImageView "RCTImageVIew" #define ReactNativeClassRCTImageView "RCTImageVIew"
#define ReactNativeClassRCTEventDispatcher "RCTEventDispatcher"
#define ReactNativeClassRCTTouchEvent "RCTTouchEvent" #define ReactNativeClassRCTTouchEvent "RCTTouchEvent"
#define ReactNativeClassRCTTouchHandler "RCTTouchHandler"
static void fb_dispatch_on_main_thread(dispatch_block_t block) { static void fb_dispatch_on_main_thread(dispatch_block_t block) {
dispatch_async(dispatch_get_main_queue(), block); dispatch_async(dispatch_get_main_queue(), block);
@ -139,13 +139,12 @@ static void fb_dispatch_on_default_thread(dispatch_block_t block) {
onClass:[UIControl class] onClass:[UIControl class]
withBlock:blockToWindow named:@"map_control"]; withBlock:blockToWindow named:@"map_control"];
// ReactNative // ReactNative
if (hasReactNative) { // If app is built via ReactNative if (hasReactNative) { // If app is built via ReactNative
Class classRCTView = objc_lookUpClass(ReactNativeClassRCTView); Class classRCTView = objc_lookUpClass(ReactNativeClassRCTView);
Class classRCTTextView = objc_lookUpClass(ReactNativeClassRCTTextView); Class classRCTTextView = objc_lookUpClass(ReactNativeClassRCTTextView);
Class classRCTImageView = objc_lookUpClass(ReactNativeClassRCTImageView); Class classRCTImageView = objc_lookUpClass(ReactNativeClassRCTImageView);
Class classRCTEventDispatcher = objc_lookUpClass(ReactNativeClassRCTEventDispatcher); Class classRCTTouchHandler = objc_lookUpClass(ReactNativeClassRCTTouchHandler);
// All react-native views would be added tp RCTRootView, so no need to check didMoveToWindow // All react-native views would be added tp RCTRootView, so no need to check didMoveToWindow
[FBSDKSwizzler swizzleSelector:@selector(didMoveToSuperview) [FBSDKSwizzler swizzleSelector:@selector(didMoveToSuperview)
@ -161,17 +160,26 @@ static void fb_dispatch_on_default_thread(dispatch_block_t block) {
withBlock:blockToSuperview withBlock:blockToSuperview
named:@"match_react_native"]; named:@"match_react_native"];
[FBSDKSwizzler swizzleSelector:@selector(dispatchEvent:) onClass:classRCTEventDispatcher withBlock:^(id dispatcher, SEL command, id event){ // RCTTouchHandler handles with touch events, like touchEnd and uses RCTEventDispather to dispatch events, so we can check _updateAndDispatchTouches to fire events
if ([event isKindOfClass:objc_lookUpClass(ReactNativeClassRCTTouchEvent)]) { [FBSDKSwizzler swizzleSelector:@selector(_updateAndDispatchTouches:eventName:) onClass:classRCTTouchHandler withBlock:^(id touchHandler, SEL command, id touches, id eventName){
if ([touches isKindOfClass:[NSSet class]] && [eventName isKindOfClass:[NSString class]]) {
@try { @try {
NSArray<id> *eventArgs = [event arguments]; NSString *reactEventName = (NSString *)eventName;
NSString *eventName = eventArgs[0]; NSSet<UITouch *> *reactTouches = (NSSet<UITouch *> *)touches;
NSArray<NSDictionary *> *touches = eventArgs[1]; if ([reactEventName isEqualToString:ReactNativeTouchEndEventName]) {
if (eventName && touches && [eventName isEqualToString:ReactNativeTouchEndEventName]) { for (UITouch *touch in reactTouches) {
for (NSDictionary<NSString *, id> *touch in touches) { UIView *targetView = ((UITouch *)touch).view.superview;
NSNumber *targetTag = touch[ReactNativeTargetKey]; NSNumber *reactTag = nil;
FBSDKEventBinding *eventBinding = self->reactBindings[targetTag]; // Find the closest React-managed touchable view like RCTTouchHandler
if (eventBinding) { while(targetView) {
reactTag = [FBSDKViewHierarchy getViewReactTag:targetView];
if (reactTag != nil && targetView.userInteractionEnabled) {
break;
}
targetView = targetView.superview;
}
FBSDKEventBinding *eventBinding = self->reactBindings[reactTag];
if (reactTag != nil && eventBinding != nil) {
[eventBinding trackEvent:nil]; [eventBinding trackEvent:nil];
} }
} }
@ -290,11 +298,8 @@ static void fb_dispatch_on_default_thread(dispatch_block_t block) {
for (FBSDKEventBinding *binding in self->eventBindings) { for (FBSDKEventBinding *binding in self->eventBindings) {
if ([FBSDKEventBinding isPath:binding.path matchViewPath:path]) { if ([FBSDKEventBinding isPath:binding.path matchViewPath:path]) {
fb_dispatch_on_main_thread(^{ fb_dispatch_on_main_thread(^{
// React Native touchable event is targeted at first subview, if (view) {
// so extract the first subview and set the binding for it NSNumber *reactTag = [FBSDKViewHierarchy getViewReactTag:view];
UIView *reactView = view.subviews.firstObject;
if (reactView) {
NSNumber *reactTag = [FBSDKViewHierarchy getViewReactTag:reactView];
if (reactTag != nil) { if (reactTag != nil) {
self->reactBindings[reactTag] = binding; self->reactBindings[reactTag] = binding;
} }

View File

@ -492,13 +492,16 @@ typedef NS_ENUM(NSUInteger, FBCodelessClassBitmask) {
[view respondsToSelector:@selector(reactTagAtPoint:)] && [view respondsToSelector:@selector(reactTagAtPoint:)] &&
[view respondsToSelector:@selector(reactTag)] && [view respondsToSelector:@selector(reactTag)] &&
view.userInteractionEnabled) { view.userInteractionEnabled) {
NSNumber *reactTag = [view performSelector:@selector(reactTagAtPoint:) // We check all its subviews locations and the view is clickable if there exists one that mathces reactTagAtPoint
withObject:[NSValue valueWithCGPoint:view.frame.origin]]; for (UIView *subview in view.subviews) {
// We get the reactTag at upper left of the view and thus check with its first subview if (subview && ![subview isKindOfClass:classRCTView]) {
UIView *subView = view.subviews.firstObject; NSNumber *reactTag = [view performSelector:@selector(reactTagAtPoint:)
NSNumber *subViewReactTag = [FBSDKViewHierarchy getViewReactTag:subView]; withObject:[NSValue valueWithCGPoint:subview.frame.origin]];
if (reactTag != nil && subViewReactTag != nil && ![subView isKindOfClass:classRCTView] && [reactTag isEqualToNumber:subViewReactTag]) { NSNumber *subviewReactTag = [FBSDKViewHierarchy getViewReactTag:subview];
return YES; if (reactTag != nil && subviewReactTag != nil && [reactTag isEqualToNumber:subviewReactTag]) {
return YES;
}
}
} }
} }

View File

@ -211,7 +211,7 @@
{ {
NSString *behaviorToLog = FBSDKLoggingBehaviorAppEvents; NSString *behaviorToLog = FBSDKLoggingBehaviorAppEvents;
if (allowLogAsDeveloperError) { if (allowLogAsDeveloperError) {
if ([[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorDeveloperErrors]) { if ([FBSDKSettings.loggingBehaviors containsObject:FBSDKLoggingBehaviorDeveloperErrors]) {
// Rather than log twice, prefer 'DeveloperErrors' if it's set over AppEvents. // Rather than log twice, prefer 'DeveloperErrors' if it's set over AppEvents.
behaviorToLog = FBSDKLoggingBehaviorDeveloperErrors; behaviorToLog = FBSDKLoggingBehaviorDeveloperErrors;
} }

View File

@ -33,6 +33,8 @@ static NSString *const FBSDKAppEventParameterNameProductTitle = @"fb_content_tit
static NSString *const FBSDKAppEventParameterNameTransactionID = @"fb_transaction_id"; static NSString *const FBSDKAppEventParameterNameTransactionID = @"fb_transaction_id";
static NSString *const FBSDKAppEventParameterNameTransactionDate = @"fb_transaction_date"; static NSString *const FBSDKAppEventParameterNameTransactionDate = @"fb_transaction_date";
static NSString *const FBSDKAppEventParameterNameSubscriptionPeriod = @"fb_iap_subs_period"; static NSString *const FBSDKAppEventParameterNameSubscriptionPeriod = @"fb_iap_subs_period";
static NSString *const FBSDKAppEventParameterNameTrialPeriod = @"fb_iap_trial_period";
static NSString *const FBSDKAppEventParameterNameTrialPrice = @"fb_iap_trial_price";
static int const FBSDKMaxParameterValueLength = 100; static int const FBSDKMaxParameterValueLength = 100;
static NSMutableArray *g_pendingRequestors; static NSMutableArray *g_pendingRequestors;
@ -235,23 +237,21 @@ static NSMutableArray *g_pendingRequestors;
FBSDKAppEventParameterNameProductTitle: [self getTruncatedString:product.localizedTitle], FBSDKAppEventParameterNameProductTitle: [self getTruncatedString:product.localizedTitle],
FBSDKAppEventParameterNameDescription: [self getTruncatedString:product.localizedDescription], FBSDKAppEventParameterNameDescription: [self getTruncatedString:product.localizedDescription],
}]; }];
#if !TARGET_OS_TV #if !TARGET_OS_TV
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_2 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_2
if (@available(iOS 11.2, *)) { if (@available(iOS 11.2, *)) {
BOOL isSubscription = (product.subscriptionPeriod != nil) && ((unsigned long)product.subscriptionPeriod.numberOfUnits > 0); BOOL isSubscription = (product.subscriptionPeriod != nil) && ((unsigned long)product.subscriptionPeriod.numberOfUnits > 0);
if (isSubscription) { if (isSubscription) {
// subs inapp // subs inapp
SKProductSubscriptionPeriod *period = product.subscriptionPeriod; eventParameters[FBSDKAppEventParameterNameSubscriptionPeriod] = [self lengthOfSubscriptionPeriod:product.subscriptionPeriod];
NSString *unit = nil;
switch (period.unit) {
case SKProductPeriodUnitDay: unit = @"D"; break;
case SKProductPeriodUnitWeek: unit = @"W"; break;
case SKProductPeriodUnitMonth: unit = @"M"; break;
case SKProductPeriodUnitYear: unit = @"Y"; break;
}
NSString *p = [NSString stringWithFormat:@"P%lu%@", (unsigned long)period.numberOfUnits, unit];
eventParameters[FBSDKAppEventParameterNameSubscriptionPeriod] = p;
eventParameters[FBSDKAppEventParameterNameInAppPurchaseType] = @"subs"; eventParameters[FBSDKAppEventParameterNameInAppPurchaseType] = @"subs";
// trial information for subs
SKProductDiscount *discount = product.introductoryPrice;
if (discount) {
eventParameters[FBSDKAppEventParameterNameTrialPeriod] = [self lengthOfSubscriptionPeriod:discount.subscriptionPeriod];
eventParameters[FBSDKAppEventParameterNameTrialPrice] = discount.price;
}
} else { } else {
eventParameters[FBSDKAppEventParameterNameInAppPurchaseType] = @"inapp"; eventParameters[FBSDKAppEventParameterNameInAppPurchaseType] = @"inapp";
} }
@ -268,6 +268,28 @@ static NSMutableArray *g_pendingRequestors;
parameters:eventParameters]; parameters:eventParameters];
} }
- (NSString *)lengthOfSubscriptionPeriod:(id)subcriptionPeriod
{
#if !TARGET_OS_TV
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_2
if (@available(iOS 11.2, *)) {
if (subcriptionPeriod && [subcriptionPeriod isKindOfClass:[SKProductSubscriptionPeriod class]]) {
SKProductSubscriptionPeriod *period = (SKProductSubscriptionPeriod *)subcriptionPeriod;
NSString *unit = nil;
switch (period.unit) {
case SKProductPeriodUnitDay: unit = @"D"; break;
case SKProductPeriodUnitWeek: unit = @"W"; break;
case SKProductPeriodUnitMonth: unit = @"M"; break;
case SKProductPeriodUnitYear: unit = @"Y"; break;
}
return [NSString stringWithFormat:@"P%lu%@", (unsigned long)period.numberOfUnits, unit];
}
}
#endif
#endif
return nil;
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{ {
NSArray* products = response.products; NSArray* products = response.products;

View File

@ -182,6 +182,10 @@ FOUNDATION_EXPORT Class fbsdkdfl_ASIdentifierManagerClass(void);
FOUNDATION_EXPORT Class fbsdkdfl_SFSafariViewControllerClass(void); FOUNDATION_EXPORT Class fbsdkdfl_SFSafariViewControllerClass(void);
FOUNDATION_EXPORT Class fbsdkdfl_SFAuthenticationSessionClass(void); FOUNDATION_EXPORT Class fbsdkdfl_SFAuthenticationSessionClass(void);
#pragma mark - AuthenticationServices Classes
FOUNDATION_EXPORT Class fbsdkdfl_ASWebAuthenticationSessionClass(void);
#pragma mark - Accounts Constants #pragma mark - Accounts Constants
FOUNDATION_EXPORT NSString *fbsdkdfl_ACFacebookAppIdKey(void); FOUNDATION_EXPORT NSString *fbsdkdfl_ACFacebookAppIdKey(void);

View File

@ -38,7 +38,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
- (instancetype)initWithLoggingBehavior:(NSString *)loggingBehavior - (instancetype)initWithLoggingBehavior:(NSString *)loggingBehavior
{ {
if ((self = [super init])) { if ((self = [super init])) {
_isActive = [[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]; _isActive = [FBSDKSettings.loggingBehaviors containsObject:loggingBehavior];
_loggingBehavior = loggingBehavior; _loggingBehavior = loggingBehavior;
if (_isActive) { if (_isActive) {
_internalContents = [[NSMutableString alloc] init]; _internalContents = [[NSMutableString alloc] init];
@ -124,7 +124,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
+ (void)singleShotLogEntry:(NSString *)loggingBehavior + (void)singleShotLogEntry:(NSString *)loggingBehavior
logEntry:(NSString *)logEntry { logEntry:(NSString *)logEntry {
if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) { if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) {
FBSDKLogger *logger = [[FBSDKLogger alloc] initWithLoggingBehavior:loggingBehavior]; FBSDKLogger *logger = [[FBSDKLogger alloc] initWithLoggingBehavior:loggingBehavior];
[logger appendString:logEntry]; [logger appendString:logEntry];
[logger emitToNSLog]; [logger emitToNSLog];
@ -134,7 +134,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
+ (void)singleShotLogEntry:(NSString *)loggingBehavior + (void)singleShotLogEntry:(NSString *)loggingBehavior
formatString:(NSString *)formatString, ... { formatString:(NSString *)formatString, ... {
if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) { if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) {
va_list vaArguments; va_list vaArguments;
va_start(vaArguments, formatString); va_start(vaArguments, formatString);
NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments]; NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments];
@ -149,7 +149,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
timestampTag:(NSObject *)timestampTag timestampTag:(NSObject *)timestampTag
formatString:(NSString *)formatString, ... { formatString:(NSString *)formatString, ... {
if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) { if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) {
va_list vaArguments; va_list vaArguments;
va_start(vaArguments, formatString); va_start(vaArguments, formatString);
NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments]; NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments];
@ -177,7 +177,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
+ (void)registerCurrentTime:(NSString *)loggingBehavior + (void)registerCurrentTime:(NSString *)loggingBehavior
withTag:(NSObject *)timestampTag { withTag:(NSObject *)timestampTag {
if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) { if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) {
if (!g_startTimesWithTags) { if (!g_startTimesWithTags) {
g_startTimesWithTags = [[NSMutableDictionary alloc] init]; g_startTimesWithTags = [[NSMutableDictionary alloc] init];
@ -203,7 +203,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
// Strings sent in here never get cleaned up, but that's OK, don't ever expect too many. // Strings sent in here never get cleaned up, but that's OK, don't ever expect too many.
if ([FBSDKSettings loggingBehavior].count > 0) { // otherwise there's no logging. if (FBSDKSettings.loggingBehaviors.count > 0) { // otherwise there's no logging.
if (!g_stringsToReplace) { if (!g_stringsToReplace) {
g_stringsToReplace = [[NSMutableDictionary alloc] init]; g_stringsToReplace = [[NSMutableDictionary alloc] init];

View File

@ -136,10 +136,12 @@ static FBSDKSystemAccountStoreAdapter *_singletonInstance = nil;
} }
} }
// construct access options // Construct access options. Constructing this way is tolerant for nil values.
NSDictionary<NSString *, id> *options = @{fbsdkdfl_ACFacebookAppIdKey(): appID, NSMutableDictionary<NSString *, id> *optionsMutable = [[NSMutableDictionary alloc] initWithCapacity:3];
fbsdkdfl_ACFacebookPermissionsKey(): permissions.allObjects, optionsMutable[fbsdkdfl_ACFacebookAppIdKey()] = appID;
fbsdkdfl_ACFacebookAudienceKey(): defaultAudience}; optionsMutable[fbsdkdfl_ACFacebookPermissionsKey()] = permissions.allObjects;
optionsMutable[fbsdkdfl_ACFacebookAudienceKey()] = defaultAudience;
NSDictionary<NSString *, id> *options = [optionsMutable copy];
if (self.forceBlockingRenew if (self.forceBlockingRenew
&& [self.accountStore accountsWithAccountType:self.accountType].count > 0) { && [self.accountStore accountsWithAccountType:self.accountType].count > 0) {

View File

@ -150,7 +150,9 @@ static NSString *const kErrorCategoryLogin = @"login";
- (id)initWithCoder:(NSCoder *)decoder - (id)initWithCoder:(NSCoder *)decoder
{ {
NSDictionary *configurationDictionary = [decoder decodeObjectOfClass:[NSDictionary class] forKey:FBSDKERRORCONFIGURATION_DICTIONARY_KEY]; NSSet *classes = [[NSSet alloc] initWithObjects:[NSDictionary class], [FBSDKErrorRecoveryConfiguration class], nil];
NSDictionary *configurationDictionary = [decoder decodeObjectOfClasses:classes
forKey:FBSDKERRORCONFIGURATION_DICTIONARY_KEY];
return [self initWithDictionary:configurationDictionary]; return [self initWithDictionary:configurationDictionary];
} }

View File

@ -99,10 +99,8 @@ static BOOL _requeryFinishedForAppStart;
+ (FBSDKGraphRequest *)requestToLoadGateKeepers:(NSString *)appID + (FBSDKGraphRequest *)requestToLoadGateKeepers:(NSString *)appID
{ {
NSString *sdkVersion = [FBSDKSettings sdkVersion]; NSString *sdkVersion = [FBSDKSettings sdkVersion];
NSString *advertiserID = [FBSDKAppEventsUtility advertiserID] ?: @"";
NSDictionary<NSString *, NSString *> *parameters = @{ @"platform": @"ios" , NSDictionary<NSString *, NSString *> *parameters = @{ @"platform": @"ios" ,
@"device_id": advertiserID,
@"sdk_version": sdkVersion, @"sdk_version": sdkVersion,
@"fields": FBSDK_GATEKEEPER_APP_GATEKEEPER_FIELDS}; @"fields": FBSDK_GATEKEEPER_APP_GATEKEEPER_FIELDS};

View File

@ -72,7 +72,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
smartLoginMenuIconURL:(NSURL *)smartLoginMenuIconURL smartLoginMenuIconURL:(NSURL *)smartLoginMenuIconURL
updateMessage:(NSString *)updateMessage updateMessage:(NSString *)updateMessage
eventBindings:(NSArray *)eventBindings eventBindings:(NSArray *)eventBindings
codelessSetupEnabled:(BOOL)codelessSetupEnabled
NS_DESIGNATED_INITIALIZER; NS_DESIGNATED_INITIALIZER;
@property (nonatomic, assign, readonly, getter=isAdvertisingIDEnabled) BOOL advertisingIDEnabled; @property (nonatomic, assign, readonly, getter=isAdvertisingIDEnabled) BOOL advertisingIDEnabled;
@ -97,7 +96,6 @@ NS_DESIGNATED_INITIALIZER;
@property (nonatomic, copy, readonly) NSURL *smartLoginMenuIconURL; @property (nonatomic, copy, readonly) NSURL *smartLoginMenuIconURL;
@property (nonatomic, copy, readonly) NSString *updateMessage; @property (nonatomic, copy, readonly) NSString *updateMessage;
@property (nonatomic, copy, readonly) NSArray *eventBindings; @property (nonatomic, copy, readonly) NSArray *eventBindings;
@property (nonatomic, assign, readonly, getter=isCodelessSetupEnabled) BOOL codelessSetupEnabled;
@property (nonatomic, readonly) NSInteger version; @property (nonatomic, readonly) NSInteger version;
- (FBSDKDialogConfiguration *)dialogConfigurationForDialogName:(NSString *)dialogName; - (FBSDKDialogConfiguration *)dialogConfigurationForDialogName:(NSString *)dialogName;

View File

@ -43,7 +43,6 @@
#define FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_KEY @"smarstLoginBookmarkMenuURL" #define FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_KEY @"smarstLoginBookmarkMenuURL"
#define FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_KEY @"SDKUpdateMessage" #define FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_KEY @"SDKUpdateMessage"
#define FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS @"eventBindings" #define FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS @"eventBindings"
#define FBSDK_SERVER_CONFIGURATION_CODELESS_SETUP_ENABLED_KEY @"codelessSetupEnabled"
#define FBSDK_SERVER_CONFIGURATION_VERSION_KEY @"version" #define FBSDK_SERVER_CONFIGURATION_VERSION_KEY @"version"
#define FBSDK_SERVER_CONFIGURATION_TRACK_UNINSTALL_ENABLED_KEY @"trackAppUninstallEnabled" #define FBSDK_SERVER_CONFIGURATION_TRACK_UNINSTALL_ENABLED_KEY @"trackAppUninstallEnabled"
@ -102,7 +101,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
smartLoginMenuIconURL:(NSURL *)smartLoginMenuIconURL smartLoginMenuIconURL:(NSURL *)smartLoginMenuIconURL
updateMessage:(NSString *)updateMessage updateMessage:(NSString *)updateMessage
eventBindings:(NSArray *)eventBindings eventBindings:(NSArray *)eventBindings
codelessSetupEnabled:(BOOL)codelessSetupEnabled
{ {
if ((self = [super init])) { if ((self = [super init])) {
_appID = [appID copy]; _appID = [appID copy];
@ -129,7 +127,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
_smartLoginBookmarkIconURL = [smartLoginBookmarkIconURL copy]; _smartLoginBookmarkIconURL = [smartLoginBookmarkIconURL copy];
_updateMessage = [updateMessage copy]; _updateMessage = [updateMessage copy];
_eventBindings = eventBindings; _eventBindings = eventBindings;
_codelessSetupEnabled = codelessSetupEnabled;
_version = FBSDKServerConfigurationVersion; _version = FBSDKServerConfigurationVersion;
} }
return self; return self;
@ -215,7 +212,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
NSURL *smartLoginMenuIconURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_KEY]; NSURL *smartLoginMenuIconURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_KEY];
NSString *updateMessage = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_KEY]; NSString *updateMessage = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_KEY];
NSArray *eventBindings = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS]; NSArray *eventBindings = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS];
BOOL codelessSetupEnabled = [decoder decodeBoolForKey:FBSDK_SERVER_CONFIGURATION_CODELESS_SETUP_ENABLED_KEY];
NSInteger version = [decoder decodeIntegerForKey:FBSDK_SERVER_CONFIGURATION_VERSION_KEY]; NSInteger version = [decoder decodeIntegerForKey:FBSDK_SERVER_CONFIGURATION_VERSION_KEY];
FBSDKServerConfiguration *configuration = [self initWithAppID:appID FBSDKServerConfiguration *configuration = [self initWithAppID:appID
appName:appName appName:appName
@ -241,7 +237,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
smartLoginMenuIconURL:smartLoginMenuIconURL smartLoginMenuIconURL:smartLoginMenuIconURL
updateMessage:updateMessage updateMessage:updateMessage
eventBindings:eventBindings eventBindings:eventBindings
codelessSetupEnabled:codelessSetupEnabled
]; ];
configuration->_version = version; configuration->_version = version;
return configuration; return configuration;
@ -275,7 +270,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
[encoder encodeObject:_smartLoginMenuIconURL forKey:FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_KEY]; [encoder encodeObject:_smartLoginMenuIconURL forKey:FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_KEY];
[encoder encodeObject:_updateMessage forKey:FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_KEY]; [encoder encodeObject:_updateMessage forKey:FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_KEY];
[encoder encodeObject:_eventBindings forKey:FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS]; [encoder encodeObject:_eventBindings forKey:FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS];
[encoder encodeBool:_codelessSetupEnabled forKey:FBSDK_SERVER_CONFIGURATION_CODELESS_SETUP_ENABLED_KEY];
[encoder encodeInteger:_version forKey:FBSDK_SERVER_CONFIGURATION_VERSION_KEY]; [encoder encodeInteger:_version forKey:FBSDK_SERVER_CONFIGURATION_VERSION_KEY];
} }

View File

@ -55,7 +55,6 @@
#define FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD @"smart_login_menu_icon_url" #define FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD @"smart_login_menu_icon_url"
#define FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD @"sdk_update_message" #define FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD @"sdk_update_message"
#define FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD @"auto_event_mapping_ios" #define FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD @"auto_event_mapping_ios"
#define FBSDK_SERVER_CONFIGURATION_CODELESS_SETUP_ENABLED_FIELD @"auto_event_setup_enabled"
@implementation FBSDKServerConfigurationManager @implementation FBSDKServerConfigurationManager
@ -208,7 +207,6 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
NSURL *smartLoginMenuIconURL = [FBSDKTypeUtility URLValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD]]; NSURL *smartLoginMenuIconURL = [FBSDKTypeUtility URLValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD]];
NSString *updateMessage = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD]]; NSString *updateMessage = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD]];
NSArray *eventBindings = [FBSDKTypeUtility arrayValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD]]; NSArray *eventBindings = [FBSDKTypeUtility arrayValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD]];
BOOL codelessSetupEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_CODELESS_SETUP_ENABLED_FIELD]];
FBSDKServerConfiguration *serverConfiguration = [[FBSDKServerConfiguration alloc] initWithAppID:appID FBSDKServerConfiguration *serverConfiguration = [[FBSDKServerConfiguration alloc] initWithAppID:appID
appName:appName appName:appName
loginTooltipEnabled:loginTooltipEnabled loginTooltipEnabled:loginTooltipEnabled
@ -233,7 +231,6 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
smartLoginMenuIconURL:smartLoginMenuIconURL smartLoginMenuIconURL:smartLoginMenuIconURL
updateMessage:updateMessage updateMessage:updateMessage
eventBindings:eventBindings eventBindings:eventBindings
codelessSetupEnabled:codelessSetupEnabled
]; ];
#if TARGET_OS_TV #if TARGET_OS_TV
// don't download icons more than once a day. // don't download icons more than once a day.
@ -278,7 +275,6 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
FBSDK_SERVER_CONFIGURATION_LOGGIN_TOKEN_FIELD FBSDK_SERVER_CONFIGURATION_LOGGIN_TOKEN_FIELD
#if !TARGET_OS_TV #if !TARGET_OS_TV
,FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD ,FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD
,FBSDK_SERVER_CONFIGURATION_CODELESS_SETUP_ENABLED_FIELD
#endif #endif
#ifdef DEBUG #ifdef DEBUG
,FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD ,FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD
@ -289,10 +285,7 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD
#endif #endif
]; ];
NSString *advertiserID = [FBSDKAppEventsUtility advertiserID] ?: @""; NSDictionary<NSString *, NSString *> *parameters = @{ @"fields": [fields componentsJoinedByString:@","]};
NSDictionary<NSString *, NSString *> *parameters = @{ @"fields": [fields componentsJoinedByString:@","],
@"advertiser_id": advertiserID
};
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:appID FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:appID
parameters:parameters parameters:parameters
@ -349,7 +342,6 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
smartLoginMenuIconURL:nil smartLoginMenuIconURL:nil
updateMessage:nil updateMessage:nil
eventBindings:nil eventBindings:nil
codelessSetupEnabled:NO
]; ];
} }
return _defaultServerConfiguration; return _defaultServerConfiguration;

View File

@ -90,7 +90,8 @@ static FBSDKWebDialog *g_currentDialog = nil;
return NO; return NO;
} }
_dialogView = [[FBSDKWebDialogView alloc] initWithFrame:window.screen.bounds]; CGRect frame = [self _applicationFrameForOrientation];
_dialogView = [[FBSDKWebDialogView alloc] initWithFrame:frame];
_dialogView.delegate = self; _dialogView.delegate = self;
[_dialogView loadURL:URL]; [_dialogView loadURL:URL];
@ -243,7 +244,6 @@ static FBSDKWebDialog *g_currentDialog = nil;
_backgroundView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); _backgroundView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
_backgroundView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:0.8]; _backgroundView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:0.8];
[window addSubview:_backgroundView]; [window addSubview:_backgroundView];
[window addSubview:_dialogView]; [window addSubview:_dialogView];
[_dialogView becomeFirstResponder]; // dismisses the keyboard if it there was another first responder with it [_dialogView becomeFirstResponder]; // dismisses the keyboard if it there was another first responder with it
@ -280,6 +280,22 @@ static FBSDKWebDialog *g_currentDialog = nil;
- (CGRect)_applicationFrameForOrientation - (CGRect)_applicationFrameForOrientation
{ {
CGRect applicationFrame = _dialogView.window.screen.bounds; CGRect applicationFrame = _dialogView.window.screen.bounds;
UIEdgeInsets insets = UIEdgeInsetsZero;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
if (@available(iOS 11.0, *)) {
insets = _dialogView.window.safeAreaInsets;
}
#endif
if (insets.top == 0.0) {
insets.top = [[UIApplication sharedApplication] statusBarFrame].size.height;
}
applicationFrame.origin.x += insets.left;
applicationFrame.origin.y += insets.top;
applicationFrame.size.width -= insets.left + insets.right;
applicationFrame.size.height -= insets.top + insets.bottom;
if ([FBSDKInternalUtility shouldManuallyAdjustOrientation]) { if ([FBSDKInternalUtility shouldManuallyAdjustOrientation]) {
switch ([UIApplication sharedApplication].statusBarOrientation) { switch ([UIApplication sharedApplication].statusBarOrientation) {
case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeLeft:
@ -311,10 +327,9 @@ static FBSDKWebDialog *g_currentDialog = nil;
transform = CGAffineTransformScale([self _transformForOrientation], scale, scale); transform = CGAffineTransformScale([self _transformForOrientation], scale, scale);
void(^updateBlock)(void) = ^{ void(^updateBlock)(void) = ^{
self->_dialogView.transform = transform; self->_dialogView.transform = transform;
self->_dialogView.center = CGPointMake(CGRectGetMidX(applicationFrame),
CGRect mainFrame = self->_dialogView.window.screen.bounds; CGRectGetMidY(applicationFrame));
self->_dialogView.center = CGPointMake(CGRectGetMidX(mainFrame), self->_dialogView.alpha = alpha;
CGRectGetMidY(mainFrame));
self->_backgroundView.alpha = alpha; self->_backgroundView.alpha = alpha;
}; };
if (animationDuration == 0.0) { if (animationDuration == 0.0) {

View File

@ -120,9 +120,14 @@
CGRect webViewBounds = _webView.bounds; CGRect webViewBounds = _webView.bounds;
_loadingView.center = CGPointMake(CGRectGetMidX(webViewBounds), CGRectGetMidY(webViewBounds)); _loadingView.center = CGPointMake(CGRectGetMidX(webViewBounds), CGRectGetMidY(webViewBounds));
CGRect closeButtonFrame = _closeButton.bounds; if (CGRectGetHeight(webViewBounds) == 0.0) {
closeButtonFrame.origin = bounds.origin; _closeButton.alpha = 0.0;
_closeButton.frame = CGRectIntegral(closeButtonFrame); } else {
_closeButton.alpha = 1.0;
CGRect closeButtonFrame = _closeButton.bounds;
closeButtonFrame.origin = bounds.origin;
_closeButton.frame = CGRectIntegral(closeButtonFrame);
}
} }
#pragma mark - Actions #pragma mark - Actions

View File

@ -373,6 +373,18 @@ Class fbsdkdfl_SFAuthenticationSessionClass(void)
return c; return c;
} }
#pragma mark - Authentication Services
_fbsdkdfl_load_framework_once_impl_(AuthenticationServices)
_fbsdkdfl_handle_get_impl_(AuthenticationServices)
#define _fbsdkdfl_AuthenticationServices_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(AuthenticationServices, SYMBOL);
Class fbsdkdfl_ASWebAuthenticationSessionClass(void)
{
_fbsdkdfl_AuthenticationServices_get_c(ASWebAuthenticationSession);
return c;
}
#pragma mark - Accounts Constants #pragma mark - Accounts Constants
_fbsdkdfl_load_framework_once_impl_(Accounts) _fbsdkdfl_load_framework_once_impl_(Accounts)

View File

@ -126,6 +126,6 @@ didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result
@param loginButton the sender @param loginButton the sender
@return YES if the login should be allowed to proceed, NO otherwise @return YES if the login should be allowed to proceed, NO otherwise
*/ */
- (BOOL) loginButtonWillLogin:(FBSDKLoginButton *)loginButton; - (BOOL)loginButtonWillLogin:(FBSDKLoginButton *)loginButton;
@end @end

View File

@ -34,6 +34,7 @@ static int const FBClientStateChallengeLength = 20;
static NSString *const FBSDKExpectedChallengeKey = @"expected_login_challenge"; static NSString *const FBSDKExpectedChallengeKey = @"expected_login_challenge";
static NSString *const FBSDKOauthPath = @"/dialog/oauth"; static NSString *const FBSDKOauthPath = @"/dialog/oauth";
static NSString *const SFVCCanceledLogin = @"com.apple.SafariServices.Authentication"; static NSString *const SFVCCanceledLogin = @"com.apple.SafariServices.Authentication";
static NSString *const ASCanceledLogin = @"com.apple.AuthenticationServices.WebAuthenticationSession";
typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) { typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) {
FBSDKLoginManagerStateIdle, FBSDKLoginManagerStateIdle,
@ -423,7 +424,8 @@ typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) {
if (didPerformLogIn) { if (didPerformLogIn) {
[self->_logger startAuthMethod:authMethod]; [self->_logger startAuthMethod:authMethod];
self->_state = FBSDKLoginManagerStatePerformingLogin; self->_state = FBSDKLoginManagerStatePerformingLogin;
} else if (error && [error.domain isEqualToString:SFVCCanceledLogin]) { } else if ([error.domain isEqualToString:SFVCCanceledLogin] ||
[error.domain isEqualToString:ASCanceledLogin]) {
[self handleImplicitCancelOfLogIn]; [self handleImplicitCancelOfLogIn];
} else { } else {
if (!error) { if (!error) {
@ -489,7 +491,9 @@ typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) {
} }
+ (NSString *)stringForChallenge { + (NSString *)stringForChallenge {
return [FBSDKCrypto randomString:FBClientStateChallengeLength]; NSString *challenge = [FBSDKCrypto randomString:FBClientStateChallengeLength];
return [challenge stringByReplacingOccurrencesOfString:@"+" withString:@"="];
} }
- (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FBSDKLoginManagerLoginResult *)loginResult - (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FBSDKLoginManagerLoginResult *)loginResult

View File

@ -145,7 +145,8 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO
- (BOOL)show - (BOOL)show
{ {
BOOL didShow = NO; BOOL didShow = NO;
NSError *error = nil; NSError *error;
NSError *validationError;
if ([self _validateWithError:&error]) { if ([self _validateWithError:&error]) {
switch (self.mode) { switch (self.mode) {
@ -166,11 +167,11 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO
break; break;
} }
case FBSDKShareDialogModeNative:{ case FBSDKShareDialogModeNative:{
didShow = [self _showNativeWithCanShowError:&error validationError:&error]; didShow = [self _showNativeWithCanShowError:&error validationError:&validationError];
break; break;
} }
case FBSDKShareDialogModeShareSheet:{ case FBSDKShareDialogModeShareSheet:{
didShow = [self _showShareSheetWithCanShowError:&error validationError:&error]; didShow = [self _showShareSheetWithCanShowError:&error validationError:&validationError];
break; break;
} }
case FBSDKShareDialogModeWeb:{ case FBSDKShareDialogModeWeb:{
@ -180,7 +181,7 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO
} }
} }
if (!didShow) { if (!didShow) {
[self _invokeDelegateDidFailWithError:error]; [self _invokeDelegateDidFailWithError:error ?: validationError];
} else { } else {
[self _logDialogShow]; [self _logDialogShow];
[FBSDKInternalUtility registerTransientObject:self]; [FBSDKInternalUtility registerTransientObject:self];
@ -188,7 +189,7 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO
return didShow; return didShow;
} }
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef - (BOOL)validateWithError:(NSError **)errorRef
{ {
return [self _validateWithError:errorRef] && [self _validateFullyCompatibleWithError:errorRef]; return [self _validateWithError:errorRef] && [self _validateFullyCompatibleWithError:errorRef];
} }
@ -262,7 +263,7 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO
return hasOGURL; return hasOGURL;
} }
-(BOOL)_showAutomatic:(NSError *__autoreleasing *)errorRef -(BOOL)_showAutomatic:(NSError **)errorRef
{ {
BOOL isDefaultToShareSheet = [self _isDefaultToShareSheet]; BOOL isDefaultToShareSheet = [self _isDefaultToShareSheet];
BOOL useNativeDialog = [self _useNativeDialog]; BOOL useNativeDialog = [self _useNativeDialog];
@ -789,7 +790,7 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO
return [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameShare]; return [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameShare];
} }
- (BOOL)_validateWithError:(NSError *__autoreleasing *)errorRef - (BOOL)_validateWithError:(NSError **)errorRef
{ {
if (errorRef != NULL) { if (errorRef != NULL) {
*errorRef = nil; *errorRef = nil;
@ -866,7 +867,7 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO
This method exists to enable the behavior described above and should only be called from `validateWithError:`. This method exists to enable the behavior described above and should only be called from `validateWithError:`.
*/ */
- (BOOL)_validateFullyCompatibleWithError:(NSError *__autoreleasing *)errorRef - (BOOL)_validateFullyCompatibleWithError:(NSError **)errorRef
{ {
id<FBSDKSharingContent> shareContent = self.shareContent; id<FBSDKSharingContent> shareContent = self.shareContent;
if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
@ -886,7 +887,7 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO
return YES; return YES;
} }
- (BOOL)_validateShareContentForBrowserWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef - (BOOL)_validateShareContentForBrowserWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError **)errorRef
{ {
id<FBSDKSharingContent> shareContent = self.shareContent; id<FBSDKSharingContent> shareContent = self.shareContent;
if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {

View File

@ -109,9 +109,9 @@
} else if (photo.imageURL) { } else if (photo.imageURL) {
if (photo.imageURL.isFileURL) { if (photo.imageURL.isFileURL) {
// load the contents of the file and bridge the image // load the contents of the file and bridge the image
UIImage *image = [UIImage imageWithContentsOfFile:photo.imageURL.absoluteString]; UIImage *image = [UIImage imageWithContentsOfFile:photo.imageURL.path];
if (image) { if (image) {
[images addObject:photo.image]; [images addObject:image];
} }
} }
} else if (photo.image) { } else if (photo.image) {

View File

@ -1,6 +1,6 @@
{ {
"name": "PNObject", "name": "PNObject",
"version": "2.6.1", "version": "2.6.3",
"summary": "PNObject is a simple replica of the more complex ParseObject", "summary": "PNObject is a simple replica of the more complex ParseObject",
"homepage": "https://github.com/giuseppenucifora/PNObject", "homepage": "https://github.com/giuseppenucifora/PNObject",
"license": { "license": {
@ -12,7 +12,7 @@
}, },
"source": { "source": {
"git": "https://github.com/giuseppenucifora/PNObject.git", "git": "https://github.com/giuseppenucifora/PNObject.git",
"tag": "2.6.1" "tag": "2.6.3"
}, },
"platforms": { "platforms": {
"ios": "9.0" "ios": "9.0"

View File

@ -37,13 +37,13 @@ PODS:
- Bolts (~> 1.9) - Bolts (~> 1.9)
- FacebookSDK/CoreKit - FacebookSDK/CoreKit
- FBSDKMarketingKit - FBSDKMarketingKit
- FBSDKCoreKit (4.39.0): - FBSDKCoreKit (4.40.0):
- Bolts (~> 1.9) - Bolts (~> 1.9)
- FBSDKLoginKit (4.39.0): - FBSDKLoginKit (4.40.0):
- FBSDKCoreKit - FBSDKCoreKit
- FBSDKMarketingKit (4.38.0): - FBSDKMarketingKit (4.38.0):
- FBSDKCoreKit - FBSDKCoreKit
- FBSDKShareKit (4.39.0): - FBSDKShareKit (4.40.0):
- FBSDKCoreKit - FBSDKCoreKit
- NSDataAES (0.2.2) - NSDataAES (0.2.2)
- NSDate_Utils (1.1.0): - NSDate_Utils (1.1.0):
@ -51,7 +51,7 @@ PODS:
- NSString-Helper (1.2.0) - NSString-Helper (1.2.0)
- nv-ios-http-status (0.0.1) - nv-ios-http-status (0.0.1)
- PEAR-FileManager-iOS (1.3.1) - PEAR-FileManager-iOS (1.3.1)
- PNObject (2.6.1): - PNObject (2.6.3):
- AFNetworking - AFNetworking
- CodFis-Helper - CodFis-Helper
- DDDKeychainWrapper - DDDKeychainWrapper
@ -115,16 +115,16 @@ SPEC CHECKSUMS:
DJLocalization: 0c84029af375647d4104a42ae36be87194c46c47 DJLocalization: 0c84029af375647d4104a42ae36be87194c46c47
Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5
FacebookSDK: 73f54b8b94e09b05647cdef0af147f470cd3edc6 FacebookSDK: 73f54b8b94e09b05647cdef0af147f470cd3edc6
FBSDKCoreKit: 1e3981faefab8c88edfaa9eecd94aab02d99a9bc FBSDKCoreKit: ae214474b25033399c131dc81d258e412582a2ba
FBSDKLoginKit: 30ba5039a2c53d65a75103889bc2deebdacd5a1f FBSDKLoginKit: 7a1e411d46acc8834588eca437daf34de42e1d52
FBSDKMarketingKit: e609f39d74ab273cf52e2f8b7e8829ed412b2827 FBSDKMarketingKit: e609f39d74ab273cf52e2f8b7e8829ed412b2827
FBSDKShareKit: 5a0021c30abb64df9eeba87351dd8a627874543b FBSDKShareKit: 0e45916f4150da485928ae2a17ca021950b194f5
NSDataAES: 967ea3337476a80e9838a533c25d570a06855ed0 NSDataAES: 967ea3337476a80e9838a533c25d570a06855ed0
NSDate_Utils: c858a89da6e204ecf53aca48dbccb4da4d25bc9e NSDate_Utils: c858a89da6e204ecf53aca48dbccb4da4d25bc9e
NSString-Helper: 1c259caa6c845e79e0bb45ee25e34f95d86d2317 NSString-Helper: 1c259caa6c845e79e0bb45ee25e34f95d86d2317
nv-ios-http-status: b6c2b5fc8656cc19e0d3000dadce2080b99d0e2f nv-ios-http-status: b6c2b5fc8656cc19e0d3000dadce2080b99d0e2f
PEAR-FileManager-iOS: 3bc403f68a53483f5629aa822f4649e40275c4d3 PEAR-FileManager-iOS: 3bc403f68a53483f5629aa822f4649e40275c4d3
PNObject: 4dd707682a5933f247091a23e39bf9688ea7e367 PNObject: b70db2cba56df79ddf5b2df096afad403cc5d041
PureLayout: f08c01b8dec00bb14a1fefa3de4c7d9c265df85e PureLayout: f08c01b8dec00bb14a1fefa3de4c7d9c265df85e
RZDataBinding: 289e2fbdce8b9585afef69def83425c5d380ffbd RZDataBinding: 289e2fbdce8b9585afef69def83425c5d380ffbd
Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66 Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66

View File

@ -8,7 +8,7 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'PNObject' s.name = 'PNObject'
s.version = '2.6.2' s.version = '2.6.3'
s.summary = 'PNObject is a simple replica of the more complex ParseObject' s.summary = 'PNObject is a simple replica of the more complex ParseObject'

View File

@ -35,7 +35,7 @@
for(NSString *propertyName in properties) { for(NSString *propertyName in properties) {
if([propertyName isEqualToString:@"mappingError"]) if([propertyName isEqualToString:@"mappingError"])
continue; continue;
NSString *mappedJSONKey; NSString *mappedJSONKey;
NSString *mappedJSONType; NSString *mappedJSONType;
@ -73,7 +73,7 @@
continue; continue;
} }
((void (^)())@{ ((void (^)(void))@{
@"c" : ^{ @"c" : ^{
char val = [value charValue]; char val = [value charValue];
[self setValue:@(val) forKey:propertyName]; [self setValue:@(val) forKey:propertyName];
@ -140,21 +140,45 @@
}, },
@"NSArray" : ^{ @"NSArray" : ^{
NSMutableArray *arr = [NSMutableArray array]; NSMutableArray *arr = [NSMutableArray array];
for(id JSONObject in value) { if ([value isKindOfClass:[NSDictionary class]]) {
if(fromLocal || [[JSONObject class] isSubclassOfClass:[PNObject class]] || [NSClassFromString(mappedJSONType) isSubclassOfClass:[PNObject class]]) {
PNObject *val;
if ([JSONObject isKindOfClass:[NSDictionary class]]) { for(id key in value) {
val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal]; id JSONObject = value[key];
if(fromLocal || [[JSONObject class] isSubclassOfClass:[PNObject class]] || [NSClassFromString(mappedJSONType) isSubclassOfClass:[PNObject class]]) {
PNObject *val;
if ([JSONObject isKindOfClass:[NSDictionary class]]) {
val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal];
}
else {
val = [[NSClassFromString(mappedJSONType) alloc] init];
}
//PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal];
[arr addObject:val];
} }
else { else {
val = [[NSClassFromString(mappedJSONType) alloc] init]; [arr addObject:JSONObject];
} }
[arr addObject:val];
} }
else { }
[arr addObject:JSONObject]; else {
for(id JSONObject in value) {
if(fromLocal || [[JSONObject class] isSubclassOfClass:[PNObject class]] || [NSClassFromString(mappedJSONType) isSubclassOfClass:[PNObject class]]) {
PNObject *val;
if ([JSONObject isKindOfClass:[NSDictionary class]]) {
val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal];
}
else {
val = [[NSClassFromString(mappedJSONType) alloc] init];
}
[arr addObject:val];
}
else {
[arr addObject:JSONObject];
}
} }
} }
@ -162,21 +186,45 @@
}, },
@"NSMutableArray" : ^{ @"NSMutableArray" : ^{
NSMutableArray *arr = [NSMutableArray array]; NSMutableArray *arr = [NSMutableArray array];
for(id JSONObject in value) { if ([value isKindOfClass:[NSDictionary class]]) {
if(fromLocal || [[JSONObject class] isSubclassOfClass:[PNObject class]] || [NSClassFromString(mappedJSONType) isSubclassOfClass:[PNObject class]]) {
PNObject *val;
if ([JSONObject isKindOfClass:[NSDictionary class]]) { for(id key in value) {
val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal]; id JSONObject = value[key];
if(fromLocal || [[JSONObject class] isSubclassOfClass:[PNObject class]] || [NSClassFromString(mappedJSONType) isSubclassOfClass:[PNObject class]]) {
PNObject *val;
if ([JSONObject isKindOfClass:[NSDictionary class]]) {
val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal];
}
else {
val = [[NSClassFromString(mappedJSONType) alloc] init];
}
//PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal];
[arr addObject:val];
} }
else { else {
val = [[NSClassFromString(mappedJSONType) alloc] init]; [arr addObject:JSONObject];
} }
//PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal];
[arr addObject:val];
} }
else { }
[arr addObject:JSONObject]; else {
for(id JSONObject in value) {
if(fromLocal || [[JSONObject class] isSubclassOfClass:[PNObject class]] || [NSClassFromString(mappedJSONType) isSubclassOfClass:[PNObject class]]) {
PNObject *val;
if ([JSONObject isKindOfClass:[NSDictionary class]]) {
val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal];
}
else {
val = [[NSClassFromString(mappedJSONType) alloc] init];
}
//PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject fromLocal:fromLocal];
[arr addObject:val];
}
else {
[arr addObject:JSONObject];
}
} }
} }
@ -211,7 +259,7 @@
for(NSString *propertyName in properties) { for(NSString *propertyName in properties) {
if([propertyName isEqualToString:@"mappingError"]) if([propertyName isEqualToString:@"mappingError"])
continue; continue;
NSString *mappedJSONKey; NSString *mappedJSONKey;
NSString *mappedJSONType; NSString *mappedJSONType;
@ -236,7 +284,7 @@
// Get JSON value for the mapped key // Get JSON value for the mapped key
((void (^)())@{ ((void (^)(void))@{
@"c" : ^{ @"c" : ^{
char val = '\0'; char val = '\0';
[self setValue:@(val) forKey:propertyName]; [self setValue:@(val) forKey:propertyName];
@ -334,68 +382,68 @@
mappedKey = formMappingKey; mappedKey = formMappingKey;
} }
((void (^)())@{ ((void (^)(void))@{
@"c" : ^{ @"c" : ^{
char val = [property charValue]; char val = [property charValue];
[JSON setValue:@(val) forKey:mappedKey]; [JSON setValue:@(val) forKey:mappedKey];
}, },
@"d" : ^{ @"d" : ^{
double val = [property doubleValue]; double val = [property doubleValue];
[JSON setValue:@(val) forKey:mappedKey]; [JSON setValue:@(val) forKey:mappedKey];
}, },
@"f" : ^{ @"f" : ^{
float val = [property floatValue]; float val = [property floatValue];
[JSON setValue:@(val) forKey:mappedKey]; [JSON setValue:@(val) forKey:mappedKey];
}, },
@"i" : ^{ @"i" : ^{
int val = [property intValue]; int val = [property intValue];
[JSON setValue:@(val) forKey:mappedKey]; [JSON setValue:@(val) forKey:mappedKey];
}, },
@"l" : ^{ @"l" : ^{
long val = [property longValue]; long val = [property longValue];
[JSON setValue:@(val) forKey:mappedKey]; [JSON setValue:@(val) forKey:mappedKey];
}, },
@"s" : ^{ @"s" : ^{
short val = [property shortValue]; short val = [property shortValue];
[JSON setValue:@(val) forKey:mappedKey]; [JSON setValue:@(val) forKey:mappedKey];
}, },
@"B" : ^{ @"B" : ^{
BOOL val = [property boolValue]; BOOL val = [property boolValue];
[JSON setValue:@(val) forKey:mappedKey]; [JSON setValue:@(val) forKey:mappedKey];
}, },
@"q" : ^{ @"q" : ^{
NSInteger val = [property integerValue]; NSInteger val = [property integerValue];
[JSON setValue:@(val) forKey:mappedKey]; [JSON setValue:@(val) forKey:mappedKey];
}, },
@"UIImage" : ^{ @"UIImage" : ^{
UIImage *image = [UIImage imageWithData:property]; UIImage *image = [UIImage imageWithData:property];
[JSON setValue:image forKey:mappedKey]; [JSON setValue:image forKey:mappedKey];
}, },
@"NSURL" : ^{ @"NSURL" : ^{
NSURL *url = property; NSURL *url = property;
if (![self isObjNull:url]) { if (![self isObjNull:url]) {
[JSON setValue:[url absoluteString] forKey:mappedKey]; [JSON setValue:[url absoluteString] forKey:mappedKey];
} }
}, },
@"NSString" : ^{ @"NSString" : ^{
NSString *val = [NSString stringWithFormat:@"%@", property]; NSString *val = [NSString stringWithFormat:@"%@", property];
if (![self isObjNull:val]) { if (![self isObjNull:val]) {
[JSON setValue:val forKey:mappedKey]; [JSON setValue:val forKey:mappedKey];
} }
}, },
@"NSNumber" : ^{ @"NSNumber" : ^{
NSNumber *val = [NSNumber numberWithDouble:[property doubleValue]]; NSNumber *val = [NSNumber numberWithDouble:[property doubleValue]];
[JSON setValue:val forKey:mappedKey]; [JSON setValue:val forKey:mappedKey];
}, },
@"NSDate" : ^{ @"NSDate" : ^{
NSDate *val = [property toLocalTime]; NSDate *val = [property toLocalTime];
if (![self isObjNull:val]) { if (![self isObjNull:val]) {
[JSON setValue:val forKey:mappedKey]; [JSON setValue:val forKey:mappedKey];
} }
}, },
@"NSArray" : ^{ @"NSArray" : ^{
NSMutableArray *arr = [NSMutableArray array]; NSMutableArray *arr = [NSMutableArray array];
for(id object in property) { for(id object in property) {
@ -412,7 +460,7 @@
[JSON setValue:arr forKey:mappedKey]; [JSON setValue:arr forKey:mappedKey];
}, },
@"NSMutableArray" : ^{ @"NSMutableArray" : ^{
NSMutableArray *arr = [NSMutableArray array]; NSMutableArray *arr = [NSMutableArray array];
for(id object in property) { for(id object in property) {
@ -429,19 +477,19 @@
[JSON setValue:arr forKey:mappedKey]; [JSON setValue:arr forKey:mappedKey];
} }
}[[property class]] ?: ^{ }[[property class]] ?: ^{
BOOL isPNObjectSubclass = [[property class] isSubclassOfClass:[PNObject class]]; BOOL isPNObjectSubclass = [[property class] isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) { if(isPNObjectSubclass) {
NSDictionary *objectDict = [(PNObject*)property getFormObject:dictionaryMappingSelector]; NSDictionary *objectDict = [(PNObject*)property getFormObject:dictionaryMappingSelector];
[JSON setValue:objectDict forKey:mappedKey]; [JSON setValue:objectDict forKey:mappedKey];
} }
else { else {
NSLogDebug(@"%@",[NSString stringWithFormat:@"Property '%@' could not be assigned any value.", property]); NSLogDebug(@"%@",[NSString stringWithFormat:@"Property '%@' could not be assigned any value.", property]);
} }
})(); })();
} }
} }
} }
@ -451,20 +499,20 @@
- (BOOL)isObjNull:(id _Nullable)obj - (BOOL)isObjNull:(id _Nullable)obj
{ {
if(!obj || nil == obj || NSNull.null == obj || ([obj isKindOfClass:[NSString class]] && [obj isEqualToString:@"(null)"]) || [obj isEqual:[NSNull null]]) if(!obj || nil == obj || NSNull.null == obj || ([obj isKindOfClass:[NSString class]] && [obj isEqualToString:@"(null)"]) || [obj isEqual:[NSNull null]])
return YES; return YES;
else else
return NO; return NO;
} }
static BOOL property_getTypeString( objc_property_t property, char *buffer ) static BOOL property_getTypeString( objc_property_t property, char *buffer )
{ {
const char * attrs = property_getAttributes( property ); const char * attrs = property_getAttributes( property );
if ( attrs == NULL ) if ( attrs == NULL )
return NO; return NO;
const char * e = strchr( attrs, ',' ); const char * e = strchr( attrs, ',' );
if ( e == NULL ) if ( e == NULL )
return NO; return NO;
int len = (int)(e - attrs); int len = (int)(e - attrs);
memcpy( buffer, attrs, len ); memcpy( buffer, attrs, len );