- Upgrade Pods
- Fix refresh token when call response failure - Various fix - Release 0.7
This commit is contained in:
1 parent
6f2f24a533
commit
f5750d801c
238 files changed
+4768
-3106
No files matched your search
@@ -363,6 +363,28 @@ FBSDK_EXTERN NSString *const FBSDKAppEventParameterValueNo;
|
||||
parameters:(NSDictionary *)parameters
|
||||
accessToken:(FBSDKAccessToken *)accessToken;
|
||||
|
||||
|
||||
/*
|
||||
* Push Notifications Logging
|
||||
*/
|
||||
|
||||
/*!
|
||||
@abstract
|
||||
Log an app event that tracks that the application was open via Push Notification.
|
||||
|
||||
@param payload Notification payload received via `UIApplicationDelegate`.
|
||||
*/
|
||||
+ (void)logPushNotificationOpen:(NSDictionary *)payload;
|
||||
|
||||
/*!
|
||||
@abstract
|
||||
Log an app event that tracks that a custom action was taken from a push notification.
|
||||
|
||||
@param payload Notification payload received via `UIApplicationDelegate`.
|
||||
@param action Name of the action that was taken.
|
||||
*/
|
||||
+ (void)logPushNotificationOpen:(NSDictionary *)payload action:(NSString *)action;
|
||||
|
||||
/*!
|
||||
|
||||
@abstract
|
||||
@@ -381,6 +403,21 @@ FBSDK_EXTERN NSString *const FBSDKAppEventParameterValueNo;
|
||||
*/
|
||||
+ (void)activateApp;
|
||||
|
||||
/*
|
||||
* Push Notifications Registration
|
||||
*/
|
||||
|
||||
/*!
|
||||
@abstract
|
||||
Sets a device token to register the current application installation for push notifications.
|
||||
|
||||
@discussion
|
||||
Sets a device token from `NSData` representation that you get from `UIApplicationDelegate.-application:didRegisterForRemoteNotificationsWithDeviceToken:`.
|
||||
|
||||
@param deviceToken Device token data.
|
||||
*/
|
||||
+ (void)setPushNotificationsDeviceToken:(NSData *)deviceToken;
|
||||
|
||||
/*
|
||||
* Control over event batching/flushing
|
||||
*/
|
||||
|
||||
@@ -147,6 +147,9 @@ NSString *const FBSDKAppEventParameterDialogOutcome = @"fb_dialog_
|
||||
NSString *const FBSDKAppEventParameterDialogErrorMessage = @"fb_dialog_outcome_error_message";
|
||||
NSString *const FBSDKAppEventParameterDialogMode = @"fb_dialog_mode";
|
||||
NSString *const FBSDKAppEventParameterDialogShareContentType = @"fb_dialog_share_content_type";
|
||||
NSString *const FBSDKAppEventParameterLogTime = @"_logTime";
|
||||
NSString *const FBSDKAppEventParameterEventName = @"_eventName";
|
||||
NSString *const FBSDKAppEventParameterImplicitlyLogged = @"_implicitlyLogged";
|
||||
|
||||
// Event parameter values internal to this file
|
||||
NSString *const FBSDKAppEventsDialogOutcomeValue_Completed = @"Completed";
|
||||
@@ -172,6 +175,19 @@ NSString *const FBSDKAppEventsLoggingResultNotification = @"com.facebook.sdk:FBS
|
||||
|
||||
NSString *const FBSDKAppEventsOverrideAppIDBundleKey = @"FacebookLoggingOverrideAppID";
|
||||
|
||||
//
|
||||
// Push Notifications
|
||||
// Activities Endpoint Parameter
|
||||
static NSString *const FBSDKActivitesParameterPushDeviceToken = @"device_token";
|
||||
// Event Name
|
||||
static NSString *const FBSDKAppEventNamePushOpened = @"fb_mobile_push_opened";
|
||||
// Event Parameter
|
||||
static NSString *const FBSDKAppEventParameterPushCampaign = @"fb_push_campaign";
|
||||
static NSString *const FBSDKAppEventParameterPushAction = @"fb_push_action";
|
||||
// Payload Keys
|
||||
static NSString *const FBSDKAppEventsPushPayloadKey = @"fb_push_payload";
|
||||
static NSString *const FBSDKAppEventsPushPayloadCampaignKey = @"campaign";
|
||||
|
||||
#define NUM_LOG_EVENTS_TO_TRY_TO_FLUSH_AFTER 100
|
||||
#define FLUSH_PERIOD_IN_SECONDS 15
|
||||
#define APP_SUPPORTS_ATTRIBUTION_ID_RECHECK_PERIOD 60 * 60 * 24
|
||||
@@ -183,6 +199,9 @@ static NSString *g_overrideAppID = nil;
|
||||
@property (nonatomic, readwrite) FBSDKAppEventsFlushBehavior flushBehavior;
|
||||
//for testing only.
|
||||
@property (nonatomic, assign) BOOL disableTimer;
|
||||
|
||||
@property (nonatomic, copy) NSString *pushNotificationsDeviceTokenString;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBSDKAppEvents
|
||||
@@ -344,6 +363,35 @@ static NSString *g_overrideAppID = nil;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Push Notifications Logging
|
||||
*/
|
||||
|
||||
+ (void)logPushNotificationOpen:(NSDictionary *)payload
|
||||
{
|
||||
[self logPushNotificationOpen:payload action:nil];
|
||||
}
|
||||
|
||||
+ (void)logPushNotificationOpen:(NSDictionary *)payload action:(NSString *)action
|
||||
{
|
||||
NSDictionary *facebookPayload = payload[FBSDKAppEventsPushPayloadKey];
|
||||
if (!facebookPayload) {
|
||||
return;
|
||||
}
|
||||
NSString *campaign = facebookPayload[FBSDKAppEventsPushPayloadCampaignKey];
|
||||
if (campaign.length == 0) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
|
||||
logEntry:@"Malformed payload specified for logging a push notification open."];
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObject:campaign forKey:FBSDKAppEventParameterPushCampaign];
|
||||
if (action) {
|
||||
parameters[FBSDKAppEventParameterPushAction] = action;
|
||||
}
|
||||
[self logEvent:FBSDKAppEventNamePushOpened parameters:parameters];
|
||||
}
|
||||
|
||||
+ (void)activateApp
|
||||
{
|
||||
[FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass(self)];
|
||||
@@ -360,6 +408,11 @@ static NSString *g_overrideAppID = nil;
|
||||
[FBSDKTimeSpentData restore:YES];
|
||||
}
|
||||
|
||||
+ (void)setPushNotificationsDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
[FBSDKAppEvents singleton].pushNotificationsDeviceTokenString = [FBSDKInternalUtility hexadecimalStringFromData:deviceToken];
|
||||
}
|
||||
|
||||
+ (FBSDKAppEventsFlushBehavior)flushBehavior
|
||||
{
|
||||
return [FBSDKAppEvents singleton].flushBehavior;
|
||||
@@ -532,11 +585,13 @@ static NSString *g_overrideAppID = nil;
|
||||
}
|
||||
|
||||
NSMutableDictionary *eventDictionary = [NSMutableDictionary dictionaryWithDictionary:parameters];
|
||||
eventDictionary[@"_eventName"] = eventName;
|
||||
eventDictionary[@"_logTime"] = @([FBSDKAppEventsUtility unixTimeNow]);
|
||||
eventDictionary[FBSDKAppEventParameterEventName] = eventName;
|
||||
if (!eventDictionary[FBSDKAppEventParameterLogTime]) {
|
||||
eventDictionary[FBSDKAppEventParameterLogTime] = @([FBSDKAppEventsUtility unixTimeNow]);
|
||||
}
|
||||
[FBSDKInternalUtility dictionary:eventDictionary setObject:valueToSum forKey:@"_valueToSum"];
|
||||
if (isImplicitlyLogged) {
|
||||
eventDictionary[@"_implicitlyLogged"] = @"1";
|
||||
eventDictionary[FBSDKAppEventParameterImplicitlyLogged] = @"1";
|
||||
}
|
||||
|
||||
NSString *currentViewControllerName;
|
||||
@@ -650,6 +705,9 @@ static NSString *g_overrideAppID = nil;
|
||||
if (appEventsState.numSkipped > 0) {
|
||||
postParameters[@"num_skipped_events"] = [NSString stringWithFormat:@"%lu", (unsigned long)appEventsState.numSkipped];
|
||||
}
|
||||
if (self.pushNotificationsDeviceTokenString) {
|
||||
postParameters[FBSDKActivitesParameterPushDeviceToken] = self.pushNotificationsDeviceTokenString;
|
||||
}
|
||||
|
||||
NSString *loggingEntry = nil;
|
||||
if ([[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorAppEvents]) {
|
||||
|
||||
+6
-15
@@ -27,6 +27,7 @@
|
||||
|
||||
#import "FBSDKGraphRequest+Internal.h"
|
||||
#import "FBSDKGraphRequestConnection.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKLogger.h"
|
||||
#import "FBSDKSettings+Internal.h"
|
||||
#import "FBSDKUtility.h"
|
||||
@@ -41,17 +42,6 @@ static NSString *const kIPadKey = @"ipad";
|
||||
static NSString *const kShouldFallbackKey = @"should_fallback";
|
||||
static NSString *const kAppLinksKey = @"app_links";
|
||||
|
||||
static void FBSDKAppLinkResolverBoltsClassFromString(Class *clazz, NSString *className)
|
||||
{
|
||||
*clazz = NSClassFromString(className);
|
||||
if (*clazz == nil) {
|
||||
NSString *message = [NSString stringWithFormat:@"Unable to load class %@. Did you link Bolts.framework?", className];
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||
reason:message
|
||||
userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
@interface FBSDKAppLinkResolver ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary *cachedLinks;
|
||||
@@ -68,10 +58,11 @@ static Class g_BFTaskClass;
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [FBSDKAppLinkResolver class]) {
|
||||
FBSDKAppLinkResolverBoltsClassFromString(&g_BFTaskCompletionSourceClass, @"BFTaskCompletionSource");
|
||||
FBSDKAppLinkResolverBoltsClassFromString(&g_BFAppLinkTargetClass, @"BFAppLinkTarget");
|
||||
FBSDKAppLinkResolverBoltsClassFromString(&g_BFAppLinkClass, @"BFAppLink");
|
||||
FBSDKAppLinkResolverBoltsClassFromString(&g_BFTaskClass, @"BFTask");
|
||||
g_BFTaskCompletionSourceClass = [FBSDKInternalUtility
|
||||
resolveBoltsClassWithName:@"BFTaskCompletionSource"];
|
||||
g_BFAppLinkTargetClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFAppLinkTarget"];
|
||||
g_BFTaskClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFTask"];
|
||||
g_BFAppLinkClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFAppLink"];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,14 @@
|
||||
*/
|
||||
typedef void (^FBSDKDeferredAppLinkHandler)(NSURL *url, NSError *error);
|
||||
|
||||
|
||||
/*!
|
||||
@abstract Describes the callback for fetchOrganicDeferredAppLink.
|
||||
@param url the url representing the deferred App Link
|
||||
*/
|
||||
typedef void (^FBSDKDeferredAppInviteHandler)(NSURL *url);
|
||||
|
||||
|
||||
/*!
|
||||
@abstract Class containing App Links related utility methods.
|
||||
*/
|
||||
@@ -52,4 +60,41 @@ typedef void (^FBSDKDeferredAppLinkHandler)(NSURL *url, NSError *error);
|
||||
*/
|
||||
+ (void)fetchDeferredAppLink:(FBSDKDeferredAppLinkHandler)handler;
|
||||
|
||||
/*!
|
||||
@abstract Call this method from the main thread to fetch deferred deeplink for App Invites
|
||||
Handler is called with deeplink url, if found, nil otherwise.
|
||||
|
||||
@param handler Handler to be called when we fetch deeplink url.
|
||||
|
||||
@return YES if async fetch process was started, NO if it failed to start. Note it returns NO
|
||||
for versions < iOS 9.
|
||||
|
||||
@discussion Call this method from the main thread to fetch deferred deeplink if you use App Invites.
|
||||
This may require a network round trip. If successful, this will call the handler provided, with
|
||||
deferred deeplink that was clicked by the user. If there is a error/timeout, handler will be called
|
||||
with nil.
|
||||
This method only works on iOS 9+ and returns NO otherwise.
|
||||
This method should only be called from a location that occurs after any launching URL has
|
||||
been processed (e.g., you should call this method from your application delegate's
|
||||
didFinishLaunchingWithOptions:).
|
||||
*/
|
||||
+ (BOOL)fetchDeferredAppInvite:(FBSDKDeferredAppInviteHandler)handler;
|
||||
|
||||
/*
|
||||
@abstract Call this method to fetch promotion code from the url, if it's present. This function
|
||||
requires Bolts framework.
|
||||
|
||||
Note: This throws an exception if Bolts.framework is not linked. Add '[BFURL class]' in intialize method
|
||||
of your AppDelegate.
|
||||
|
||||
@param url App Link url that was passed to the app.
|
||||
|
||||
@return Promotion code string.
|
||||
|
||||
@discussion Call this method to fetch App Invite Promotion Code from applink if present.
|
||||
This can be used to fetch the promotion code that was associated with the invite when it
|
||||
was created. This method should be called with the url from the openURL method.
|
||||
*/
|
||||
+ (NSString*)appInvitePromotionCodeFromURL:(NSURL*)url;
|
||||
|
||||
@end
|
||||
@@ -18,8 +18,12 @@
|
||||
|
||||
#import "FBSDKAppLinkUtility.h"
|
||||
|
||||
#import <Bolts/BFURL.h>
|
||||
|
||||
#import "FBSDKAppEventsUtility.h"
|
||||
#import "FBSDKGraphRequest.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKOrganicDeeplinkHelper.h"
|
||||
#import "FBSDKSettings.h"
|
||||
#import "FBSDKUtility.h"
|
||||
|
||||
@@ -77,4 +81,34 @@ static NSString *const FBSDKDeferredAppLinkEvent = @"DEFERRED_APP_LINK";
|
||||
}];
|
||||
}
|
||||
|
||||
+ (BOOL)fetchDeferredAppInvite:(FBSDKDeferredAppInviteHandler)handler
|
||||
{
|
||||
NSAssert([NSThread isMainThread], @"FBSDKAppLink fetchOrganicDeferredAppLink: must be invoked from main thread.");
|
||||
|
||||
NSAssert(handler, @"FBSDKAppLink fetchOrganicDeferredAppLink: must be invoked with valid handler.");
|
||||
|
||||
FBSDKOrganicDeeplinkHelper *deeplinkHelper = [[FBSDKOrganicDeeplinkHelper alloc] init];
|
||||
return [deeplinkHelper fetchOrganicDeeplink:handler];
|
||||
}
|
||||
|
||||
+ (NSString*)appInvitePromotionCodeFromURL:(NSURL*)url;
|
||||
{
|
||||
BFURL *parsedUrl = [[FBSDKInternalUtility resolveBoltsClassWithName:@"BFURL"] URLWithURL:url];
|
||||
NSDictionary *extras = [parsedUrl appLinkExtras];
|
||||
if (extras) {
|
||||
NSString *deeplinkContextString = extras[@"deeplink_context"];
|
||||
|
||||
// Parse deeplinkContext and extract promo code
|
||||
if ([deeplinkContextString length] > 0) {
|
||||
NSError *error = nil;
|
||||
NSDictionary *deeplinkContextData = [FBSDKInternalUtility objectForJSONString:deeplinkContextString error:&error];
|
||||
if (!error && [deeplinkContextData isKindOfClass:[NSDictionary class]]) {
|
||||
return deeplinkContextData[@"promo_code"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
}
|
||||
@end
|
||||
+31
@@ -39,6 +39,7 @@
|
||||
#import "FBSDKBridgeAPIResponse.h"
|
||||
#import "FBSDKContainerViewController.h"
|
||||
#import "FBSDKProfile+Internal.h"
|
||||
#import "FBSDKOrganicDeeplinkHelper.h"
|
||||
#endif
|
||||
|
||||
NSString *const FBSDKApplicationDidBecomeActiveNotification = @"com.facebook.sdk.FBSDKApplicationDidBecomeActiveNotification";
|
||||
@@ -51,6 +52,7 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
|
||||
FBSDKBridgeAPIRequest *_pendingRequest;
|
||||
FBSDKBridgeAPICallbackBlock _pendingRequestCompletionBlock;
|
||||
id<FBSDKURLOpening> _pendingURLOpen;
|
||||
FBSDKDeferredAppInviteHandler _organicDeeplinkHandler;
|
||||
#endif
|
||||
BOOL _expectingBackground;
|
||||
UIViewController *_safariViewController;
|
||||
@@ -82,6 +84,8 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
|
||||
// Register on UIApplicationDidEnterBackgroundNotification events to reset source application data when app backgrounds.
|
||||
[FBSDKTimeSpentData registerAutoResetSourceApplication];
|
||||
|
||||
[FBSDKInternalUtility validateFacebookReservedURLSchemes];
|
||||
|
||||
// Remove the observer
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
@@ -131,7 +135,34 @@ static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound";
|
||||
userInfo:nil];
|
||||
}
|
||||
[FBSDKTimeSpentData setSourceApplication:sourceApplication openURL:url];
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
if (_organicDeeplinkHandler) {
|
||||
NSDictionary *params = [FBSDKUtility dictionaryWithQueryString:url.query];
|
||||
if([params[@"fbsdk_deeplink"] isEqualToString: @"1"]) {
|
||||
|
||||
NSURL *sanitizedUrl = nil;
|
||||
|
||||
if(![params[@"fbsdk_deeplink_exception"] isEqualToString:@"1"]) {
|
||||
|
||||
NSMutableDictionary *sanitizedParams = [NSMutableDictionary dictionaryWithDictionary:params];
|
||||
[sanitizedParams removeObjectForKey:@"fbsdk_deeplink"];
|
||||
sanitizedUrl = [FBSDKInternalUtility URLWithScheme:url.scheme
|
||||
host:url.host
|
||||
path:url.path
|
||||
queryParameters:sanitizedParams
|
||||
error:nil];
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// Callback handler for organic deeplinking.
|
||||
_organicDeeplinkHandler(sanitizedUrl);
|
||||
_organicDeeplinkHandler = nil;
|
||||
});
|
||||
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
// if they completed a SFVC flow, dimiss it.
|
||||
[_safariViewController.presentingViewController dismissViewControllerAnimated:YES completion: nil];
|
||||
_safariViewController = nil;
|
||||
|
||||
@@ -39,7 +39,10 @@
|
||||
#import <FBSDKCoreKit/FBSDKMutableCopying.h>
|
||||
#import <FBSDKCoreKit/FBSDKProfile.h>
|
||||
#import <FBSDKCoreKit/FBSDKProfilePictureView.h>
|
||||
#else
|
||||
#import <FBSDKCoreKit/FBSDKDeviceButton.h>
|
||||
#import <FBSDKCoreKit/FBSDKDeviceViewControllerBase.h>
|
||||
#endif
|
||||
|
||||
#define FBSDK_VERSION_STRING @"4.10.1"
|
||||
#define FBSDK_TARGET_PLATFORM_VERSION @"v2.5"
|
||||
#define FBSDK_VERSION_STRING @"4.11.0"
|
||||
#define FBSDK_TARGET_PLATFORM_VERSION @"v2.6"
|
||||
@@ -123,6 +123,14 @@ FBSDK_EXTERN NSString *const FBSDKProfileChangeNewKey;
|
||||
*/
|
||||
+ (void)enableUpdatesOnAccessTokenChange:(BOOL)enable;
|
||||
|
||||
/*!
|
||||
@abstract Loads the current profile and passes it to the completion block.
|
||||
@param completion The block to be executed once the profile is loaded
|
||||
@discussion If the profile is already loaded, this method will call the completion block synchronously, otherwise it
|
||||
will begin a graph request to update `currentProfile` and then call the completion block when finished.
|
||||
*/
|
||||
+ (void)loadCurrentProfileWithCompletion:(void(^)(FBSDKProfile *profile, NSError *error))completion;
|
||||
|
||||
/*!
|
||||
@abstract A convenience method for returning a complete `NSURL` for retrieving the user's profile image.
|
||||
@param mode The picture mode
|
||||
|
||||
@@ -122,6 +122,11 @@ static FBSDKProfile *g_currentProfile;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)loadCurrentProfileWithCompletion:(void (^)(FBSDKProfile *, NSError *))completion
|
||||
{
|
||||
[self loadProfileWithToken:[FBSDKAccessToken currentAccessToken] completion:completion];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(NSZone *)zone
|
||||
@@ -205,9 +210,8 @@ static FBSDKProfile *g_currentProfile;
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
+ (void)observeChangeAccessTokenChange:(NSNotification *)notification
|
||||
+ (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(void (^)(FBSDKProfile *, NSError *))completion
|
||||
{
|
||||
FBSDKAccessToken *token = notification.userInfo[FBSDKAccessTokenChangeNewKey];
|
||||
static FBSDKGraphRequestConnection *executingRequestConnection = nil;
|
||||
|
||||
BOOL isStale = [[NSDate date] timeIntervalSinceDate:g_currentProfile.refreshDate] > FBSDKPROFILE_STALE_IN_SECONDS;
|
||||
@@ -223,6 +227,9 @@ static FBSDKProfile *g_currentProfile;
|
||||
executingRequestConnection = [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
if (expectedCurrentProfile != g_currentProfile) {
|
||||
// current profile has already changed since request was started. Let's not overwrite.
|
||||
if (completion != NULL) {
|
||||
completion(nil, nil);
|
||||
}
|
||||
return;
|
||||
}
|
||||
FBSDKProfile *profile = nil;
|
||||
@@ -236,10 +243,21 @@ static FBSDKProfile *g_currentProfile;
|
||||
refreshDate:[NSDate date]];
|
||||
}
|
||||
[[self class] setCurrentProfile:profile];
|
||||
if (completion != NULL) {
|
||||
completion(profile, error);
|
||||
}
|
||||
}];
|
||||
} else if (completion != NULL) {
|
||||
completion(g_currentProfile, nil);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)observeChangeAccessTokenChange:(NSNotification *)notification
|
||||
{
|
||||
FBSDKAccessToken *token = notification.userInfo[FBSDKAccessTokenChangeNewKey];
|
||||
[self loadProfileWithToken:token completion:NULL];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBSDKProfile(Internal)
|
||||
|
||||
Generated
+1
@@ -144,6 +144,7 @@ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlImpression;
|
||||
FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable;
|
||||
|
||||
FBSDK_EXTERN NSString *const FBSDKAppEventParameterDialogErrorMessage;
|
||||
FBSDK_EXTERN NSString *const FBSDKAppEventParameterLogTime;
|
||||
|
||||
@interface FBSDKAppEvents (Internal)
|
||||
|
||||
|
||||
Generated
+33
-8
@@ -207,30 +207,55 @@
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAppEventsLoggingResultNotification object:error];
|
||||
}
|
||||
|
||||
+ (BOOL)matchString:(NSString *)string
|
||||
firstCharacterSet:(NSCharacterSet *)firstCharacterSet
|
||||
restOfStringCharacterSet:(NSCharacterSet *)restOfStringCharacterSet
|
||||
{
|
||||
if (string.length == 0) {
|
||||
return NO;
|
||||
}
|
||||
for (NSUInteger i = 0; i < string.length; i++) {
|
||||
const unichar c = [string characterAtIndex:i];
|
||||
if (i == 0) {
|
||||
if (![firstCharacterSet characterIsMember:c]) {
|
||||
return NO;
|
||||
}
|
||||
} else {
|
||||
if (![restOfStringCharacterSet characterIsMember:c]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)regexValidateIdentifier:(NSString *)identifier
|
||||
{
|
||||
static NSRegularExpression *regex;
|
||||
static NSCharacterSet *firstCharacterSet;
|
||||
static NSCharacterSet *restOfStringCharacterSet;
|
||||
static dispatch_once_t onceToken;
|
||||
static NSMutableSet *cachedIdentifiers;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *regexString = @"^[0-9a-zA-Z_]+[0-9a-zA-Z _-]*$";
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:regexString
|
||||
options:0
|
||||
error:NULL];
|
||||
NSMutableCharacterSet *mutableSet = [NSMutableCharacterSet alphanumericCharacterSet];
|
||||
[mutableSet addCharactersInString:@"_"];
|
||||
firstCharacterSet = [mutableSet copy];
|
||||
|
||||
[mutableSet addCharactersInString:@"- "];
|
||||
restOfStringCharacterSet = [mutableSet copy];
|
||||
cachedIdentifiers = [[NSMutableSet alloc] init];
|
||||
});
|
||||
|
||||
@synchronized(self) {
|
||||
if (![cachedIdentifiers containsObject:identifier]) {
|
||||
NSUInteger numMatches = [regex numberOfMatchesInString:identifier options:0 range:NSMakeRange(0, identifier.length)];
|
||||
if (numMatches > 0) {
|
||||
if ([self matchString:identifier
|
||||
firstCharacterSet:firstCharacterSet
|
||||
restOfStringCharacterSet:restOfStringCharacterSet]) {
|
||||
[cachedIdentifiers addObject:identifier];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
Generated
+49
-40
@@ -22,6 +22,8 @@
|
||||
#import "FBSDKAppEventsUtility.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKLogger.h"
|
||||
#import "FBSDKServerConfiguration.h"
|
||||
#import "FBSDKServerConfigurationManager.h"
|
||||
#import "FBSDKSettings.h"
|
||||
|
||||
|
||||
@@ -30,13 +32,15 @@ NSString *const FBSDKTimeSpentFilename
|
||||
static NSString *const FBSDKTimeSpentPersistKeySessionSecondsSpent = @"secondsSpentInCurrentSession";
|
||||
static NSString *const FBSDKTimeSpentPersistKeySessionNumInterruptions = @"numInterruptions";
|
||||
static NSString *const FBSDKTimeSpentPersistKeyLastSuspendTime = @"lastSuspendTime";
|
||||
static NSString *const FBSDKTimeSpentPersistKeySessionID = @"sessionID";
|
||||
|
||||
static NSString *const FBSDKAppEventNameActivatedApp = @"fb_mobile_activate_app";
|
||||
static NSString *const FBSDKAppEventNameDeactivatedApp = @"fb_mobile_deactivate_app";
|
||||
static NSString *const FBSDKAppEventParameterNameSessionInterruptions = @"fb_mobile_app_interruptions";
|
||||
static NSString *const FBSDKAppEventParameterNameTimeBetweenSessions = @"fb_mobile_time_between_sessions";
|
||||
static NSString *const FBSDKAppEventParameterNameSessionID = @"_session_id";
|
||||
|
||||
|
||||
static const int NUM_SECONDS_IDLE_TO_BE_NEW_SESSION = 60;
|
||||
static const int SECS_PER_MIN = 60;
|
||||
static const int SECS_PER_HOUR = 60 * SECS_PER_MIN;
|
||||
static const int SECS_PER_DAY = 24 * SECS_PER_HOUR;
|
||||
@@ -79,12 +83,6 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
* with the duration of the previous session as the 'value' of this event, along with the number of
|
||||
* interruptions from that previous session as an event parameter.
|
||||
*/
|
||||
@interface FBSDKTimeSpentData()
|
||||
|
||||
@property (nonatomic) NSInteger numSecondsIdleToBeNewSession;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBSDKTimeSpentData
|
||||
{
|
||||
BOOL _isCurrentlyLoaded;
|
||||
@@ -94,6 +92,8 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
long _timeSinceLastSuspend;
|
||||
int _numInterruptionsInCurrentSession;
|
||||
long _lastRestoreTime;
|
||||
long _lastSuspendTime;
|
||||
NSString *_sessionID;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -113,15 +113,6 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
//
|
||||
// Internal methods
|
||||
//
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_numSecondsIdleToBeNewSession = NUM_SECONDS_IDLE_TO_BE_NEW_SESSION;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (FBSDKTimeSpentData *)singleton
|
||||
{
|
||||
static dispatch_once_t pred;
|
||||
@@ -159,7 +150,8 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
@{
|
||||
FBSDKTimeSpentPersistKeySessionSecondsSpent : @(_secondsSpentInCurrentSession),
|
||||
FBSDKTimeSpentPersistKeySessionNumInterruptions : @(_numInterruptionsInCurrentSession),
|
||||
FBSDKTimeSpentPersistKeyLastSuspendTime : @(now)
|
||||
FBSDKTimeSpentPersistKeyLastSuspendTime : @(now),
|
||||
FBSDKTimeSpentPersistKeySessionID : _sessionID,
|
||||
};
|
||||
|
||||
NSString *content = [FBSDKInternalUtility JSONStringForObject:timeSpentData error:NULL invalidObjectHandler:NULL];
|
||||
@@ -200,8 +192,10 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
if (!content) {
|
||||
|
||||
// Nothing persisted, so this is the first launch.
|
||||
_sessionID = [[NSUUID UUID] UUIDString];
|
||||
_secondsSpentInCurrentSession = 0;
|
||||
_numInterruptionsInCurrentSession = 0;
|
||||
_lastSuspendTime = 0;
|
||||
|
||||
// We want to log the app activation event on the first launch, but not the deactivate event
|
||||
_shouldLogActivateEvent = YES;
|
||||
@@ -211,12 +205,13 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
|
||||
NSDictionary *results = [FBSDKInternalUtility objectForJSONString:content error:NULL];
|
||||
|
||||
long lastActiveTime = [[results objectForKey:FBSDKTimeSpentPersistKeyLastSuspendTime] longValue];
|
||||
_lastSuspendTime = [[results objectForKey:FBSDKTimeSpentPersistKeyLastSuspendTime] longValue];
|
||||
|
||||
_timeSinceLastSuspend = now - lastActiveTime;
|
||||
_timeSinceLastSuspend = now - _lastSuspendTime;
|
||||
_secondsSpentInCurrentSession = [[results objectForKey:FBSDKTimeSpentPersistKeySessionSecondsSpent] intValue];
|
||||
_sessionID = results[FBSDKTimeSpentPersistKeySessionID];
|
||||
_numInterruptionsInCurrentSession = [[results objectForKey:FBSDKTimeSpentPersistKeySessionNumInterruptions] intValue];
|
||||
_shouldLogActivateEvent = (_timeSinceLastSuspend > _numSecondsIdleToBeNewSession);
|
||||
_shouldLogActivateEvent = (_timeSinceLastSuspend > [FBSDKServerConfigurationManager cachedServerConfiguration].sessionTimoutInterval);
|
||||
|
||||
// Other than the first launch, we always log the last session's deactivate with this session's activate.
|
||||
_shouldLogDeactivateEvent = _shouldLogActivateEvent;
|
||||
@@ -233,38 +228,52 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
_isCurrentlyLoaded = YES;
|
||||
|
||||
if (calledFromActivateApp) {
|
||||
|
||||
if (_shouldLogActivateEvent) {
|
||||
[FBSDKAppEvents logEvent:FBSDKAppEventNameActivatedApp
|
||||
parameters:@{
|
||||
FBSDKAppEventParameterLaunchSource: [[self class] getSourceApplication]
|
||||
}];
|
||||
}
|
||||
|
||||
// It's important to log deactivate first to reset sessionID
|
||||
if (_shouldLogDeactivateEvent) {
|
||||
|
||||
int quantaIndex = 0;
|
||||
while (_timeSinceLastSuspend > INACTIVE_SECONDS_QUANTA[quantaIndex]) {
|
||||
quantaIndex++;
|
||||
}
|
||||
|
||||
[FBSDKAppEvents logEvent:FBSDKAppEventNameDeactivatedApp
|
||||
valueToSum:_secondsSpentInCurrentSession
|
||||
parameters:
|
||||
@{ FBSDKAppEventParameterNameSessionInterruptions : @(_numInterruptionsInCurrentSession),
|
||||
FBSDKAppEventParameterNameTimeBetweenSessions : [NSString stringWithFormat:@"session_quanta_%d", quantaIndex],
|
||||
FBSDKAppEventParameterLaunchSource: [[self class] getSourceApplication],
|
||||
}
|
||||
];
|
||||
parameters:[self appEventsParametersForDeactivate]];
|
||||
|
||||
// We've logged the session stats, now reset.
|
||||
_secondsSpentInCurrentSession = 0;
|
||||
_numInterruptionsInCurrentSession = 0;
|
||||
_sessionID = [[NSUUID UUID] UUIDString];
|
||||
}
|
||||
|
||||
if (_shouldLogActivateEvent) {
|
||||
[FBSDKAppEvents logEvent:FBSDKAppEventNameActivatedApp
|
||||
parameters:[self appEventsParametersForActivate]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *)appEventsParametersForActivate
|
||||
{
|
||||
return @{
|
||||
FBSDKAppEventParameterLaunchSource: [[self class] getSourceApplication],
|
||||
FBSDKAppEventParameterNameSessionID: _sessionID,
|
||||
};
|
||||
}
|
||||
|
||||
- (NSDictionary *)appEventsParametersForDeactivate
|
||||
{
|
||||
int quantaIndex = 0;
|
||||
while (_timeSinceLastSuspend > INACTIVE_SECONDS_QUANTA[quantaIndex]) {
|
||||
quantaIndex++;
|
||||
}
|
||||
|
||||
NSMutableDictionary *params = [@{ FBSDKAppEventParameterNameSessionInterruptions : @(_numInterruptionsInCurrentSession),
|
||||
FBSDKAppEventParameterNameTimeBetweenSessions : [NSString stringWithFormat:@"session_quanta_%d", quantaIndex],
|
||||
FBSDKAppEventParameterLaunchSource: [[self class] getSourceApplication],
|
||||
FBSDKAppEventParameterNameSessionID : _sessionID ?: @"",
|
||||
} mutableCopy];
|
||||
if (_lastSuspendTime) {
|
||||
params[FBSDKAppEventParameterLogTime] = @(_lastSuspendTime);
|
||||
}
|
||||
return [params copy];
|
||||
}
|
||||
|
||||
+ (void)setSourceApplication:(NSString *)sourceApplication openURL:(NSURL *)url
|
||||
{
|
||||
[self setSourceApplication:sourceApplication
|
||||
|
||||
Generated
+25
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKAppLinkUtility.h>
|
||||
|
||||
@interface FBSDKOrganicDeeplinkHelper: NSObject
|
||||
- (bool)fetchOrganicDeeplink:(FBSDKDeferredAppInviteHandler)handler;
|
||||
@end
|
||||
Generated
+151
@@ -0,0 +1,151 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKOrganicDeeplinkHelper.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SafariServices/SafariServices.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "FBSDKApplicationDelegate+Internal.h"
|
||||
#import "FBSDKDynamicFrameworkLoader.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKSettings.h"
|
||||
|
||||
|
||||
@interface FBSDKOrganicDeeplinkHelper () <
|
||||
SFSafariViewControllerDelegate
|
||||
>
|
||||
@end
|
||||
|
||||
@implementation FBSDKOrganicDeeplinkHelper {
|
||||
UIWindow *_safariWindow;
|
||||
UIViewController *_safariViewController;
|
||||
FBSDKDeferredAppInviteHandler _handler;
|
||||
}
|
||||
|
||||
- (bool)fetchOrganicDeeplink:(FBSDKDeferredAppInviteHandler) handler
|
||||
{
|
||||
_handler = handler;
|
||||
|
||||
// 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) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
_safariWindow = [[UIWindow alloc] initWithFrame:[[[[UIApplication sharedApplication] delegate] window] bounds]];
|
||||
|
||||
_safariWindow.windowLevel = UIWindowLevelNormal - 1;
|
||||
|
||||
_safariWindow.rootViewController = [[UIViewController alloc] init];;
|
||||
[_safariWindow setHidden:NO];
|
||||
_safariViewController = [[SFSafariViewControllerClass alloc] initWithURL: [self constructDeeplinkRetrievalUrl]];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[FBSDKApplicationDelegate sharedInstance].organicDeeplinkHandler = handler;
|
||||
[self presentSafariViewController];
|
||||
|
||||
// Dispatch a fallback handler call, if we get no response within 10 seconds.
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
if([FBSDKApplicationDelegate sharedInstance].organicDeeplinkHandler)
|
||||
{
|
||||
[self cleanUpSafariViewController];
|
||||
[FBSDKApplicationDelegate sharedInstance].organicDeeplinkHandler = nil;
|
||||
_handler(nil);
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)presentSafariViewController
|
||||
{
|
||||
_safariViewController.view.userInteractionEnabled = NO;
|
||||
_safariViewController.view.alpha = 0;
|
||||
[_safariWindow.rootViewController addChildViewController:_safariViewController];
|
||||
[_safariWindow.rootViewController.view addSubview:_safariViewController.view];
|
||||
[_safariViewController performSelector:@selector(setDelegate:) withObject:self];
|
||||
[_safariViewController didMoveToParentViewController:_safariWindow.rootViewController];
|
||||
_safariViewController.view.frame = CGRectZero;
|
||||
return;
|
||||
}
|
||||
|
||||
- (void)cleanUpSafariViewController
|
||||
{
|
||||
if(_safariViewController)
|
||||
{
|
||||
[_safariViewController performSelector:@selector(setDelegate:) withObject:nil];
|
||||
[_safariViewController willMoveToParentViewController:nil];
|
||||
[_safariViewController.view removeFromSuperview];
|
||||
[_safariViewController removeFromParentViewController];
|
||||
_safariViewController = nil;
|
||||
_safariWindow.rootViewController = nil;
|
||||
_safariWindow = nil;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
- (NSURL*)constructDeeplinkRetrievalUrl
|
||||
{
|
||||
NSString *appID = [FBSDKSettings appID];
|
||||
UIDevice* device = [UIDevice currentDevice];
|
||||
NSString* deviceName = @"default";
|
||||
|
||||
switch (device.userInterfaceIdiom) {
|
||||
case UIUserInterfaceIdiomPad:
|
||||
deviceName = @"ipad";
|
||||
break;
|
||||
|
||||
case UIUserInterfaceIdiomPhone:
|
||||
deviceName = @"iphone";
|
||||
break;
|
||||
|
||||
case UIUserInterfaceIdiomTV:
|
||||
deviceName = @"tvos";
|
||||
break;
|
||||
|
||||
#if __IPHONE_9_3
|
||||
case UIUserInterfaceIdiomCarPlay:
|
||||
#endif
|
||||
case UIUserInterfaceIdiomUnspecified:
|
||||
deviceName = @"unspecified";
|
||||
break;
|
||||
}
|
||||
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
parameters[@"application_id"] = appID;
|
||||
parameters[@"device"] = deviceName;
|
||||
return [FBSDKInternalUtility facebookURLWithHostPrefix:@"m"
|
||||
path:@"/deferreddeeplink/retrieve/"
|
||||
queryParameters:parameters
|
||||
defaultVersion: @""
|
||||
error:nil];
|
||||
}
|
||||
|
||||
#pragma mark - SFSafariViewControllerDelegate
|
||||
- (void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully
|
||||
{
|
||||
// Mark request as complete, Safari would redirect to url with correct deeplink or default uri.
|
||||
[self cleanUpSafariViewController];
|
||||
}
|
||||
|
||||
@end
|
||||
Generated
+2
@@ -46,6 +46,8 @@ typedef void(^FBSDKBridgeAPICallbackBlock)(FBSDKBridgeAPIResponse *response);
|
||||
handler:(void(^)(BOOL))handler;
|
||||
|
||||
- (void)openURL:(NSURL *)url sender:(id<FBSDKURLOpening>)sender handler:(void(^)(BOOL))handler;
|
||||
|
||||
@property (nonatomic, copy) FBSDKDeferredAppInviteHandler organicDeeplinkHandler;
|
||||
#endif
|
||||
|
||||
@property (nonatomic, readonly, getter=isActive) BOOL active;
|
||||
|
||||
+5
@@ -38,6 +38,11 @@
|
||||
#import "UI/FBSDKUIUtility.h"
|
||||
#import "UI/FBSDKViewImpressionTracker.h"
|
||||
#import "WebDialog/FBSDKWebDialog.h"
|
||||
#else
|
||||
#import "Device/FBSDKDeviceButton+Internal.h"
|
||||
#import "Device/FBSDKDeviceDialogView.h"
|
||||
#import "Device/FBSDKDeviceViewControllerBase+Internal.h"
|
||||
#import "Device/FBSDKModalFormPresentationController.h"
|
||||
#endif
|
||||
|
||||
#import "AppEvents/FBSDKAppEvents+Internal.h"
|
||||
|
||||
+19
@@ -20,7 +20,9 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#define FBSDK_CANOPENURL_FACEBOOK @"fbauth2"
|
||||
#define FBSDK_CANOPENURL_FBAPI @"fbapi"
|
||||
#define FBSDK_CANOPENURL_MESSENGER @"fb-messenger-api"
|
||||
#define FBSDK_CANOPENURL_SHARE_EXTENSION @"fbshareextension"
|
||||
|
||||
typedef NS_ENUM(int32_t, FBSDKUIKitVersion)
|
||||
{
|
||||
@@ -281,11 +283,22 @@ setJSONStringForObject:(id)object
|
||||
*/
|
||||
+ (void)validateAppID;
|
||||
|
||||
/**
|
||||
Validates that the client access token is non-nil, otherwise - throws an NSException otherwise.
|
||||
Returns the composed client access token.
|
||||
*/
|
||||
+ (NSString *)validateRequiredClientAccessToken;
|
||||
|
||||
/*!
|
||||
@abstract validates that the right URL schemes are registered, throws an NSException if not.
|
||||
*/
|
||||
+ (void)validateURLSchemes;
|
||||
|
||||
/*!
|
||||
@abstract validates that Facebook reserved URL schemes are not registered, throws an NSException if they are.
|
||||
*/
|
||||
+ (void)validateFacebookReservedURLSchemes;
|
||||
|
||||
/*!
|
||||
@abstract Attempts to find the first UIViewController in the view's responder chain. Returns nil if not found.
|
||||
*/
|
||||
@@ -301,6 +314,11 @@ setJSONStringForObject:(id)object
|
||||
*/
|
||||
+ (UIViewController *)topMostViewController;
|
||||
|
||||
/*!
|
||||
@abstract Converts NSData to a hexadecimal UTF8 String.
|
||||
*/
|
||||
+ (NSString *)hexadecimalStringFromData:(NSData *)data;
|
||||
|
||||
/*
|
||||
@abstract Checks if the permission is a publish permission.
|
||||
*/
|
||||
@@ -333,4 +351,5 @@ setJSONStringForObject:(id)object
|
||||
|
||||
#define FB_BASE_URL @"facebook.com"
|
||||
|
||||
+ (Class)resolveBoltsClassWithName:(NSString *)className;
|
||||
@end
|
||||
+47
@@ -587,6 +587,16 @@ static NSMapTable *_transientObjects;
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)validateRequiredClientAccessToken {
|
||||
if (![FBSDKSettings clientToken]) {
|
||||
NSString *reason = @"ClientToken is required to be set for this operation. "
|
||||
@"Set the FacebookClientToken in the Info.plist or call [FBSDKSettings setClientToken:]. "
|
||||
@"You can find your client token in your App Settings -> Advanced.";
|
||||
@throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil];
|
||||
}
|
||||
return [NSString stringWithFormat:@"%@|%@", [FBSDKSettings appID], [FBSDKSettings clientToken]];
|
||||
}
|
||||
|
||||
+ (void)validateURLSchemes
|
||||
{
|
||||
[self validateAppID];
|
||||
@@ -597,6 +607,16 @@ static NSMapTable *_transientObjects;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)validateFacebookReservedURLSchemes
|
||||
{
|
||||
for (NSString * fbUrlScheme in @[FBSDK_CANOPENURL_FACEBOOK, FBSDK_CANOPENURL_MESSENGER, FBSDK_CANOPENURL_FBAPI, FBSDK_CANOPENURL_SHARE_EXTENSION]) {
|
||||
if ([self isRegisteredURLScheme:fbUrlScheme]) {
|
||||
NSString *reason = [NSString stringWithFormat:@"%@ is registered as a URL scheme. Please move the entry from CFBundleURLSchemes in your Info.plist to LSApplicationQueriesSchemes. If you are trying to resolve \"canOpenURL: failed\" warnings, those only indicate that the Facebook app is not installed on your device or simulator and can be ignored.", fbUrlScheme];
|
||||
@throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ (UIViewController *)topMostViewController
|
||||
{
|
||||
@@ -607,6 +627,20 @@ static NSMapTable *_transientObjects;
|
||||
return topController;
|
||||
}
|
||||
|
||||
+ (NSString *)hexadecimalStringFromData:(NSData *)data
|
||||
{
|
||||
NSUInteger dataLength = data.length;
|
||||
if (dataLength == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
const unsigned char *dataBuffer = data.bytes;
|
||||
NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
|
||||
for (int i = 0; i < dataLength; ++i) {
|
||||
[hexString appendFormat:@"%02x", dataBuffer[i]];
|
||||
}
|
||||
return [hexString copy];
|
||||
}
|
||||
|
||||
+ (BOOL)isRegisteredURLScheme:(NSString *)urlScheme {
|
||||
static dispatch_once_t fetchBundleOnce;
|
||||
@@ -692,4 +726,17 @@ static NSMapTable *_transientObjects;
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (Class)resolveBoltsClassWithName:(NSString *)className;
|
||||
{
|
||||
Class clazz = NSClassFromString(className);
|
||||
if (clazz == nil) {
|
||||
NSString *message = [NSString stringWithFormat:@"Unable to load class %@. Did you link Bolts.framework?", className];
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||
reason:message
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@end
|
||||
+1
@@ -26,6 +26,7 @@
|
||||
+ (NSInteger)integerValue:(id)object;
|
||||
+ (id)objectValue:(id)object;
|
||||
+ (NSString *)stringValue:(id)object;
|
||||
+ (NSTimeInterval)timeIntervalValue:(id)object;
|
||||
+ (NSUInteger)unsignedIntegerValue:(id)object;
|
||||
+ (NSURL *)URLValue:(id)object;
|
||||
|
||||
|
||||
+11
@@ -76,6 +76,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSTimeInterval)timeIntervalValue:(id)object
|
||||
{
|
||||
if ([object isKindOfClass:[NSNumber class]]) {
|
||||
return [(NSNumber *)object doubleValue];
|
||||
} else if ([object isKindOfClass:[NSString class]]) {
|
||||
return [(NSString *)object doubleValue];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSUInteger)unsignedIntegerValue:(id)object
|
||||
{
|
||||
if ([object isKindOfClass:[NSNumber class]]) {
|
||||
|
||||
+1
-2
@@ -18,8 +18,7 @@
|
||||
|
||||
#import "FBSDKErrorConfiguration.h"
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKErrorRecoveryConfiguration.h"
|
||||
|
||||
static NSString *const kErrorCategoryOther = @"other";
|
||||
|
||||
+2
@@ -50,6 +50,7 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
|
||||
dialogFlows:(NSDictionary *)dialogFlows
|
||||
timestamp:(NSDate *)timestamp
|
||||
errorConfiguration:(FBSDKErrorConfiguration *)errorConfiguration
|
||||
sessionTimeoutInterval:(NSTimeInterval) sessionTimeoutInterval
|
||||
defaults:(BOOL)defaults
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@@ -66,6 +67,7 @@ NS_DESIGNATED_INITIALIZER;
|
||||
@property (nonatomic, assign, readonly, getter=isSystemAuthenticationEnabled) BOOL systemAuthenticationEnabled;
|
||||
@property (nonatomic, copy, readonly) NSString *loginTooltipText;
|
||||
@property (nonatomic, copy, readonly) NSDate *timestamp;
|
||||
@property (nonatomic, assign) NSTimeInterval sessionTimoutInterval;
|
||||
|
||||
- (FBSDKDialogConfiguration *)dialogConfigurationForDialogName:(NSString *)dialogName;
|
||||
- (BOOL)useNativeDialogForDialogName:(NSString *)dialogName;
|
||||
|
||||
+6
@@ -36,6 +36,7 @@
|
||||
#define FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_KEY @"systemAuthenticationEnabled"
|
||||
#define FBSDK_SERVER_CONFIGURATION_NATIVE_AUTH_FLOW_ENABLED_KEY @"nativeAuthFlowEnabled"
|
||||
#define FBSDK_SERVER_CONFIGURATION_TIMESTAMP_KEY @"timestamp"
|
||||
#define FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_INTERVAL @"sessionTimeoutInterval"
|
||||
|
||||
#pragma mark - Dialog Names
|
||||
|
||||
@@ -82,6 +83,7 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
|
||||
dialogFlows:(NSDictionary *)dialogFlows
|
||||
timestamp:(NSDate *)timestamp
|
||||
errorConfiguration:(FBSDKErrorConfiguration *)errorConfiguration
|
||||
sessionTimeoutInterval:(NSTimeInterval) sessionTimeoutInterval
|
||||
defaults:(BOOL)defaults
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
@@ -99,6 +101,7 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
|
||||
_dialogFlows = [dialogFlows copy];
|
||||
_timestamp = [timestamp copy];
|
||||
_errorConfiguration = [errorConfiguration copy];
|
||||
_sessionTimoutInterval = sessionTimeoutInterval;
|
||||
_defaults = defaults;
|
||||
}
|
||||
return self;
|
||||
@@ -173,6 +176,7 @@ implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled
|
||||
NSDictionary *dialogFlows = [decoder decodeObjectOfClasses:dialogFlowsClasses
|
||||
forKey:FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_KEY];
|
||||
FBSDKErrorConfiguration *errorConfiguration = [decoder decodeObjectOfClass:[FBSDKErrorConfiguration class] forKey:FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGS_KEY];
|
||||
NSTimeInterval sessionTimeoutInterval = [decoder decodeDoubleForKey:FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_INTERVAL];
|
||||
return [self initWithAppID:appID
|
||||
appName:appName
|
||||
loginTooltipEnabled:loginTooltipEnabled
|
||||
@@ -187,6 +191,7 @@ implicitPurchaseLoggingEnabled:implicitPurchaseLoggingEnabbled
|
||||
dialogFlows:dialogFlows
|
||||
timestamp:timestamp
|
||||
errorConfiguration:errorConfiguration
|
||||
sessionTimeoutInterval:sessionTimeoutInterval
|
||||
defaults:NO];
|
||||
}
|
||||
|
||||
@@ -207,6 +212,7 @@ implicitPurchaseLoggingEnabled:implicitPurchaseLoggingEnabbled
|
||||
[encoder encodeBool:_nativeAuthFlowEnabled forKey:FBSDK_SERVER_CONFIGURATION_NATIVE_AUTH_FLOW_ENABLED_KEY];
|
||||
[encoder encodeBool:_systemAuthenticationEnabled forKey:FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_KEY];
|
||||
[encoder encodeObject:_timestamp forKey:FBSDK_SERVER_CONFIGURATION_TIMESTAMP_KEY];
|
||||
[encoder encodeDouble:_sessionTimoutInterval forKey:FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_INTERVAL];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
+2
@@ -28,4 +28,6 @@
|
||||
|
||||
+ (FBSDKGraphRequest *)requestToLoadServerConfiguration:(NSString *)appID;
|
||||
|
||||
+ (void)clearCache;
|
||||
|
||||
@end
|
||||
+17
@@ -28,6 +28,7 @@
|
||||
#import "FBSDKTypeUtility.h"
|
||||
|
||||
// one hour
|
||||
#define DEFAULT_SESSION_TIMEOUT_INTERVAL 60
|
||||
#define FBSDK_SERVER_CONFIGURATION_MANAGER_CACHE_TIMEOUT (60 * 60)
|
||||
|
||||
#define FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY @"com.facebook.sdk:serverConfiguration%@"
|
||||
@@ -43,6 +44,7 @@
|
||||
#define FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_FIELD @"gdpv4_nux_content"
|
||||
#define FBSDK_SERVER_CONFIGURATION_NATIVE_PROXY_AUTH_FLOW_ENABLED_FIELD @"ios_supports_native_proxy_auth_flow"
|
||||
#define FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_FIELD @"ios_supports_system_auth"
|
||||
#define FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_FIELD @"app_events_session_timeout"
|
||||
|
||||
@implementation FBSDKServerConfigurationManager
|
||||
|
||||
@@ -69,6 +71,17 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)clearCache
|
||||
{
|
||||
_serverConfiguration = nil;
|
||||
_serverConfigurationError = nil;
|
||||
_serverConfigurationErrorTimestamp = nil;
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString *defaultsKey = [NSString stringWithFormat:FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY, [FBSDKSettings appID]];
|
||||
[defaults removeObjectForKey:defaultsKey];
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
||||
+ (FBSDKServerConfiguration *)cachedServerConfiguration
|
||||
{
|
||||
NSString *appID = [FBSDKSettings appID];
|
||||
@@ -167,6 +180,7 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
|
||||
NSDictionary *dialogFlows = [FBSDKTypeUtility dictionaryValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_FIELD]];
|
||||
FBSDKErrorConfiguration *errorConfiguration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil];
|
||||
[errorConfiguration parseArray:resultDictionary[FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGURATION_FIELD]];
|
||||
NSTimeInterval sessionTimeoutInterval = [FBSDKTypeUtility timeIntervalValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_FIELD]] ?: DEFAULT_SESSION_TIMEOUT_INTERVAL;
|
||||
FBSDKServerConfiguration *serverConfiguration = [[FBSDKServerConfiguration alloc] initWithAppID:appID
|
||||
appName:appName
|
||||
loginTooltipEnabled:loginTooltipEnabled
|
||||
@@ -181,6 +195,7 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
|
||||
dialogFlows:dialogFlows
|
||||
timestamp:[NSDate date]
|
||||
errorConfiguration:errorConfiguration
|
||||
sessionTimeoutInterval:sessionTimeoutInterval
|
||||
defaults:NO];
|
||||
[self _didProcessConfigurationFromNetwork:serverConfiguration appID:appID error:nil];
|
||||
}
|
||||
@@ -204,6 +219,7 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
|
||||
FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_FIELD,
|
||||
FBSDK_SERVER_CONFIGURATION_NATIVE_PROXY_AUTH_FLOW_ENABLED_FIELD,
|
||||
FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_FIELD,
|
||||
FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_FIELD,
|
||||
];
|
||||
NSDictionary *parameters = @{ @"fields": [fields componentsJoinedByString:@","] };
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:appID
|
||||
@@ -251,6 +267,7 @@ typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures)
|
||||
dialogFlows:dialogFlows
|
||||
timestamp:nil
|
||||
errorConfiguration:nil
|
||||
sessionTimeoutInterval:DEFAULT_SESSION_TIMEOUT_INTERVAL
|
||||
defaults:YES];
|
||||
}
|
||||
return _defaultServerConfiguration;
|
||||
|
||||
Reference in new issue
Block a user