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

View File

@ -659,23 +659,6 @@ static NSString *g_overrideAppID = nil;
if ([FBSDKAppEvents flushBehavior] != FBSDKAppEventsFlushBehaviorExplicitOnly) {
[[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;
if ([[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorAppEvents]) {
if ([FBSDKSettings.loggingBehaviors containsObject:FBSDKLoggingBehaviorAppEvents]) {
NSData *prettyJSONData = [NSJSONSerialization dataWithJSONObject:appEventsState.events
options:NSJSONWritingPrettyPrinted
error:NULL];

View File

@ -102,8 +102,10 @@ static Class g_BFTaskClass;
appLinks[url] = self.cachedFBSDKAppLinks[url];
} else {
[toFind addObject:url];
NSCharacterSet *urlAllowedSet = [NSCharacterSet URLQueryAllowedCharacterSet];
NSString *toFindString = [url.absoluteString stringByAddingPercentEncodingWithAllowedCharacters:urlAllowedSet];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSString *toFindString = [url.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
#pragma clang diagnostic pop
if (toFindString) {
[toFindStrings addObject:toFindString];
}
@ -196,8 +198,13 @@ static Class g_BFTaskClass;
appLinks[url] = self.cachedBFAppLinks[url];
} else {
[toFind addObject:url];
NSCharacterSet *urlAllowedSet = [NSCharacterSet URLQueryAllowedCharacterSet];
[toFindStrings addObject:[url.absoluteString stringByAddingPercentEncodingWithAllowedCharacters:urlAllowedSet]];
#pragma clang diagnostic push
#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";
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
{
#if !TARGET_OS_TV
FBSDKBridgeAPIRequest *_pendingRequest;
FBSDKBridgeAPICallbackBlock _pendingRequestCompletionBlock;
id<FBSDKURLOpening> _pendingURLOpen;
SFAuthenticationSession *_authenticationSession NS_AVAILABLE_IOS(11_0);
SFAuthenticationCompletionHandler _authenticationSessionCompletionHandler NS_AVAILABLE_IOS(11_0);
FBSDKBridgeAPIRequest *_pendingRequest;
FBSDKBridgeAPICallbackBlock _pendingRequestCompletionBlock;
id<FBSDKURLOpening> _pendingURLOpen;
id<FBSDKAuthenticationSession> _authenticationSession NS_AVAILABLE_IOS(11_0);
FBSDKAuthenticationCompletionHandler _authenticationSessionCompletionHandler NS_AVAILABLE_IOS(11_0);
#endif
BOOL _expectingBackground;
BOOL _isRequestingSFAuthenticationSession;
UIViewController *_safariViewController;
BOOL _isDismissingSafariViewController;
BOOL _isAppLaunched;
BOOL _expectingBackground;
BOOL _isRequestingSFAuthenticationSession;
UIViewController *_safariViewController;
BOOL _isDismissingSafariViewController;
BOOL _isAppLaunched;
}
#pragma mark - Class Methods
+ (void)load
{
// when the app becomes active by any means, kick off the initialization.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(initializeWithLaunchData:)
name:UIApplicationDidFinishLaunchingNotification
object:nil];
// when the app becomes active by any means, kick off the initialization.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(initializeWithLaunchData:)
name:UIApplicationDidFinishLaunchingNotification
object:nil];
}
// Initialize SDK listeners
// Don't call this function in any place else. It should only be called when the class is loaded.
+ (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
// Register Listener for Bolts measurement events
[FBSDKBoltsMeasurementEventListener defaultListener];
// Register Listener for Bolts measurement events
[FBSDKBoltsMeasurementEventListener defaultListener];
#endif
// 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]
openURL:launchData[UIApplicationLaunchOptionsURLKey]];
// Register on UIApplicationDidEnterBackgroundNotification events to reset source application data when app backgrounds.
[FBSDKTimeSpentData registerAutoResetSourceApplication];
// 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]
openURL:launchData[UIApplicationLaunchOptionsURLKey]];
// Register on UIApplicationDidEnterBackgroundNotification events to reset source application data when app backgrounds.
[FBSDKTimeSpentData registerAutoResetSourceApplication];
[FBSDKInternalUtility validateFacebookReservedURLSchemes];
// Remove the observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
[FBSDKInternalUtility validateFacebookReservedURLSchemes];
// Remove the observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
+ (instancetype)sharedInstance
{
static FBSDKApplicationDelegate *_sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] _init];
});
return _sharedInstance;
static FBSDKApplicationDelegate *_sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] _init];
});
return _sharedInstance;
}
#pragma mark - Object Lifecycle
- (instancetype)_init
{
if ((self = [super init]) != nil) {
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[defaultCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
if ((self = [super init]) != nil) {
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[defaultCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[FBSDKAppEvents singleton] registerNotifications];
}
return self;
[[FBSDKAppEvents singleton] registerNotifications];
}
return self;
}
- (instancetype)init
{
return nil;
return nil;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - UIApplicationDelegate
@ -149,14 +159,14 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
if (@available(iOS 9.0, *)) {
return [self application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
if (@available(iOS 9.0, *)) {
return [self application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
return NO;
return NO;
}
#endif
@ -165,127 +175,127 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
if (sourceApplication != nil && ![sourceApplication isKindOfClass:[NSString class]]) {
@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]. "
userInfo:nil];
}
[FBSDKTimeSpentData setSourceApplication:sourceApplication openURL:url];
if (sourceApplication != nil && ![sourceApplication isKindOfClass:[NSString class]]) {
@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]. "
userInfo:nil];
}
[FBSDKTimeSpentData setSourceApplication:sourceApplication openURL:url];
#if !TARGET_OS_TV
id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen;
id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen;
void (^completePendingOpenURLBlock)(void) = ^{
self->_pendingURLOpen = nil;
[pendingURLOpen application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
self->_isDismissingSafariViewController = NO;
};
// if they completed a SFVC flow, dismiss it.
if (_safariViewController) {
_isDismissingSafariViewController = YES;
[_safariViewController.presentingViewController dismissViewControllerAnimated:YES
completion:completePendingOpenURLBlock];
_safariViewController = nil;
} else {
if (@available(iOS 11.0, *)) {
if (_authenticationSession != nil) {
[_authenticationSession cancel];
_authenticationSession = nil;
}
void (^completePendingOpenURLBlock)(void) = ^{
self->_pendingURLOpen = nil;
[pendingURLOpen application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
self->_isDismissingSafariViewController = NO;
};
// if they completed a SFVC flow, dismiss it.
if (_safariViewController) {
_isDismissingSafariViewController = YES;
[_safariViewController.presentingViewController dismissViewControllerAnimated:YES
completion:completePendingOpenURLBlock];
_safariViewController = nil;
} else if (@available(iOS 11.0, *)) {
if (_authenticationSession != nil) {
[_authenticationSession cancel];
_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
{
if (_isAppLaunched) {
return NO;
}
_isAppLaunched = YES;
FBSDKAccessToken *cachedToken = [FBSDKSettings accessTokenCache].accessToken;
[FBSDKAccessToken setCurrentAccessToken:cachedToken];
// fetch app settings
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
// fetch gate keepers
[FBSDKGateKeeperManager loadGateKeepers];
if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) {
[self _logSDKInitialize];
}
#if !TARGET_OS_TV
FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile];
[FBSDKProfile setCurrentProfile:cachedProfile];
NSURL *launchedURL = launchOptions[UIApplicationLaunchOptionsURLKey];
NSString *sourceApplication = launchOptions[UIApplicationLaunchOptionsSourceApplicationKey];
if (launchedURL &&
sourceApplication) {
Class loginManagerClass = NSClassFromString(@"FBSDKLoginManager");
if (loginManagerClass) {
id annotation = launchOptions[UIApplicationLaunchOptionsAnnotationKey];
id<FBSDKURLOpening> loginManager = [[loginManagerClass alloc] init];
return [loginManager application:application
openURL:launchedURL
sourceApplication:sourceApplication
annotation:annotation];
if (_isAppLaunched) {
return NO;
}
_isAppLaunched = YES;
FBSDKAccessToken *cachedToken = [FBSDKSettings accessTokenCache].accessToken;
[FBSDKAccessToken setCurrentAccessToken:cachedToken];
// fetch app settings
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
// fetch gate keepers
[FBSDKGateKeeperManager loadGateKeepers];
if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) {
[self _logSDKInitialize];
}
#if !TARGET_OS_TV
FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile];
[FBSDKProfile setCurrentProfile:cachedProfile];
NSURL *launchedURL = launchOptions[UIApplicationLaunchOptionsURLKey];
NSString *sourceApplication = launchOptions[UIApplicationLaunchOptionsSourceApplicationKey];
if (launchedURL &&
sourceApplication) {
Class loginManagerClass = NSClassFromString(@"FBSDKLoginManager");
if (loginManagerClass) {
id annotation = launchOptions[UIApplicationLaunchOptionsAnnotationKey];
id<FBSDKURLOpening> loginManager = [[loginManagerClass alloc] init];
return [loginManager application:application
openURL:launchedURL
sourceApplication:sourceApplication
annotation:annotation];
}
}
}
#endif
return NO;
return NO;
}
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
_isRequestingSFAuthenticationSession = NO;
_active = NO;
_expectingBackground = NO;
_isRequestingSFAuthenticationSession = NO;
_active = NO;
_expectingBackground = NO;
}
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
// Auto log basic events in case autoLogAppEventsEnabled is set
if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) {
[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);
// Auto log basic events in case autoLogAppEventsEnabled is set
if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) {
[FBSDKAppEvents activateApp];
}
notExpectingBackground = notExpectingBackground && !_authenticationSession;
}
#endif
if (notExpectingBackground) {
_active = YES;
// _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
[_pendingURLOpen applicationDidBecomeActive:notification.object];
[self _cancelBridgeRequest];
if (@available(iOS 11.0, *)) {
if (notExpectingBackground && _authenticationSessionCompletionHandler != nil) {
_authenticationSessionCompletionHandler(nil, nil);
}
notExpectingBackground = notExpectingBackground && !_authenticationSession;
}
#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
@ -296,33 +306,33 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
- (void)openURL:(NSURL *)url sender:(id<FBSDKURLOpening>)sender handler:(void(^)(BOOL, NSError *))handler
{
_expectingBackground = YES;
_pendingURLOpen = sender;
dispatch_async(dispatch_get_main_queue(), ^{
// 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 };
if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS10Version]) {
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
handler(success, nil);
}];
}
} else {
BOOL opened = [[UIApplication sharedApplication] openURL:url];
_expectingBackground = YES;
_pendingURLOpen = sender;
dispatch_async(dispatch_get_main_queue(), ^{
// 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 };
if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS10Version]) {
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
handler(success, nil);
}];
}
} else {
BOOL opened = [[UIApplication sharedApplication] openURL:url];
if ([url.scheme hasPrefix:@"http"] && !opened) {
NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 };
if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) {
// 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
opened = YES;
if ([url.scheme hasPrefix:@"http"] && !opened) {
NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 };
if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) {
// 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
opened = YES;
}
}
if (handler) {
handler(opened, nil);
}
}
}
if (handler) {
handler(opened, nil);
}
}
});
});
}
- (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request
@ -330,41 +340,41 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
fromViewController:(UIViewController *)fromViewController
completionBlock:(FBSDKBridgeAPICallbackBlock)completionBlock
{
if (!request) {
return;
}
NSError *error;
NSURL *requestURL = [request requestURL:&error];
if (!requestURL) {
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error];
completionBlock(response);
return;
}
_pendingRequest = request;
_pendingRequestCompletionBlock = [completionBlock copy];
void (^handler)(BOOL, NSError *) = ^(BOOL openedURL, NSError *anError) {
if (!openedURL) {
self->_pendingRequest = nil;
self->_pendingRequestCompletionBlock = nil;
NSError *openedURLError;
if ([request.scheme hasPrefix:@"http"]) {
openedURLError = [NSError fbErrorWithCode:FBSDKErrorBrowserUnavailable
message:@"the app switch failed because the browser is unavailable"];
} else {
openedURLError = [NSError fbErrorWithCode:FBSDKErrorAppVersionUnsupported
message:@"the app switch failed because the destination app is out of date"];
}
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request
error:openedURLError];
completionBlock(response);
return;
if (!request) {
return;
}
NSError *error;
NSURL *requestURL = [request requestURL:&error];
if (!requestURL) {
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error];
completionBlock(response);
return;
}
_pendingRequest = request;
_pendingRequestCompletionBlock = [completionBlock copy];
void (^handler)(BOOL, NSError *) = ^(BOOL openedURL, NSError *anError) {
if (!openedURL) {
self->_pendingRequest = nil;
self->_pendingRequestCompletionBlock = nil;
NSError *openedURLError;
if ([request.scheme hasPrefix:@"http"]) {
openedURLError = [NSError fbErrorWithCode:FBSDKErrorBrowserUnavailable
message:@"the app switch failed because the browser is unavailable"];
} else {
openedURLError = [NSError fbErrorWithCode:FBSDKErrorAppVersionUnsupported
message:@"the app switch failed because the destination app is out of date"];
}
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request
error:openedURLError];
completionBlock(response);
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
@ -372,90 +382,105 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
fromViewController:(UIViewController *)fromViewController
handler:(void(^)(BOOL, NSError *))handler
{
if (![url.scheme hasPrefix:@"http"]) {
[self openURL:url sender:sender handler:handler];
return;
}
if (![url.scheme hasPrefix:@"http"]) {
[self openURL:url sender:sender handler:handler];
return;
}
_expectingBackground = NO;
_pendingURLOpen = sender;
_expectingBackground = NO;
_pendingURLOpen = sender;
if (@available(iOS 11.0, *)) {
if ([sender isAuthenticationURL:url]) {
Class SFAuthenticationSessionClass = fbsdkdfl_SFAuthenticationSessionClass();
if (SFAuthenticationSessionClass != 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];
if (@available(iOS 11.0, *)) {
if ([sender isAuthenticationURL:url]) {
[self _setSessionCompletionHandlerFromHandler:handler];
[self _openURLWithAuthenticationSession:url];
return;
}
__weak typeof(self) weakSelf = self;
_authenticationSessionCompletionHandler = ^ (NSURL *aURL, NSError *error) {
typeof(self) strongSelf = weakSelf;
strongSelf->_isRequestingSFAuthenticationSession = NO;
handler(error == nil, error);
if (error == nil) {
[strongSelf application:[UIApplication sharedApplication] openURL:aURL sourceApplication:@"com.apple" annotation:nil];
}
strongSelf->_authenticationSession = nil;
strongSelf->_authenticationSessionCompletionHandler = nil;
};
_authenticationSession = [[SFAuthenticationSessionClass alloc] initWithURL:url
callbackURLScheme:[FBSDKInternalUtility appURLScheme]
completionHandler:_authenticationSessionCompletionHandler];
}
// trying to dynamically load SFSafariViewController class
// 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
Class SFSafariViewControllerClass = fbsdkdfl_SFSafariViewControllerClass();
if (SFSafariViewControllerClass) {
UIViewController *parent = fromViewController ?: [FBSDKInternalUtility topMostViewController];
if (parent == nil) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
formatString:@"There are no valid ViewController to present SafariViewController with", nil];
return;
}
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;
[_authenticationSession start];
return;
}
}
}
}
// trying to dynamically load SFSafariViewController class
// 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
Class SFSafariViewControllerClass = fbsdkdfl_SFSafariViewControllerClass();
if (SFSafariViewControllerClass) {
UIViewController *parent = fromViewController ?: [FBSDKInternalUtility topMostViewController];
if (parent == nil) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
formatString:@"There are no valid ViewController to present SafariViewController with", nil];
return;
}
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)_setSessionCompletionHandlerFromHandler:(void(^)(BOOL, NSError *))handler
{
__weak typeof(self) weakSelf = self;
_authenticationSessionCompletionHandler = ^ (NSURL *aURL, NSError *error) {
typeof(self) strongSelf = weakSelf;
strongSelf->_isRequestingSFAuthenticationSession = NO;
handler(error == nil, error);
if (error == nil) {
[strongSelf application:[UIApplication sharedApplication] openURL:aURL sourceApplication:@"com.apple" annotation:nil];
}
strongSelf->_authenticationSession = nil;
strongSelf->_authenticationSessionCompletionHandler = nil;
};
}
#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.
- (void)safariViewControllerDidFinish:(UIViewController *)safariViewController
{
if (_pendingURLOpen) {
id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen;
if (_pendingURLOpen) {
id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen;
_pendingURLOpen = nil;
_pendingURLOpen = nil;
[pendingURLOpen application:nil
openURL:nil
sourceApplication:nil
annotation:nil];
[pendingURLOpen application:nil
openURL:nil
sourceApplication:nil
annotation:nil];
}
[self _cancelBridgeRequest];
_safariViewController = nil;
}
[self _cancelBridgeRequest];
_safariViewController = nil;
}
#pragma mark -- FBSDKContainerViewControllerDelegate
- (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated
{
if (_safariViewController) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
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 "
"controller will not be prematurely dismissed."];
[self safariViewControllerDidFinish:_safariViewController];
}
if (_safariViewController) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
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 "
"controller will not be prematurely dismissed."];
[self safariViewControllerDidFinish:_safariViewController];
}
}
#endif
@ -497,113 +522,113 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
- (void)_logIfAppLinkEvent:(NSURL *)url
{
if (!url) {
return;
}
NSDictionary *params = [FBSDKUtility dictionaryWithQueryString:url.query];
NSString *applinkDataString = params[@"al_applink_data"];
if (!applinkDataString) {
return;
}
if (!url) {
return;
}
NSDictionary *params = [FBSDKUtility dictionaryWithQueryString:url.query];
NSString *applinkDataString = params[@"al_applink_data"];
if (!applinkDataString) {
return;
}
NSDictionary *applinkData = [FBSDKInternalUtility objectForJSONString:applinkDataString error:NULL];
if (!applinkData) {
return;
}
NSDictionary *applinkData = [FBSDKInternalUtility objectForJSONString:applinkDataString error:NULL];
if (!applinkData) {
return;
}
NSString *targetURLString = applinkData[@"target_url"];
NSURL *targetURL = [targetURLString isKindOfClass:[NSString class]] ? [NSURL URLWithString:targetURLString] : nil;
NSString *targetURLString = applinkData[@"target_url"];
NSURL *targetURL = [targetURLString isKindOfClass:[NSString class]] ? [NSURL URLWithString:targetURLString] : nil;
NSMutableDictionary *logData = [[NSMutableDictionary alloc] init];
[FBSDKInternalUtility dictionary:logData setObject:targetURL.absoluteString forKey:@"targetURL"];
[FBSDKInternalUtility dictionary:logData setObject:targetURL.host forKey:@"targetURLHost"];
NSMutableDictionary *logData = [[NSMutableDictionary alloc] init];
[FBSDKInternalUtility dictionary:logData setObject:targetURL.absoluteString forKey:@"targetURL"];
[FBSDKInternalUtility dictionary:logData setObject:targetURL.host forKey:@"targetURLHost"];
NSDictionary *refererData = applinkData[@"referer_data"];
if (refererData) {
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"target_url"] forKey:@"referralTargetURL"];
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"url"] forKey:@"referralURL"];
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"app_name"] forKey:@"referralAppName"];
}
[FBSDKInternalUtility dictionary:logData setObject:url.absoluteString forKey:@"inputURL"];
[FBSDKInternalUtility dictionary:logData setObject:url.scheme forKey:@"inputURLScheme"];
NSDictionary *refererData = applinkData[@"referer_data"];
if (refererData) {
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"target_url"] forKey:@"referralTargetURL"];
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"url"] forKey:@"referralURL"];
[FBSDKInternalUtility dictionary:logData setObject:refererData[@"app_name"] forKey:@"referralAppName"];
}
[FBSDKInternalUtility dictionary:logData setObject:url.absoluteString forKey:@"inputURL"];
[FBSDKInternalUtility dictionary:logData setObject:url.scheme forKey:@"inputURLScheme"];
[FBSDKAppEvents logImplicitEvent:FBSDKAppLinkInboundEvent
valueToSum:nil
parameters:logData
accessToken:nil];
[FBSDKAppEvents logImplicitEvent:FBSDKAppLinkInboundEvent
valueToSum:nil
parameters:logData
accessToken:nil];
}
- (void)_logSDKInitialize
{
NSMutableDictionary *params = [NSMutableDictionary new];
params[@"core_lib_included"] = @1;
if (objc_lookUpClass("FBSDKShareDialog") != nil) {
params[@"share_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKLoginManager") != nil) {
params[@"login_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKPlacesManager") != nil) {
params[@"places_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKMessengerButton") != nil) {
params[@"messenger_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKMessengerButton") != nil) {
params[@"messenger_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKTVInterfaceFactory.m") != nil) {
params[@"tv_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKAutoLog") != nil) {
params[@"marketing_lib_included"] = @1;
}
[FBSDKAppEvents logEvent:@"fb_sdk_initialize" parameters:params];
NSMutableDictionary *params = [NSMutableDictionary new];
params[@"core_lib_included"] = @1;
if (objc_lookUpClass("FBSDKShareDialog") != nil) {
params[@"share_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKLoginManager") != nil) {
params[@"login_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKPlacesManager") != nil) {
params[@"places_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKMessengerButton") != nil) {
params[@"messenger_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKMessengerButton") != nil) {
params[@"messenger_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKTVInterfaceFactory.m") != nil) {
params[@"tv_lib_included"] = @1;
}
if (objc_lookUpClass("FBSDKAutoLog") != nil) {
params[@"marketing_lib_included"] = @1;
}
[FBSDKAppEvents logEvent:@"fb_sdk_initialize" parameters:params];
}
#pragma mark -- (non-tvos)
#if !TARGET_OS_TV
- (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication
{
FBSDKBridgeAPIRequest *request = _pendingRequest;
FBSDKBridgeAPICallbackBlock completionBlock = _pendingRequestCompletionBlock;
_pendingRequest = nil;
_pendingRequestCompletionBlock = NULL;
if (![responseURL.scheme isEqualToString:[FBSDKInternalUtility appURLScheme]]) {
return NO;
}
if (![responseURL.host isEqualToString:@"bridge"]) {
return NO;
}
if (!request) {
return NO;
}
if (!completionBlock) {
return YES;
}
NSError *error;
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request
responseURL:responseURL
sourceApplication:sourceApplication
error:&error];
if (response) {
completionBlock(response);
return YES;
} else if (error) {
completionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error]);
return YES;
} else {
return NO;
}
FBSDKBridgeAPIRequest *request = _pendingRequest;
FBSDKBridgeAPICallbackBlock completionBlock = _pendingRequestCompletionBlock;
_pendingRequest = nil;
_pendingRequestCompletionBlock = NULL;
if (![responseURL.scheme isEqualToString:[FBSDKInternalUtility appURLScheme]]) {
return NO;
}
if (![responseURL.host isEqualToString:@"bridge"]) {
return NO;
}
if (!request) {
return NO;
}
if (!completionBlock) {
return YES;
}
NSError *error;
FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request
responseURL:responseURL
sourceApplication:sourceApplication
error:&error];
if (response) {
completionBlock(response);
return YES;
} else if (error) {
completionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error]);
return YES;
} else {
return NO;
}
}
- (void)_cancelBridgeRequest
{
if (_pendingRequest && _pendingRequestCompletionBlock) {
_pendingRequestCompletionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseCancelledWithRequest:_pendingRequest]);
}
_pendingRequest = nil;
_pendingRequestCompletionBlock = NULL;
if (_pendingRequest && _pendingRequestCompletionBlock) {
_pendingRequestCompletionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseCancelledWithRequest:_pendingRequest]);
}
_pendingRequest = nil;
_pendingRequestCompletionBlock = NULL;
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

@ -208,9 +208,12 @@ FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorDeveloperErrors;
+ (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

View File

@ -35,6 +35,9 @@ static TYPE *g_##PLIST_KEY = nil; \
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 FBSDKLoggingBehaviorPerformanceCharacteristics = @"perf_characteristics";
NSString *const FBSDKLoggingBehaviorAppEvents = @"app_events";
@ -47,21 +50,33 @@ NSString *const FBSDKLoggingBehaviorGraphAPIDebugInfo = @"graph_api_debug_info";
NSString *const FBSDKLoggingBehaviorNetworkRequests = @"network_requests";
static NSObject<FBSDKAccessTokenCaching> *g_tokenCache;
static NSMutableSet *g_loggingBehavior;
static NSMutableSet *g_loggingBehaviors;
static NSString *g_legacyUserDefaultTokenInformationKeyName = @"FBAccessTokenInformationKey";
static NSString *const FBSDKSettingsLimitEventAndDataUsage = @"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage";
static BOOL g_disableErrorRecovery;
static NSString *g_userAgentSuffix;
static NSString *g_defaultGraphAPIVersion;
static FBSDKAccessTokenExpirer *g_accessTokenExpirer;
static NSString *const FBSDKSettingsAutoLogAppEventsEnabled = @"FacebookAutoLogAppEventsEnabled";
static NSString *const FBSDKSettingsAdvertiserIDCollectionEnabled = @"FacebookAdvertiserIDCollectionEnabled";
static NSNumber *g_autoLogAppEventsEnabled;
static NSNumber *g_advertiserIDCollectionEnabled;
@implementation FBSDKSettings
+ (void)initialize
{
if (self == [FBSDKSettings class]) {
NSString *appID = [self appID];
g_tokenCache = [[FBSDKAccessTokenCache 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, FacebookDomainPart, facebookDomainPart, setFacebookDomainPart, nil);
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,
setCodelessDebugLogEnabled, @0);
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCollectionEnabled, advertiserIDCollectionEnabled,
setAdvertiserIDCollectionEnabled, @1);
+ (void)setGraphErrorRecoveryDisabled:(BOOL)disableGraphErrorRecovery {
g_disableErrorRecovery = disableGraphErrorRecovery;
@ -114,45 +125,55 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCol
[defaults synchronize];
}
+ (NSSet *)loggingBehavior
+ (NSSet<NSString *> *)loggingBehaviors
{
if (!g_loggingBehavior) {
if (!g_loggingBehaviors) {
NSArray *bundleLoggingBehaviors = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FacebookLoggingBehavior"];
if (bundleLoggingBehaviors) {
g_loggingBehavior = [[NSMutableSet alloc] initWithArray:bundleLoggingBehaviors];
g_loggingBehaviors = [[NSMutableSet alloc] initWithArray:bundleLoggingBehaviors];
} else {
// Establish set of default enabled logging behaviors. You can completely disable logging by
// 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]) {
g_loggingBehavior = [loggingBehavior mutableCopy];
if (![g_loggingBehaviors isEqualToSet:loggingBehaviors]) {
g_loggingBehaviors = [loggingBehaviors mutableCopy];
[self updateGraphAPIDebugBehavior];
}
}
+ (NSSet *)loggingBehavior
{
return [self loggingBehaviors];
}
+ (void)setLoggingBehavior:(NSSet *)loggingBehavior
{
[self setLoggingBehaviors:loggingBehavior];
}
+ (void)enableLoggingBehavior:(NSString *)loggingBehavior
{
if (!g_loggingBehavior) {
[self loggingBehavior];
if (!g_loggingBehaviors) {
[self loggingBehaviors];
}
[g_loggingBehavior addObject:loggingBehavior];
[g_loggingBehaviors addObject:loggingBehavior];
[self updateGraphAPIDebugBehavior];
}
+ (void)disableLoggingBehavior:(NSString *)loggingBehavior
{
if (!g_loggingBehavior) {
[self loggingBehavior];
if (!g_loggingBehaviors) {
[self loggingBehaviors];
}
[g_loggingBehavior removeObject:loggingBehavior];
[g_loggingBehaviors removeObject:loggingBehavior];
[self updateGraphAPIDebugBehavior];
}
@ -214,22 +235,68 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCol
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
+ (void)updateGraphAPIDebugBehavior
{
// Enable Warnings everytime Info is enabled
if ([g_loggingBehavior containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]
&& ![g_loggingBehavior containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) {
[g_loggingBehavior addObject:FBSDKLoggingBehaviorGraphAPIDebugWarning];
if ([g_loggingBehaviors containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]
&& ![g_loggingBehaviors containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) {
[g_loggingBehaviors addObject:FBSDKLoggingBehaviorGraphAPIDebugWarning];
}
}
+ (NSString *)graphAPIDebugParamValue
{
if ([[self loggingBehavior] containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]) {
if ([[self loggingBehaviors] containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]) {
return @"info";
} else if ([[self loggingBehavior] containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) {
} else if ([[self loggingBehaviors] containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) {
return @"warning";
}

View File

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

View File

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

View File

@ -35,6 +35,9 @@ static BOOL _isCodelessIndexing;
static BOOL _isCheckingSession;
static BOOL _isCodelessIndexingEnabled;
static NSMutableDictionary<NSString *, id> *_codelessSetting;
static const NSTimeInterval kTimeout = 4.0;
static NSString *_deviceSessionID;
static NSTimer *_appIndexingTimer;
static NSString *_lastTreeHash;
@ -44,14 +47,95 @@ static NSString *_lastTreeHash;
#if TARGET_OS_SIMULATOR
[self setupGesture];
#else
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *error) {
if (serverConfiguration.codelessSetupEnabled) {
[self loadCodelessSettingWithCompletionBlock:^(BOOL isCodelessSetupEnabled, NSError *error) {
if (isCodelessSetupEnabled) {
[self setupGesture];
}
}];
#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
{
[UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;
@ -64,8 +148,6 @@ static NSString *_lastTreeHash;
} named:@"motionBegan"];
}
+ (void)checkCodelessIndexingSession
{
if (_isCheckingSession) return;

View File

@ -58,6 +58,12 @@
#define CODELESS_INDEXING_ENDPOINT @"app_indexing"
#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
#define CODELESS_VIEW_TREE_CLASS_NAME_KEY @"classname"
#define CODELESS_VIEW_TREE_CLASS_TYPE_BIT_MASK_KEY @"classtypebitmask"

View File

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

View File

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

View File

@ -211,7 +211,7 @@
{
NSString *behaviorToLog = FBSDKLoggingBehaviorAppEvents;
if (allowLogAsDeveloperError) {
if ([[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorDeveloperErrors]) {
if ([FBSDKSettings.loggingBehaviors containsObject:FBSDKLoggingBehaviorDeveloperErrors]) {
// Rather than log twice, prefer 'DeveloperErrors' if it's set over AppEvents.
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 FBSDKAppEventParameterNameTransactionDate = @"fb_transaction_date";
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 NSMutableArray *g_pendingRequestors;
@ -235,23 +237,21 @@ static NSMutableArray *g_pendingRequestors;
FBSDKAppEventParameterNameProductTitle: [self getTruncatedString:product.localizedTitle],
FBSDKAppEventParameterNameDescription: [self getTruncatedString:product.localizedDescription],
}];
#if !TARGET_OS_TV
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_2
if (@available(iOS 11.2, *)) {
BOOL isSubscription = (product.subscriptionPeriod != nil) && ((unsigned long)product.subscriptionPeriod.numberOfUnits > 0);
if (isSubscription) {
// subs inapp
SKProductSubscriptionPeriod *period = 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[FBSDKAppEventParameterNameSubscriptionPeriod] = [self lengthOfSubscriptionPeriod:product.subscriptionPeriod];
eventParameters[FBSDKAppEventParameterNameInAppPurchaseType] = @"subs";
// trial information for subs
SKProductDiscount *discount = product.introductoryPrice;
if (discount) {
eventParameters[FBSDKAppEventParameterNameTrialPeriod] = [self lengthOfSubscriptionPeriod:discount.subscriptionPeriod];
eventParameters[FBSDKAppEventParameterNameTrialPrice] = discount.price;
}
} else {
eventParameters[FBSDKAppEventParameterNameInAppPurchaseType] = @"inapp";
}
@ -268,6 +268,28 @@ static NSMutableArray *g_pendingRequestors;
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
{
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_SFAuthenticationSessionClass(void);
#pragma mark - AuthenticationServices Classes
FOUNDATION_EXPORT Class fbsdkdfl_ASWebAuthenticationSessionClass(void);
#pragma mark - Accounts Constants
FOUNDATION_EXPORT NSString *fbsdkdfl_ACFacebookAppIdKey(void);

View File

@ -38,7 +38,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
- (instancetype)initWithLoggingBehavior:(NSString *)loggingBehavior
{
if ((self = [super init])) {
_isActive = [[FBSDKSettings loggingBehavior] containsObject:loggingBehavior];
_isActive = [FBSDKSettings.loggingBehaviors containsObject:loggingBehavior];
_loggingBehavior = loggingBehavior;
if (_isActive) {
_internalContents = [[NSMutableString alloc] init];
@ -124,7 +124,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
+ (void)singleShotLogEntry:(NSString *)loggingBehavior
logEntry:(NSString *)logEntry {
if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) {
if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) {
FBSDKLogger *logger = [[FBSDKLogger alloc] initWithLoggingBehavior:loggingBehavior];
[logger appendString:logEntry];
[logger emitToNSLog];
@ -134,7 +134,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
+ (void)singleShotLogEntry:(NSString *)loggingBehavior
formatString:(NSString *)formatString, ... {
if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) {
if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) {
va_list vaArguments;
va_start(vaArguments, formatString);
NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments];
@ -149,7 +149,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
timestampTag:(NSObject *)timestampTag
formatString:(NSString *)formatString, ... {
if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) {
if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) {
va_list vaArguments;
va_start(vaArguments, formatString);
NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments];
@ -177,7 +177,7 @@ static NSMutableDictionary *g_startTimesWithTags = nil;
+ (void)registerCurrentTime:(NSString *)loggingBehavior
withTag:(NSObject *)timestampTag {
if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) {
if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) {
if (!g_startTimesWithTags) {
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.
if ([FBSDKSettings loggingBehavior].count > 0) { // otherwise there's no logging.
if (FBSDKSettings.loggingBehaviors.count > 0) { // otherwise there's no logging.
if (!g_stringsToReplace) {
g_stringsToReplace = [[NSMutableDictionary alloc] init];

View File

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

View File

@ -150,7 +150,9 @@ static NSString *const kErrorCategoryLogin = @"login";
- (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];
}

View File

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

View File

@ -72,7 +72,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
smartLoginMenuIconURL:(NSURL *)smartLoginMenuIconURL
updateMessage:(NSString *)updateMessage
eventBindings:(NSArray *)eventBindings
codelessSetupEnabled:(BOOL)codelessSetupEnabled
NS_DESIGNATED_INITIALIZER;
@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) NSString *updateMessage;
@property (nonatomic, copy, readonly) NSArray *eventBindings;
@property (nonatomic, assign, readonly, getter=isCodelessSetupEnabled) BOOL codelessSetupEnabled;
@property (nonatomic, readonly) NSInteger version;
- (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_UPDATE_MESSAGE_KEY @"SDKUpdateMessage"
#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_TRACK_UNINSTALL_ENABLED_KEY @"trackAppUninstallEnabled"
@ -102,7 +101,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
smartLoginMenuIconURL:(NSURL *)smartLoginMenuIconURL
updateMessage:(NSString *)updateMessage
eventBindings:(NSArray *)eventBindings
codelessSetupEnabled:(BOOL)codelessSetupEnabled
{
if ((self = [super init])) {
_appID = [appID copy];
@ -129,7 +127,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
_smartLoginBookmarkIconURL = [smartLoginBookmarkIconURL copy];
_updateMessage = [updateMessage copy];
_eventBindings = eventBindings;
_codelessSetupEnabled = codelessSetupEnabled;
_version = FBSDKServerConfigurationVersion;
}
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];
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];
BOOL codelessSetupEnabled = [decoder decodeBoolForKey:FBSDK_SERVER_CONFIGURATION_CODELESS_SETUP_ENABLED_KEY];
NSInteger version = [decoder decodeIntegerForKey:FBSDK_SERVER_CONFIGURATION_VERSION_KEY];
FBSDKServerConfiguration *configuration = [self initWithAppID:appID
appName:appName
@ -241,7 +237,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
smartLoginMenuIconURL:smartLoginMenuIconURL
updateMessage:updateMessage
eventBindings:eventBindings
codelessSetupEnabled:codelessSetupEnabled
];
configuration->_version = version;
return configuration;
@ -275,7 +270,6 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
[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:_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];
}

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_UPDATE_MESSAGE_FIELD @"sdk_update_message"
#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
@ -208,7 +207,6 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
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]];
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
appName:appName
loginTooltipEnabled:loginTooltipEnabled
@ -233,7 +231,6 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
smartLoginMenuIconURL:smartLoginMenuIconURL
updateMessage:updateMessage
eventBindings:eventBindings
codelessSetupEnabled:codelessSetupEnabled
];
#if TARGET_OS_TV
// don't download icons more than once a day.
@ -278,7 +275,6 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
FBSDK_SERVER_CONFIGURATION_LOGGIN_TOKEN_FIELD
#if !TARGET_OS_TV
,FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD
,FBSDK_SERVER_CONFIGURATION_CODELESS_SETUP_ENABLED_FIELD
#endif
#ifdef DEBUG
,FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD
@ -289,10 +285,7 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD
#endif
];
NSString *advertiserID = [FBSDKAppEventsUtility advertiserID] ?: @"";
NSDictionary<NSString *, NSString *> *parameters = @{ @"fields": [fields componentsJoinedByString:@","],
@"advertiser_id": advertiserID
};
NSDictionary<NSString *, NSString *> *parameters = @{ @"fields": [fields componentsJoinedByString:@","]};
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:appID
parameters:parameters
@ -349,7 +342,6 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
smartLoginMenuIconURL:nil
updateMessage:nil
eventBindings:nil
codelessSetupEnabled:NO
];
}
return _defaultServerConfiguration;

View File

@ -90,7 +90,8 @@ static FBSDKWebDialog *g_currentDialog = nil;
return NO;
}
_dialogView = [[FBSDKWebDialogView alloc] initWithFrame:window.screen.bounds];
CGRect frame = [self _applicationFrameForOrientation];
_dialogView = [[FBSDKWebDialogView alloc] initWithFrame:frame];
_dialogView.delegate = self;
[_dialogView loadURL:URL];
@ -243,7 +244,6 @@ static FBSDKWebDialog *g_currentDialog = nil;
_backgroundView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
_backgroundView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:0.8];
[window addSubview:_backgroundView];
[window addSubview:_dialogView];
[_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 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]) {
switch ([UIApplication sharedApplication].statusBarOrientation) {
case UIInterfaceOrientationLandscapeLeft:
@ -311,10 +327,9 @@ static FBSDKWebDialog *g_currentDialog = nil;
transform = CGAffineTransformScale([self _transformForOrientation], scale, scale);
void(^updateBlock)(void) = ^{
self->_dialogView.transform = transform;
CGRect mainFrame = self->_dialogView.window.screen.bounds;
self->_dialogView.center = CGPointMake(CGRectGetMidX(mainFrame),
CGRectGetMidY(mainFrame));
self->_dialogView.center = CGPointMake(CGRectGetMidX(applicationFrame),
CGRectGetMidY(applicationFrame));
self->_dialogView.alpha = alpha;
self->_backgroundView.alpha = alpha;
};
if (animationDuration == 0.0) {

View File

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

View File

@ -373,6 +373,18 @@ Class fbsdkdfl_SFAuthenticationSessionClass(void)
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
_fbsdkdfl_load_framework_once_impl_(Accounts)

View File

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

View File

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

View File

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

View File

@ -109,9 +109,9 @@
} else if (photo.imageURL) {
if (photo.imageURL.isFileURL) {
// 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) {
[images addObject:photo.image];
[images addObject:image];
}
}
} else if (photo.image) {

View File

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

View File

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

View File

@ -8,7 +8,7 @@
Pod::Spec.new do |s|
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'

View File

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