- Upgrade Libraries
This commit is contained in:
1 parent
060efc0c83
commit
f84e3ef366
535 files changed
+14099
-19527
No files matched your search
+219
-180
@@ -24,23 +24,28 @@
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequestConnection.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class FBSDKAccessToken;
|
||||
@class FBSDKGraphRequest;
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
/** NSNotificationCenter name indicating a result of a failed log flush attempt. The posted object will be an NSError instance. */
|
||||
FOUNDATION_EXPORT NSNotificationName const FBSDKAppEventsLoggingResultNotification;
|
||||
FOUNDATION_EXPORT NSNotificationName const FBSDKAppEventsLoggingResultNotification
|
||||
NS_SWIFT_NAME(AppEventsLoggingResult);
|
||||
|
||||
#else
|
||||
|
||||
/** NSNotificationCenter name indicating a result of a failed log flush attempt. The posted object will be an NSError instance. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventsLoggingResultNotification;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventsLoggingResultNotification
|
||||
NS_SWIFT_NAME(AppEventsLoggingResultNotification);
|
||||
|
||||
#endif
|
||||
|
||||
/** optional plist key ("FacebookLoggingOverrideAppID") for setting `loggingOverrideAppID` */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventsOverrideAppIDBundleKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventsOverrideAppIDBundleKey
|
||||
NS_SWIFT_NAME(AppEventsOverrideAppIDBundleKey);
|
||||
|
||||
/**
|
||||
|
||||
@@ -59,8 +64,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushBehavior)
|
||||
events are persisted and re-established at activation, but they will only be written with an
|
||||
explicit call to `flush`. */
|
||||
FBSDKAppEventsFlushBehaviorExplicitOnly,
|
||||
|
||||
};
|
||||
} NS_SWIFT_NAME(AppEvents.FlushBehavior);
|
||||
|
||||
/**
|
||||
NS_ENUM(NSUInteger, FBSDKProductAvailability)
|
||||
@@ -88,7 +92,7 @@ typedef NS_ENUM(NSUInteger, FBSDKProductAvailability)
|
||||
* Discontinued
|
||||
*/
|
||||
FBSDKProductAvailabilityDiscontinued,
|
||||
};
|
||||
} NS_SWIFT_NAME(AppEvents.ProductAvailability);
|
||||
|
||||
/**
|
||||
NS_ENUM(NSUInteger, FBSDKProductCondition)
|
||||
@@ -99,208 +103,266 @@ typedef NS_ENUM(NSUInteger, FBSDKProductCondition)
|
||||
FBSDKProductConditionNew = 0,
|
||||
FBSDKProductConditionRefurbished,
|
||||
FBSDKProductConditionUsed,
|
||||
};
|
||||
} NS_SWIFT_NAME(AppEvents.ProductCondition);
|
||||
|
||||
/**
|
||||
@methodgroup Predefined event names for logging events common to many apps. Logging occurs through the `logEvent` family of methods on `FBSDKAppEvents`.
|
||||
Common event parameters are provided in the `FBSDKAppEventsParameterNames*` constants.
|
||||
*/
|
||||
|
||||
/// typedef for FBSDKAppEventName
|
||||
typedef NSString *const FBSDKAppEventName NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAME(AppEvents.Name);
|
||||
|
||||
/** Log this event when the user has achieved a level in the app. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameAchievedLevel;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameAchievedLevel;
|
||||
|
||||
/** Log this event when the user has entered their payment info. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameAddedPaymentInfo;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameAddedPaymentInfo;
|
||||
|
||||
/** Log this event when the user has added an item to their cart. The valueToSum passed to logEvent should be the item's price. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameAddedToCart;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameAddedToCart;
|
||||
|
||||
/** Log this event when the user has added an item to their wishlist. The valueToSum passed to logEvent should be the item's price. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameAddedToWishlist;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameAddedToWishlist;
|
||||
|
||||
/** Log this event when a user has completed registration with the app. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameCompletedRegistration;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameCompletedRegistration;
|
||||
|
||||
/** Log this event when the user has completed a tutorial in the app. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameCompletedTutorial;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameCompletedTutorial;
|
||||
|
||||
/** Log this event when the user has entered the checkout process. The valueToSum passed to logEvent should be the total price in the cart. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameInitiatedCheckout;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameInitiatedCheckout;
|
||||
|
||||
/** Log this event when the user has completed a transaction. The valueToSum passed to logEvent should be the total price of the transaction. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNamePurchased;
|
||||
|
||||
/** Log this event when the user has rated an item in the app. The valueToSum passed to logEvent should be the numeric rating. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameRated;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameRated;
|
||||
|
||||
/** Log this event when a user has performed a search within the app. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameSearched;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameSearched;
|
||||
|
||||
/** Log this event when the user has spent app credits. The valueToSum passed to logEvent should be the number of credits spent. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameSpentCredits;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameSpentCredits;
|
||||
|
||||
/** Log this event when the user has unlocked an achievement in the app. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameUnlockedAchievement;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameUnlockedAchievement;
|
||||
|
||||
/** Log this event when a user has viewed a form of content in the app. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameViewedContent;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameViewedContent;
|
||||
|
||||
/** A telephone/SMS, email, chat or other type of contact between a customer and your business. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameContact;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameContact;
|
||||
|
||||
/** The customization of products through a configuration tool or other application your business owns. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameCustomizeProduct;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameCustomizeProduct;
|
||||
|
||||
/** The donation of funds to your organization or cause. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameDonate;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameDonate;
|
||||
|
||||
/** When a person finds one of your locations via web or application, with an intention to visit (example: find product at a local store). */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFindLocation;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameFindLocation;
|
||||
|
||||
/** The booking of an appointment to visit one of your locations. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameSchedule;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameSchedule;
|
||||
|
||||
/** The subsequent subscriptions after the start of a paid subscription for a product or service you offer. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameSubscriptionHeartbeat __attribute((deprecated("This attribute is no longer used.")));
|
||||
|
||||
/** The start of a free trial of a product or service you offer (example: trial subscription). */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameStartTrial;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameStartTrial;
|
||||
|
||||
/** The submission of an application for a product, service or program you offer (example: credit card, educational program or job). */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameSubmitApplication;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameSubmitApplication;
|
||||
|
||||
/** The start of a paid subscription for a product or service you offer. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameSubscribe;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameSubscribe;
|
||||
|
||||
/** Log this event when the user views an ad. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameAdImpression;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameAdImpression;
|
||||
|
||||
/** Log this event when the user clicks an ad. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameAdClick;
|
||||
FOUNDATION_EXPORT FBSDKAppEventName FBSDKAppEventNameAdClick;
|
||||
|
||||
/**
|
||||
@methodgroup Predefined event name parameters for common additional information to accompany events logged through the `logEvent` family
|
||||
of methods on `FBSDKAppEvents`. Common event names are provided in the `FBAppEventName*` constants.
|
||||
*/
|
||||
|
||||
/// typedef for FBSDKAppEventParameterName
|
||||
typedef NSString *const FBSDKAppEventParameterName NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAME(AppEvents.ParameterName);
|
||||
|
||||
/**
|
||||
* Parameter key used to specify data for the one or more pieces of content being logged about.
|
||||
* Data should be a JSON encoded string.
|
||||
* Example:
|
||||
* "[{\"id\": \"1234\", \"quantity\": 2, \"item_price\": 5.99}, {\"id\": \"5678\", \"quantity\": 1, \"item_price\": 9.99}]"
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameContent;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameContent;
|
||||
|
||||
/** Parameter key used to specify an ID for the specific piece of content being logged about. Could be an EAN, article identifier, etc., depending on the nature of the app. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameContentID;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameContentID;
|
||||
|
||||
/** Parameter key used to specify a generic content type/family for the logged event, e.g. "music", "photo", "video". Options to use will vary based upon what the app is all about. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameContentType;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameContentType;
|
||||
|
||||
/** Parameter key used to specify currency used with logged event. E.g. "USD", "EUR", "GBP". See ISO-4217 for specific values. One reference for these is <http://en.wikipedia.org/wiki/ISO_4217>. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameCurrency;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameCurrency;
|
||||
|
||||
/** Parameter key used to specify a description appropriate to the event being logged. E.g., the name of the achievement unlocked in the `FBAppEventNameAchievementUnlocked` event. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameDescription;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameDescription;
|
||||
|
||||
/** Parameter key used to specify the level achieved in a `FBAppEventNameAchieved` event. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameLevel;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameLevel;
|
||||
|
||||
/** Parameter key used to specify the maximum rating available for the `FBAppEventNameRate` event. E.g., "5" or "10". */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameMaxRatingValue;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameMaxRatingValue;
|
||||
|
||||
/** Parameter key used to specify how many items are being processed for an `FBAppEventNameInitiatedCheckout` or `FBAppEventNamePurchased` event. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameNumItems;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameNumItems;
|
||||
|
||||
/** Parameter key used to specify whether payment info is available for the `FBAppEventNameInitiatedCheckout` event. `FBSDKAppEventParameterValueYes` and `FBSDKAppEventParameterValueNo` are good canonical values to use for this parameter. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNamePaymentInfoAvailable;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNamePaymentInfoAvailable;
|
||||
|
||||
/** Parameter key used to specify method user has used to register for the app, e.g., "Facebook", "email", "Twitter", etc */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameRegistrationMethod;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameRegistrationMethod;
|
||||
|
||||
/** Parameter key used to specify the string provided by the user for a search operation. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameSearchString;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameSearchString;
|
||||
|
||||
/** Parameter key used to specify whether the activity being logged about was successful or not. `FBSDKAppEventParameterValueYes` and `FBSDKAppEventParameterValueNo` are good canonical values to use for this parameter. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameSuccess;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameSuccess;
|
||||
|
||||
/**
|
||||
@methodgroup Predefined event name parameters for common additional information to accompany events logged through the `logProductItem` method on `FBSDKAppEvents`.
|
||||
*/
|
||||
|
||||
/// typedef for FBSDKAppEventParameterProduct
|
||||
typedef NSString *const FBSDKAppEventParameterProduct NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAME(AppEvents.ParameterProduct);
|
||||
|
||||
/** Parameter key used to specify the product item's category. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCategory;
|
||||
|
||||
/** Parameter key used to specify the product item's custom label 0. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductCustomLabel0;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel0;
|
||||
|
||||
/** Parameter key used to specify the product item's custom label 1. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductCustomLabel1;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel1;
|
||||
|
||||
/** Parameter key used to specify the product item's custom label 2. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductCustomLabel2;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel2;
|
||||
|
||||
/** Parameter key used to specify the product item's custom label 3. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductCustomLabel3;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel3;
|
||||
|
||||
/** Parameter key used to specify the product item's custom label 4. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductCustomLabel4;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel4;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app URL for iOS. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIOSUrl;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSUrl;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app ID for iOS App Store. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIOSAppStoreID;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSAppStoreID;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app name for iOS. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIOSAppName;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSAppName;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app URL for iPhone. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIPhoneUrl;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneUrl;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app ID for iPhone App Store. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIPhoneAppStoreID;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneAppStoreID;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app name for iPhone. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIPhoneAppName;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneAppName;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app URL for iPad. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIPadUrl;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadUrl;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app ID for iPad App Store. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIPadAppStoreID;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadAppStoreID;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app name for iPad. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkIPadAppName;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadAppName;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app URL for Android. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkAndroidUrl;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidUrl;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink fully-qualified package name for intent generation. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkAndroidPackage;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidPackage;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app name for Android. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkAndroidAppName;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidAppName;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app URL for Windows Phone. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkWindowsPhoneUrl;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneUrl;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app ID, as a GUID, for App Store. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkWindowsPhoneAppID;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneAppID;
|
||||
|
||||
/** Parameter key used to specify the product item's AppLink app name for Windows Phone. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterProductAppLinkWindowsPhoneAppName;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneAppName;
|
||||
|
||||
/*
|
||||
@methodgroup Predefined values to assign to event parameters that accompany events logged through the `logEvent` family
|
||||
of methods on `FBSDKAppEvents`. Common event parameters are provided in the `FBSDKAppEventParameterName*` constants.
|
||||
*/
|
||||
|
||||
/// typedef for FBSDKAppEventParameterValue
|
||||
typedef NSString *const FBSDKAppEventParameterValue NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAME(AppEvents.ParameterValue);
|
||||
|
||||
/** Yes-valued parameter value to be used with parameter keys that need a Yes/No value */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterValueYes;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterValue FBSDKAppEventParameterValueYes;
|
||||
|
||||
/** No-valued parameter value to be used with parameter keys that need a Yes/No value */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterValueNo;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterValue FBSDKAppEventParameterValueNo;
|
||||
|
||||
/** Parameter key used to specify the type of ad in an FBSDKAppEventNameAdImpression
|
||||
* or FBSDKAppEventNameAdClick event.
|
||||
* E.g. "banner", "interstitial", "rewarded_video", "native" */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameAdType;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameAdType;
|
||||
|
||||
/** Parameter key used to specify the unique ID for all events within a subscription
|
||||
* in an FBSDKAppEventNameSubscribe or FBSDKAppEventNameStartTrial event. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
FOUNDATION_EXPORT FBSDKAppEventParameterName FBSDKAppEventParameterNameOrderID;
|
||||
|
||||
/*
|
||||
@methodgroup Predefined values to assign to user data store
|
||||
*/
|
||||
|
||||
/// typedef for FBSDKAppEventUserDataType
|
||||
typedef NSString *const FBSDKAppEventUserDataType NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAME(AppEvents.UserDataType);
|
||||
|
||||
/** Parameter key used to specify user's email. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventEmail;
|
||||
|
||||
/** Parameter key used to specify user's first name. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventFirstName;
|
||||
|
||||
/** Parameter key used to specify user's last name. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventLastName;
|
||||
|
||||
/** Parameter key used to specify user's phone. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventPhone;
|
||||
|
||||
/** Parameter key used to specify user's date of birth. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventDateOfBirth;
|
||||
|
||||
/** Parameter key used to specify user's gender. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventGender;
|
||||
|
||||
/** Parameter key used to specify user's city. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventCity;
|
||||
|
||||
/** Parameter key used to specify user's state. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventState;
|
||||
|
||||
/** Parameter key used to specify user's zip. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventZip;
|
||||
|
||||
/** Parameter key used to specify user's country. */
|
||||
FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventCountry;
|
||||
|
||||
/**
|
||||
|
||||
@@ -351,8 +413,45 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
+ The length of each parameter value can be no more than on the order of 100 characters.
|
||||
|
||||
*/
|
||||
|
||||
NS_SWIFT_NAME(AppEvents)
|
||||
@interface FBSDKAppEvents : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/*
|
||||
* Control over event batching/flushing
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
The current event flushing behavior specifying when events are sent back to Facebook servers.
|
||||
*/
|
||||
@property (class, nonatomic, assign) FBSDKAppEventsFlushBehavior flushBehavior;
|
||||
|
||||
/**
|
||||
Set the 'override' App ID for App Event logging.
|
||||
|
||||
|
||||
|
||||
In some cases, apps want to use one Facebook App ID for login and social presence and another
|
||||
for App Event logging. (An example is if multiple apps from the same company share an app ID for login, but
|
||||
want distinct logging.) By default, this value is `nil`, and defers to the `FBSDKAppEventsOverrideAppIDBundleKey`
|
||||
plist value. If that's not set, it defaults to `[FBSDKSettings appID]`.
|
||||
|
||||
This should be set before any other calls are made to `FBSDKAppEvents`. Thus, you should set it in your application
|
||||
delegate's `application:didFinishLaunchingWithOptions:` delegate.
|
||||
*/
|
||||
@property (class, nonatomic, copy, nullable) NSString *loggingOverrideAppID;
|
||||
|
||||
/*
|
||||
The custom user ID to associate with all app events.
|
||||
|
||||
The userID is persisted until it is cleared by passing nil.
|
||||
*/
|
||||
@property (class, nonatomic, copy, nullable) NSString *userID;
|
||||
|
||||
/*
|
||||
* Basic event logging
|
||||
*/
|
||||
@@ -365,7 +464,7 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
are given in the `FBSDKAppEvents` documentation.
|
||||
|
||||
*/
|
||||
+ (void)logEvent:(NSString *)eventName;
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName;
|
||||
|
||||
/**
|
||||
|
||||
@@ -377,7 +476,7 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
@param valueToSum Amount to be aggregated into all events of this eventName, and App Insights will report
|
||||
the cumulative and average value of this amount.
|
||||
*/
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(double)valueToSum;
|
||||
|
||||
|
||||
@@ -394,8 +493,8 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names
|
||||
are provided in `FBSDKAppEventParameterName*` constants.
|
||||
*/
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
parameters:(NSDictionary *)parameters;
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
parameters:(NSDictionary<FBSDKAppEventParameterName, id> *)parameters;
|
||||
|
||||
/**
|
||||
|
||||
@@ -414,9 +513,9 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
are provided in `FBSDKAppEventParameterName*` constants.
|
||||
|
||||
*/
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
parameters:(NSDictionary *)parameters;
|
||||
parameters:(NSDictionary<FBSDKAppEventParameterName, id> *)parameters;
|
||||
|
||||
|
||||
/**
|
||||
@@ -439,10 +538,10 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
|
||||
@param accessToken The optional access token to log the event as.
|
||||
*/
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
valueToSum:(NSNumber *)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
accessToken:(FBSDKAccessToken *)accessToken;
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(nullable NSNumber *)valueToSum
|
||||
parameters:(NSDictionary<FBSDKAppEventParameterName, id> *)parameters
|
||||
accessToken:(nullable FBSDKAccessToken *)accessToken;
|
||||
|
||||
/*
|
||||
* Purchase logging
|
||||
@@ -489,7 +588,7 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
*/
|
||||
+ (void)logPurchase:(double)purchaseAmount
|
||||
currency:(NSString *)currency
|
||||
parameters:(NSDictionary *)parameters;
|
||||
parameters:(NSDictionary<NSString *, id> *)parameters;
|
||||
|
||||
/**
|
||||
|
||||
@@ -516,8 +615,8 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
*/
|
||||
+ (void)logPurchase:(double)purchaseAmount
|
||||
currency:(NSString *)currency
|
||||
parameters:(NSDictionary *)parameters
|
||||
accessToken:(FBSDKAccessToken *)accessToken;
|
||||
parameters:(NSDictionary<NSString *, id> *)parameters
|
||||
accessToken:(nullable FBSDKAccessToken *)accessToken;
|
||||
|
||||
|
||||
/*
|
||||
@@ -574,10 +673,10 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
title:(NSString *)title
|
||||
priceAmount:(double)priceAmount
|
||||
currency:(NSString *)currency
|
||||
gtin:(NSString *)gtin
|
||||
mpn:(NSString *)mpn
|
||||
brand:(NSString *)brand
|
||||
parameters:(NSDictionary *)parameters;
|
||||
gtin:(nullable NSString *)gtin
|
||||
mpn:(nullable NSString *)mpn
|
||||
brand:(nullable NSString *)brand
|
||||
parameters:(nullable NSDictionary<NSString *, id> *)parameters;
|
||||
|
||||
/**
|
||||
|
||||
@@ -624,52 +723,8 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
|
||||
@param deviceTokenString Device token string.
|
||||
*/
|
||||
+ (void)setPushNotificationsDeviceTokenString:(NSString *)deviceTokenString;
|
||||
|
||||
/*
|
||||
* Control over event batching/flushing
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
Get the current event flushing behavior specifying when events are sent back to Facebook servers.
|
||||
*/
|
||||
+ (FBSDKAppEventsFlushBehavior)flushBehavior;
|
||||
|
||||
/**
|
||||
|
||||
Set the current event flushing behavior specifying when events are sent back to Facebook servers.
|
||||
|
||||
@param flushBehavior The desired `FBSDKAppEventsFlushBehavior` to be used.
|
||||
*/
|
||||
+ (void)setFlushBehavior:(FBSDKAppEventsFlushBehavior)flushBehavior;
|
||||
|
||||
/**
|
||||
Set the 'override' App ID for App Event logging.
|
||||
|
||||
|
||||
|
||||
In some cases, apps want to use one Facebook App ID for login and social presence and another
|
||||
for App Event logging. (An example is if multiple apps from the same company share an app ID for login, but
|
||||
want distinct logging.) By default, this value is `nil`, and defers to the `FBSDKAppEventsOverrideAppIDBundleKey`
|
||||
plist value. If that's not set, it defaults to `[FBSDKSettings appID]`.
|
||||
|
||||
This should be set before any other calls are made to `FBSDKAppEvents`. Thus, you should set it in your application
|
||||
delegate's `application:didFinishLaunchingWithOptions:` delegate.
|
||||
|
||||
@param appID The Facebook App ID to be used for App Event logging.
|
||||
*/
|
||||
+ (void)setLoggingOverrideAppID:(NSString *)appID;
|
||||
|
||||
/**
|
||||
Get the 'override' App ID for App Event logging.
|
||||
|
||||
|
||||
@see setLoggingOverrideAppID:
|
||||
|
||||
*/
|
||||
+ (NSString *)loggingOverrideAppID;
|
||||
|
||||
+ (void)setPushNotificationsDeviceTokenString:(NSString *)deviceTokenString
|
||||
NS_SWIFT_NAME(setPushNotificationsDeviceToken(_:));
|
||||
|
||||
/**
|
||||
Explicitly kick off flushing of events to Facebook. This is an asynchronous method, but it does initiate an immediate
|
||||
@@ -682,11 +737,6 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
Callers will send this ID back to their own servers, collect up a set to create a Facebook Custom Audience with,
|
||||
and then use the resultant Custom Audience to target ads.
|
||||
|
||||
@param accessToken The access token to use to establish the user's identity for users logged into Facebook through this app.
|
||||
If `nil`, then the `[FBSDKAccessToken currentAccessToken]` is used.
|
||||
|
||||
|
||||
|
||||
The JSON in the request's response will include an "custom_audience_third_party_id" key/value pair, with the value being the ID retrieved.
|
||||
This ID is an encrypted encoding of the Facebook user's ID and the invoking Facebook app ID.
|
||||
Multiple calls with the same user will return different IDs, thus these IDs cannot be used to correlate behavior
|
||||
@@ -699,49 +749,17 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
|
||||
This method returns `nil` if either the user has opted-out (via iOS) from Ad Tracking, the app itself has limited event usage
|
||||
via the `[FBSDKSettings limitEventAndDataUsage]` flag, or a specific Facebook user cannot be identified.
|
||||
*/
|
||||
+ (FBSDKGraphRequest *)requestForCustomAudienceThirdPartyIDWithAccessToken:(FBSDKAccessToken *)accessToken;
|
||||
|
||||
/*
|
||||
Sets a custom user ID to associate with all app events.
|
||||
|
||||
The userID is persisted until it is cleared by passing nil.
|
||||
@param accessToken The access token to use to establish the user's identity for users logged into Facebook through this app.
|
||||
If `nil`, then the `[FBSDKAccessToken currentAccessToken]` is used.
|
||||
*/
|
||||
+ (void)setUserID:(NSString *)userID;
|
||||
+ (nullable FBSDKGraphRequest *)requestForCustomAudienceThirdPartyIDWithAccessToken:(nullable FBSDKAccessToken *)accessToken;
|
||||
|
||||
/*
|
||||
Clears the custom user ID to associate with all app events.
|
||||
*/
|
||||
+ (void)clearUserID;
|
||||
|
||||
/*
|
||||
Returns the set custom user ID.
|
||||
*/
|
||||
+ (NSString *)userID;
|
||||
|
||||
/*
|
||||
Sets custom user data to associate with all app events. All user data are hashed
|
||||
and used to match Facebook user from this instance of an application.
|
||||
|
||||
The user data will be persisted between application instances.
|
||||
|
||||
@param userData user data to identify the user. User data should be formated as
|
||||
a NSDictionary of data type name and value.
|
||||
Supported data types and names are:
|
||||
Email: em
|
||||
First Name: fn
|
||||
Last Name: ln
|
||||
Phone: ph
|
||||
Date of Birth: db
|
||||
Gender: ge
|
||||
City: ct
|
||||
State: st
|
||||
Zip: zp
|
||||
Country: country
|
||||
*/
|
||||
+ (void)setUserData:(NSDictionary *)userData
|
||||
DEPRECATED_MSG_ATTRIBUTE("Renamed `setUserEmail:firstName: ...`");
|
||||
|
||||
/*
|
||||
Sets custom user data to associate with all app events. All user data are hashed
|
||||
and used to match Facebook user from this instance of an application.
|
||||
@@ -759,26 +777,45 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
@param zip user's zip
|
||||
@param country user's country
|
||||
*/
|
||||
+ (void)setUserEmail:(NSString *)email
|
||||
firstName:(NSString *)firstName
|
||||
lastName:(NSString *)lastName
|
||||
phone:(NSString *)phone
|
||||
dateOfBirth:(NSString *)dateOfBirth
|
||||
gender:(NSString *)gender
|
||||
city:(NSString *)city
|
||||
state:(NSString *)state
|
||||
zip:(NSString *)zip
|
||||
country:(NSString *)country;
|
||||
+ (void)setUserEmail:(nullable NSString *)email
|
||||
firstName:(nullable NSString *)firstName
|
||||
lastName:(nullable NSString *)lastName
|
||||
phone:(nullable NSString *)phone
|
||||
dateOfBirth:(nullable NSString *)dateOfBirth
|
||||
gender:(nullable NSString *)gender
|
||||
city:(nullable NSString *)city
|
||||
state:(nullable NSString *)state
|
||||
zip:(nullable NSString *)zip
|
||||
country:(nullable NSString *)country
|
||||
NS_SWIFT_NAME(setUser(email:firstName:lastName:phone:dateOfBirth:gender:city:state:zip:country:));
|
||||
|
||||
/*
|
||||
Returns the set user data else nil
|
||||
*/
|
||||
+ (NSString *)getUserData;
|
||||
+ (nullable NSString *)getUserData;
|
||||
|
||||
/*
|
||||
Clears the current user data
|
||||
*/
|
||||
+ (void)clearUserData;
|
||||
|
||||
/*
|
||||
Sets custom user data to associate with all app events. All user data are hashed
|
||||
and used to match Facebook user from this instance of an application.
|
||||
|
||||
The user data will be persisted between application instances.
|
||||
|
||||
@param data data
|
||||
@param type data type, e.g. FBSDKAppEventEmail, FBSDKAppEventPhone
|
||||
*/
|
||||
+ (void)setUserData:(nullable NSString *)data
|
||||
forType:(FBSDKAppEventUserDataType)type;
|
||||
|
||||
/*
|
||||
Clears the current user data of certain type
|
||||
*/
|
||||
+ (void)clearUserDataForType:(FBSDKAppEventUserDataType)type;
|
||||
|
||||
/*
|
||||
Sends a request to update the properties for the current user, set by `setUserID:`
|
||||
|
||||
@@ -786,7 +823,7 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
@param properties the custom user properties
|
||||
@param handler the optional completion handler
|
||||
*/
|
||||
+ (void)updateUserProperties:(NSDictionary *)properties handler:(FBSDKGraphRequestHandler)handler;
|
||||
+ (void)updateUserProperties:(NSDictionary<NSString *, id> *)properties handler:(nullable FBSDKGraphRequestBlock)handler;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
/*
|
||||
@@ -820,3 +857,5 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterNameOrderID;
|
||||
+ (void)sendEventBindingsToUnity;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+333
-216
@@ -18,7 +18,7 @@
|
||||
|
||||
#import "FBSDKAppEvents.h"
|
||||
#import "FBSDKAppEvents+Internal.h"
|
||||
|
||||
#import "FBSDKApplicationDelegate+Internal.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import <UIKit/UIApplication.h>
|
||||
@@ -30,9 +30,11 @@
|
||||
#import "FBSDKConstants.h"
|
||||
#import "FBSDKDynamicFrameworkLoader.h"
|
||||
#import "FBSDKError.h"
|
||||
#import "FBSDKFeatureManager.h"
|
||||
#import "FBSDKGraphRequest+Internal.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKLogger.h"
|
||||
#import "FBSDKRestrictiveDataFilterManager.h"
|
||||
#import "FBSDKPaymentObserver.h"
|
||||
#import "FBSDKServerConfiguration.h"
|
||||
#import "FBSDKServerConfigurationManager.h"
|
||||
@@ -51,162 +53,178 @@
|
||||
//
|
||||
|
||||
// General purpose
|
||||
NSString *const FBSDKAppEventNameCompletedRegistration = @"fb_mobile_complete_registration";
|
||||
NSString *const FBSDKAppEventNameViewedContent = @"fb_mobile_content_view";
|
||||
NSString *const FBSDKAppEventNameSearched = @"fb_mobile_search";
|
||||
NSString *const FBSDKAppEventNameRated = @"fb_mobile_rate";
|
||||
NSString *const FBSDKAppEventNameCompletedTutorial = @"fb_mobile_tutorial_completion";
|
||||
NSString *const FBSDKAppEventNameContact = @"Contact";
|
||||
NSString *const FBSDKAppEventNameCustomizeProduct = @"CustomizeProduct";
|
||||
NSString *const FBSDKAppEventNameDonate = @"Donate";
|
||||
NSString *const FBSDKAppEventNameFindLocation = @"FindLocation";
|
||||
NSString *const FBSDKAppEventNameSchedule = @"Schedule";
|
||||
NSString *const FBSDKAppEventNameStartTrial = @"StartTrial";
|
||||
NSString *const FBSDKAppEventNameSubmitApplication = @"SubmitApplication";
|
||||
NSString *const FBSDKAppEventNameSubscribe = @"Subscribe";
|
||||
NSString *const FBSDKAppEventNameAdImpression = @"AdImpression";
|
||||
NSString *const FBSDKAppEventNameAdClick = @"AdClick";
|
||||
FBSDKAppEventName FBSDKAppEventNameCompletedRegistration = @"fb_mobile_complete_registration";
|
||||
FBSDKAppEventName FBSDKAppEventNameViewedContent = @"fb_mobile_content_view";
|
||||
FBSDKAppEventName FBSDKAppEventNameSearched = @"fb_mobile_search";
|
||||
FBSDKAppEventName FBSDKAppEventNameRated = @"fb_mobile_rate";
|
||||
FBSDKAppEventName FBSDKAppEventNameCompletedTutorial = @"fb_mobile_tutorial_completion";
|
||||
FBSDKAppEventName FBSDKAppEventNameContact = @"Contact";
|
||||
FBSDKAppEventName FBSDKAppEventNameCustomizeProduct = @"CustomizeProduct";
|
||||
FBSDKAppEventName FBSDKAppEventNameDonate = @"Donate";
|
||||
FBSDKAppEventName FBSDKAppEventNameFindLocation = @"FindLocation";
|
||||
FBSDKAppEventName FBSDKAppEventNameSchedule = @"Schedule";
|
||||
FBSDKAppEventName FBSDKAppEventNameStartTrial = @"StartTrial";
|
||||
FBSDKAppEventName FBSDKAppEventNameSubmitApplication = @"SubmitApplication";
|
||||
FBSDKAppEventName FBSDKAppEventNameSubscribe = @"Subscribe";
|
||||
FBSDKAppEventName FBSDKAppEventNameSubscriptionHeartbeat = @"SubscriptionHeartbeat";
|
||||
FBSDKAppEventName FBSDKAppEventNameAdImpression = @"AdImpression";
|
||||
FBSDKAppEventName FBSDKAppEventNameAdClick = @"AdClick";
|
||||
|
||||
// Ecommerce related
|
||||
NSString *const FBSDKAppEventNameAddedToCart = @"fb_mobile_add_to_cart";
|
||||
NSString *const FBSDKAppEventNameAddedToWishlist = @"fb_mobile_add_to_wishlist";
|
||||
NSString *const FBSDKAppEventNameInitiatedCheckout = @"fb_mobile_initiated_checkout";
|
||||
NSString *const FBSDKAppEventNameAddedPaymentInfo = @"fb_mobile_add_payment_info";
|
||||
NSString *const FBSDKAppEventNameProductCatalogUpdate = @"fb_mobile_catalog_update";
|
||||
FBSDKAppEventName FBSDKAppEventNameAddedToCart = @"fb_mobile_add_to_cart";
|
||||
FBSDKAppEventName FBSDKAppEventNameAddedToWishlist = @"fb_mobile_add_to_wishlist";
|
||||
FBSDKAppEventName FBSDKAppEventNameInitiatedCheckout = @"fb_mobile_initiated_checkout";
|
||||
FBSDKAppEventName FBSDKAppEventNameAddedPaymentInfo = @"fb_mobile_add_payment_info";
|
||||
FBSDKAppEventName FBSDKAppEventNameProductCatalogUpdate = @"fb_mobile_catalog_update";
|
||||
FBSDKAppEventName FBSDKAppEventNamePurchased = @"fb_mobile_purchase";
|
||||
|
||||
// Gaming related
|
||||
NSString *const FBSDKAppEventNameAchievedLevel = @"fb_mobile_level_achieved";
|
||||
NSString *const FBSDKAppEventNameUnlockedAchievement = @"fb_mobile_achievement_unlocked";
|
||||
NSString *const FBSDKAppEventNameSpentCredits = @"fb_mobile_spent_credits";
|
||||
FBSDKAppEventName FBSDKAppEventNameAchievedLevel = @"fb_mobile_level_achieved";
|
||||
FBSDKAppEventName FBSDKAppEventNameUnlockedAchievement = @"fb_mobile_achievement_unlocked";
|
||||
FBSDKAppEventName FBSDKAppEventNameSpentCredits = @"fb_mobile_spent_credits";
|
||||
|
||||
//
|
||||
// Public event parameter names
|
||||
//
|
||||
|
||||
NSString *const FBSDKAppEventParameterNameCurrency = @"fb_currency";
|
||||
NSString *const FBSDKAppEventParameterNameRegistrationMethod = @"fb_registration_method";
|
||||
NSString *const FBSDKAppEventParameterNameContentType = @"fb_content_type";
|
||||
NSString *const FBSDKAppEventParameterNameContent = @"fb_content";
|
||||
NSString *const FBSDKAppEventParameterNameContentID = @"fb_content_id";
|
||||
NSString *const FBSDKAppEventParameterNameSearchString = @"fb_search_string";
|
||||
NSString *const FBSDKAppEventParameterNameSuccess = @"fb_success";
|
||||
NSString *const FBSDKAppEventParameterNameMaxRatingValue = @"fb_max_rating_value";
|
||||
NSString *const FBSDKAppEventParameterNamePaymentInfoAvailable = @"fb_payment_info_available";
|
||||
NSString *const FBSDKAppEventParameterNameNumItems = @"fb_num_items";
|
||||
NSString *const FBSDKAppEventParameterNameLevel = @"fb_level";
|
||||
NSString *const FBSDKAppEventParameterNameDescription = @"fb_description";
|
||||
NSString *const FBSDKAppEventParameterLaunchSource = @"fb_mobile_launch_source";
|
||||
NSString *const FBSDKAppEventParameterNameAdType = @"ad_type";
|
||||
NSString *const FBSDKAppEventParameterNameOrderID = @"fb_order_id";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameCurrency = @"fb_currency";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameRegistrationMethod = @"fb_registration_method";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameContentType = @"fb_content_type";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameContent = @"fb_content";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameContentID = @"fb_content_id";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameSearchString = @"fb_search_string";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameSuccess = @"fb_success";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameMaxRatingValue = @"fb_max_rating_value";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNamePaymentInfoAvailable = @"fb_payment_info_available";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameNumItems = @"fb_num_items";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameLevel = @"fb_level";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameDescription = @"fb_description";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterLaunchSource = @"fb_mobile_launch_source";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameAdType = @"ad_type";
|
||||
FBSDKAppEventParameterName FBSDKAppEventParameterNameOrderID = @"fb_order_id";
|
||||
|
||||
//
|
||||
// Public event parameter names for DPA Catalog
|
||||
//
|
||||
|
||||
NSString *const FBSDKAppEventParameterProductCustomLabel0 = @"fb_product_custom_label_0";
|
||||
NSString *const FBSDKAppEventParameterProductCustomLabel1 = @"fb_product_custom_label_1";
|
||||
NSString *const FBSDKAppEventParameterProductCustomLabel2 = @"fb_product_custom_label_2";
|
||||
NSString *const FBSDKAppEventParameterProductCustomLabel3 = @"fb_product_custom_label_3";
|
||||
NSString *const FBSDKAppEventParameterProductCustomLabel4 = @"fb_product_custom_label_4";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIOSUrl = @"fb_product_applink_ios_url";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIOSAppStoreID = @"fb_product_applink_ios_app_store_id";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIOSAppName = @"fb_product_applink_ios_app_name";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIPhoneUrl = @"fb_product_applink_iphone_url";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIPhoneAppStoreID = @"fb_product_applink_iphone_app_store_id";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIPhoneAppName = @"fb_product_applink_iphone_app_name";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIPadUrl = @"fb_product_applink_ipad_url";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIPadAppStoreID = @"fb_product_applink_ipad_app_store_id";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkIPadAppName = @"fb_product_applink_ipad_app_name";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkAndroidUrl = @"fb_product_applink_android_url";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkAndroidPackage = @"fb_product_applink_android_package";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkAndroidAppName = @"fb_product_applink_android_app_name";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkWindowsPhoneUrl = @"fb_product_applink_windows_phone_url";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkWindowsPhoneAppID = @"fb_product_applink_windows_phone_app_id";
|
||||
NSString *const FBSDKAppEventParameterProductAppLinkWindowsPhoneAppName = @"fb_product_applink_windows_phone_app_name";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel0 = @"fb_product_custom_label_0";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel1 = @"fb_product_custom_label_1";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel2 = @"fb_product_custom_label_2";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel3 = @"fb_product_custom_label_3";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel4 = @"fb_product_custom_label_4";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCategory = @"fb_product_category";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSUrl = @"fb_product_applink_ios_url";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSAppStoreID = @"fb_product_applink_ios_app_store_id";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSAppName = @"fb_product_applink_ios_app_name";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneUrl = @"fb_product_applink_iphone_url";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneAppStoreID = @"fb_product_applink_iphone_app_store_id";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneAppName = @"fb_product_applink_iphone_app_name";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadUrl = @"fb_product_applink_ipad_url";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadAppStoreID = @"fb_product_applink_ipad_app_store_id";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadAppName = @"fb_product_applink_ipad_app_name";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidUrl = @"fb_product_applink_android_url";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidPackage = @"fb_product_applink_android_package";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidAppName = @"fb_product_applink_android_app_name";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneUrl = @"fb_product_applink_windows_phone_url";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneAppID = @"fb_product_applink_windows_phone_app_id";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneAppName = @"fb_product_applink_windows_phone_app_name";
|
||||
|
||||
//
|
||||
// Public event parameter values
|
||||
//
|
||||
|
||||
NSString *const FBSDKAppEventParameterValueNo = @"0";
|
||||
NSString *const FBSDKAppEventParameterValueYes = @"1";
|
||||
FBSDKAppEventParameterValue FBSDKAppEventParameterValueNo = @"0";
|
||||
FBSDKAppEventParameterValue FBSDKAppEventParameterValueYes = @"1";
|
||||
|
||||
//
|
||||
// Public event user data types
|
||||
//
|
||||
|
||||
FBSDKAppEventUserDataType FBSDKAppEventEmail = @"em";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventFirstName = @"fn";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventLastName = @"ln";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventPhone = @"ph";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventDateOfBirth = @"dob";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventGender = @"ge";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventCity = @"ct";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventState = @"st";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventZip = @"zp";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventCountry = @"country";
|
||||
|
||||
//
|
||||
// Event names internal to this file
|
||||
//
|
||||
NSString *const FBSDKAppEventNamePurchased = @"fb_mobile_purchase";
|
||||
FBSDKAppEventName FBSDKAppEventNameLoginViewUsage = @"fb_login_view_usage";
|
||||
FBSDKAppEventName FBSDKAppEventNameShareSheetLaunch = @"fb_share_sheet_launch";
|
||||
FBSDKAppEventName FBSDKAppEventNameShareSheetDismiss = @"fb_share_sheet_dismiss";
|
||||
FBSDKAppEventName FBSDKAppEventNameShareTrayDidLaunch = @"fb_share_tray_did_launch";
|
||||
FBSDKAppEventName FBSDKAppEventNameShareTrayDidSelectActivity = @"fb_share_tray_did_select_activity";
|
||||
FBSDKAppEventName FBSDKAppEventNamePermissionsUILaunch = @"fb_permissions_ui_launch";
|
||||
FBSDKAppEventName FBSDKAppEventNamePermissionsUIDismiss = @"fb_permissions_ui_dismiss";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentShareDialog = @"fb_dialogs_present_share";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentShareDialogPhoto = @"fb_dialogs_present_share_photo";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentShareDialogOG = @"fb_dialogs_present_share_og";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentLikeDialogOG = @"fb_dialogs_present_like_og";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentMessageDialog = @"fb_dialogs_present_message";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentMessageDialogPhoto = @"fb_dialogs_present_message_photo";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentMessageDialogOG = @"fb_dialogs_present_message_og";
|
||||
|
||||
NSString *const FBSDKAppEventNameLoginViewUsage = @"fb_login_view_usage";
|
||||
NSString *const FBSDKAppEventNameShareSheetLaunch = @"fb_share_sheet_launch";
|
||||
NSString *const FBSDKAppEventNameShareSheetDismiss = @"fb_share_sheet_dismiss";
|
||||
NSString *const FBSDKAppEventNameShareTrayDidLaunch = @"fb_share_tray_did_launch";
|
||||
NSString *const FBSDKAppEventNameShareTrayDidSelectActivity = @"fb_share_tray_did_select_activity";
|
||||
NSString *const FBSDKAppEventNamePermissionsUILaunch = @"fb_permissions_ui_launch";
|
||||
NSString *const FBSDKAppEventNamePermissionsUIDismiss = @"fb_permissions_ui_dismiss";
|
||||
NSString *const FBSDKAppEventNameFBDialogsPresentShareDialog = @"fb_dialogs_present_share";
|
||||
NSString *const FBSDKAppEventNameFBDialogsPresentShareDialogPhoto = @"fb_dialogs_present_share_photo";
|
||||
NSString *const FBSDKAppEventNameFBDialogsPresentShareDialogOG = @"fb_dialogs_present_share_og";
|
||||
NSString *const FBSDKAppEventNameFBDialogsPresentLikeDialogOG = @"fb_dialogs_present_like_og";
|
||||
NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialog = @"fb_dialogs_present_message";
|
||||
NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialogPhoto = @"fb_dialogs_present_message_photo";
|
||||
NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialogOG = @"fb_dialogs_present_message_og";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBDialogsNativeLoginDialogStart = @"fb_dialogs_native_login_dialog_start";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsNativeLoginDialogStart = @"fb_dialogs_native_login_dialog_start";
|
||||
NSString *const FBSDKAppEventsNativeLoginDialogStartTime = @"fb_native_login_dialog_start_time";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBDialogsNativeLoginDialogEnd = @"fb_dialogs_native_login_dialog_end";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsNativeLoginDialogEnd = @"fb_dialogs_native_login_dialog_end";
|
||||
NSString *const FBSDKAppEventsNativeLoginDialogEndTime = @"fb_native_login_dialog_end_time";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBDialogsWebLoginCompleted = @"fb_dialogs_web_login_dialog_complete";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBDialogsWebLoginCompleted = @"fb_dialogs_web_login_dialog_complete";
|
||||
NSString *const FBSDKAppEventsWebLoginE2E = @"fb_web_login_e2e";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBSessionAuthStart = @"fb_mobile_login_start";
|
||||
NSString *const FBSDKAppEventNameFBSessionAuthEnd = @"fb_mobile_login_complete";
|
||||
NSString *const FBSDKAppEventNameFBSessionAuthMethodStart = @"fb_mobile_login_method_start";
|
||||
NSString *const FBSDKAppEventNameFBSessionAuthMethodEnd = @"fb_mobile_login_method_complete";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSessionAuthStart = @"fb_mobile_login_start";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSessionAuthEnd = @"fb_mobile_login_complete";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSessionAuthMethodStart = @"fb_mobile_login_method_start";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSessionAuthMethodEnd = @"fb_mobile_login_method_complete";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeButtonImpression = @"fb_like_button_impression";
|
||||
NSString *const FBSDKAppEventNameFBSDKLoginButtonImpression = @"fb_login_button_impression";
|
||||
NSString *const FBSDKAppEventNameFBSDKSendButtonImpression = @"fb_send_button_impression";
|
||||
NSString *const FBSDKAppEventNameFBSDKShareButtonImpression = @"fb_share_button_impression";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingButtonImpression = @"fb_live_streaming_button_impression";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeButtonImpression = @"fb_like_button_impression";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLoginButtonImpression = @"fb_login_button_impression";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKSendButtonImpression = @"fb_send_button_impression";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKShareButtonImpression = @"fb_share_button_impression";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingButtonImpression = @"fb_live_streaming_button_impression";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBSDKSmartLoginService = @"fb_smart_login_service";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKSmartLoginService = @"fb_smart_login_service";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeButtonDidTap = @"fb_like_button_did_tap";
|
||||
NSString *const FBSDKAppEventNameFBSDKLoginButtonDidTap = @"fb_login_button_did_tap";
|
||||
NSString *const FBSDKAppEventNameFBSDKSendButtonDidTap = @"fb_send_button_did_tap";
|
||||
NSString *const FBSDKAppEventNameFBSDKShareButtonDidTap = @"fb_share_button_did_tap";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingButtonDidTap = @"fb_live_streaming_button_did_tap";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeButtonDidTap = @"fb_like_button_did_tap";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLoginButtonDidTap = @"fb_login_button_did_tap";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKSendButtonDidTap = @"fb_send_button_did_tap";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKShareButtonDidTap = @"fb_share_button_did_tap";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingButtonDidTap = @"fb_live_streaming_button_did_tap";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeControlDidDisable = @"fb_like_control_did_disable";
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeControlDidLike = @"fb_like_control_did_like";
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeControlDidPresentDialog = @"fb_like_control_did_present_dialog";
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeControlDidTap = @"fb_like_control_did_tap";
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeControlDidUnlike = @"fb_like_control_did_unlike";
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeControlError = @"fb_like_control_error";
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeControlImpression = @"fb_like_control_impression";
|
||||
NSString *const FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable = @"fb_like_control_network_unavailable";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidDisable = @"fb_like_control_did_disable";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidLike = @"fb_like_control_did_like";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidPresentDialog = @"fb_like_control_did_present_dialog";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidTap = @"fb_like_control_did_tap";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidUnlike = @"fb_like_control_did_unlike";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlError = @"fb_like_control_error";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlImpression = @"fb_like_control_impression";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable = @"fb_like_control_network_unavailable";
|
||||
|
||||
NSString *const FBSDLAppEventNameFBSDKEventShareDialogResult = @"fb_dialog_share_result";
|
||||
NSString *const FBSDKAppEventNameFBSDKEventMessengerShareDialogResult = @"fb_messenger_dialog_share_result";
|
||||
NSString *const FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult = @"fb_app_invite_dialog_share_result";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKEventShareDialogResult = @"fb_dialog_share_result";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKEventMessengerShareDialogResult = @"fb_messenger_dialog_share_result";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult = @"fb_app_invite_dialog_share_result";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBSDKEventShareDialogShow = @"fb_dialog_share_show";
|
||||
NSString *const FBSDKAppEventNameFBSDKEventMessengerShareDialogShow = @"fb_messenger_dialog_share_show";
|
||||
NSString *const FBSDKAppEventNameFBSDKEventAppInviteShareDialogShow = @"fb_app_invite_share_show";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKEventShareDialogShow = @"fb_dialog_share_show";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKEventMessengerShareDialogShow = @"fb_messenger_dialog_share_show";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKEventAppInviteShareDialogShow = @"fb_app_invite_share_show";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBSessionFASLoginDialogResult = @"fb_mobile_login_fas_dialog_result";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSessionFASLoginDialogResult = @"fb_mobile_login_fas_dialog_result";
|
||||
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingStart = @"fb_sdk_live_streaming_start";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingStop = @"fb_sdk_live_streaming_stop";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingPause = @"fb_sdk_live_streaming_pause";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingResume = @"fb_sdk_live_streaming_resume";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingError = @"fb_sdk_live_streaming_error";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingUpdateStatus = @"fb_sdk_live_streaming_update_status";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingVideoID = @"fb_sdk_live_streaming_video_id";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingMic = @"fb_sdk_live_streaming_mic";
|
||||
NSString *const FBSDKAppEventNameFBSDKLiveStreamingCamera = @"fb_sdk_live_streaming_camera";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingStart = @"fb_sdk_live_streaming_start";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingStop = @"fb_sdk_live_streaming_stop";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingPause = @"fb_sdk_live_streaming_pause";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingResume = @"fb_sdk_live_streaming_resume";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingError = @"fb_sdk_live_streaming_error";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingUpdateStatus = @"fb_sdk_live_streaming_update_status";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingVideoID = @"fb_sdk_live_streaming_video_id";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingMic = @"fb_sdk_live_streaming_mic";
|
||||
FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingCamera = @"fb_sdk_live_streaming_camera";
|
||||
|
||||
// Event Parameters internal to this file
|
||||
NSString *const FBSDKAppEventParameterDialogOutcome = @"fb_dialog_outcome";
|
||||
@@ -220,6 +238,7 @@ NSString *const FBSDKAppEventParameterShareTrayResult = @"fb_share_t
|
||||
NSString *const FBSDKAppEventParameterLogTime = @"_logTime";
|
||||
NSString *const FBSDKAppEventParameterEventName = @"_eventName";
|
||||
NSString *const FBSDKAppEventParameterImplicitlyLogged = @"_implicitlyLogged";
|
||||
NSString *const FBSDKAppEventParameterInBackground = @"_inBackground";
|
||||
|
||||
NSString *const FBSDKAppEventParameterLiveStreamingPrevStatus = @"live_streaming_prev_status";
|
||||
NSString *const FBSDKAppEventParameterLiveStreamingStatus = @"live_streaming_status";
|
||||
@@ -228,18 +247,18 @@ NSString *const FBSDKAppEventParameterLiveStreamingVideoID = @"live_stream
|
||||
NSString *const FBSDKAppEventParameterLiveStreamingMicEnabled = @"live_streaming_mic_enabled";
|
||||
NSString *const FBSDKAppEventParameterLiveStreamingCameraEnabled = @"live_streaming_camera_enabled";
|
||||
|
||||
NSString *const FBSDKAppEventParameterProductItemID = @"fb_product_item_id";
|
||||
NSString *const FBSDKAppEventParameterProductAvailability = @"fb_product_availability";
|
||||
NSString *const FBSDKAppEventParameterProductCondition = @"fb_product_condition";
|
||||
NSString *const FBSDKAppEventParameterProductDescription = @"fb_product_description";
|
||||
NSString *const FBSDKAppEventParameterProductImageLink = @"fb_product_image_link";
|
||||
NSString *const FBSDKAppEventParameterProductLink = @"fb_product_link";
|
||||
NSString *const FBSDKAppEventParameterProductTitle = @"fb_product_title";
|
||||
NSString *const FBSDKAppEventParameterProductGTIN = @"fb_product_gtin";
|
||||
NSString *const FBSDKAppEventParameterProductMPN = @"fb_product_mpn";
|
||||
NSString *const FBSDKAppEventParameterProductBrand = @"fb_product_brand";
|
||||
NSString *const FBSDKAppEventParameterProductPriceAmount = @"fb_product_price_amount";
|
||||
NSString *const FBSDKAppEventParameterProductPriceCurrency = @"fb_product_price_currency";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductItemID = @"fb_product_item_id";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAvailability = @"fb_product_availability";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCondition = @"fb_product_condition";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductDescription = @"fb_product_description";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductImageLink = @"fb_product_image_link";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductLink = @"fb_product_link";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductTitle = @"fb_product_title";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductGTIN = @"fb_product_gtin";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductMPN = @"fb_product_mpn";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductBrand = @"fb_product_brand";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductPriceAmount = @"fb_product_price_amount";
|
||||
FBSDKAppEventParameterProduct FBSDKAppEventParameterProductPriceCurrency = @"fb_product_price_currency";
|
||||
|
||||
// Event parameter values internal to this file
|
||||
NSString *const FBSDKAppEventsDialogOutcomeValue_Completed = @"Completed";
|
||||
@@ -265,6 +284,8 @@ NSString *const FBSDKAppEventsDialogShareContentTypeMessengerMediaTemplate
|
||||
NSString *const FBSDKAppEventsDialogShareContentTypeMessengerOpenGraphMusicTemplate = @"OpenGraphMusicTemplate";
|
||||
NSString *const FBSDKAppEventsDialogShareContentTypeUnknown = @"Unknown";
|
||||
|
||||
NSString *const FBSDKGateKeeperAppEventsKillSwitch = @"app_events_killswitch";
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
NSNotificationName const FBSDKAppEventsLoggingResultNotification = @"com.facebook.sdk:FBSDKAppEventsLoggingResultNotification";
|
||||
@@ -283,8 +304,8 @@ NSString *const FBSDKAppEventsOverrideAppIDBundleKey = @"FacebookLoggingOverride
|
||||
// Activities Endpoint Parameter
|
||||
static NSString *const FBSDKActivitesParameterPushDeviceToken = @"device_token";
|
||||
// Event Names
|
||||
static NSString *const FBSDKAppEventNamePushTokenObtained = @"fb_mobile_obtain_push_token";
|
||||
static NSString *const FBSDKAppEventNamePushOpened = @"fb_mobile_push_opened";
|
||||
static FBSDKAppEventName FBSDKAppEventNamePushTokenObtained = @"fb_mobile_obtain_push_token";
|
||||
static FBSDKAppEventName FBSDKAppEventNamePushOpened = @"fb_mobile_push_opened";
|
||||
// Event Parameter
|
||||
static NSString *const FBSDKAppEventParameterPushCampaign = @"fb_push_campaign";
|
||||
static NSString *const FBSDKAppEventParameterPushAction = @"fb_push_action";
|
||||
@@ -301,7 +322,6 @@ NSString *const FBSDKAppEventsWKWebViewMessagesEventKey = @"event";
|
||||
NSString *const FBSDKAppEventsWKWebViewMessagesParamsKey = @"params";
|
||||
NSString *const FBSDKAPPEventsWKWebViewMessagesProtocolKey = @"fbmq-0.1";
|
||||
|
||||
|
||||
#define NUM_LOG_EVENTS_TO_TRY_TO_FLUSH_AFTER 100
|
||||
#define FLUSH_PERIOD_IN_SECONDS 15
|
||||
#define USER_ID_USER_DEFAULTS_KEY @"com.facebook.sdk.appevents.userid"
|
||||
@@ -309,11 +329,6 @@ NSString *const FBSDKAPPEventsWKWebViewMessagesProtocolKey = @"fbmq-0.1";
|
||||
#define FBUnityUtilityClassName "FBUnityUtility"
|
||||
#define FBUnityUtilityUpdateBindingsSelector @"triggerUpdateBindings:"
|
||||
|
||||
#define UNINSTALL_TRACKING_DEVICE_ID_KEY @"device_id"
|
||||
#define UNINSTALL_TRACKING_PLATFORM_KEY @"platform"
|
||||
#define UNINSTALL_TRACKING_DEVICE_TOKEN_KEY @"device_token"
|
||||
#define UNINSTALL_TRACKING_TOKEN_ENDPOINT @"app_push_device_token"
|
||||
|
||||
static NSString *g_overrideAppID = nil;
|
||||
|
||||
@interface FBSDKAppEvents ()
|
||||
@@ -346,16 +361,17 @@ static NSString *g_overrideAppID = nil;
|
||||
{
|
||||
if (self == [FBSDKAppEvents class]) {
|
||||
g_overrideAppID = [[[NSBundle mainBundle] objectForInfoDictionaryKey:FBSDKAppEventsOverrideAppIDBundleKey] copy];
|
||||
[FBSDKBasicUtility anonymousID];
|
||||
}
|
||||
}
|
||||
|
||||
- (FBSDKAppEvents *)init
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_flushBehavior = FBSDKAppEventsFlushBehaviorAuto;
|
||||
|
||||
typeof(self) __weak weakSelf = self;
|
||||
__weak FBSDKAppEvents *weakSelf = self;
|
||||
self.flushTimer = [FBSDKUtility startGCDTimerWithInterval:FLUSH_PERIOD_IN_SECONDS
|
||||
block:^{
|
||||
[weakSelf flushTimerFired:nil];
|
||||
@@ -397,21 +413,21 @@ static NSString *g_overrideAppID = nil;
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
{
|
||||
[FBSDKAppEvents logEvent:eventName
|
||||
parameters:nil];
|
||||
parameters:@{}];
|
||||
}
|
||||
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
{
|
||||
[FBSDKAppEvents logEvent:eventName
|
||||
valueToSum:valueToSum
|
||||
parameters:nil];
|
||||
parameters:@{}];
|
||||
}
|
||||
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
parameters:(NSDictionary *)parameters
|
||||
{
|
||||
[FBSDKAppEvents logEvent:eventName
|
||||
@@ -420,7 +436,7 @@ static NSString *g_overrideAppID = nil;
|
||||
accessToken:nil];
|
||||
}
|
||||
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
{
|
||||
@@ -430,7 +446,7 @@ static NSString *g_overrideAppID = nil;
|
||||
accessToken:nil];
|
||||
}
|
||||
|
||||
+ (void)logEvent:(NSString *)eventName
|
||||
+ (void)logEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(NSNumber *)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
accessToken:(FBSDKAccessToken *)accessToken
|
||||
@@ -447,7 +463,7 @@ static NSString *g_overrideAppID = nil;
|
||||
{
|
||||
[FBSDKAppEvents logPurchase:purchaseAmount
|
||||
currency:currency
|
||||
parameters:nil];
|
||||
parameters:@{}];
|
||||
}
|
||||
|
||||
+ (void)logPurchase:(double)purchaseAmount
|
||||
@@ -494,7 +510,7 @@ static NSString *g_overrideAppID = nil;
|
||||
|
||||
+ (void)logPushNotificationOpen:(NSDictionary *)payload
|
||||
{
|
||||
[self logPushNotificationOpen:payload action:nil];
|
||||
[self logPushNotificationOpen:payload action:@""];
|
||||
}
|
||||
|
||||
+ (void)logPushNotificationOpen:(NSDictionary *)payload action:(NSString *)action
|
||||
@@ -511,7 +527,7 @@ static NSString *g_overrideAppID = nil;
|
||||
}
|
||||
|
||||
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObject:campaign forKey:FBSDKAppEventParameterPushCampaign];
|
||||
if (action) {
|
||||
if (action && action.length > 0) {
|
||||
parameters[FBSDKAppEventParameterPushAction] = action;
|
||||
}
|
||||
[self logEvent:FBSDKAppEventNamePushOpened parameters:parameters];
|
||||
@@ -532,7 +548,8 @@ static NSString *g_overrideAppID = nil;
|
||||
gtin:(NSString *)gtin
|
||||
mpn:(NSString *)mpn
|
||||
brand:(NSString *)brand
|
||||
parameters:(NSDictionary *)parameters {
|
||||
parameters:(NSDictionary *)parameters
|
||||
{
|
||||
if (itemID == nil) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
|
||||
logEntry:@"itemID cannot be null"];
|
||||
@@ -634,7 +651,6 @@ static NSString *g_overrideAppID = nil;
|
||||
// when appropriate, result in logging an "activated app" and "deactivated app" (for the
|
||||
// previous session) App Event.
|
||||
[FBSDKTimeSpentData restore:YES];
|
||||
[FBSDKUserDataStore initStore];
|
||||
}
|
||||
|
||||
+ (void)setPushNotificationsDeviceToken:(NSData *)deviceToken
|
||||
@@ -713,75 +729,82 @@ static NSString *g_overrideAppID = nil;
|
||||
return [[self class] singleton]->_userID;
|
||||
}
|
||||
|
||||
+ (void)setUserData:(NSDictionary*)userData
|
||||
+ (void)setUserEmail:(nullable NSString *)email
|
||||
firstName:(nullable NSString *)firstName
|
||||
lastName:(nullable NSString *)lastName
|
||||
phone:(nullable NSString *)phone
|
||||
dateOfBirth:(nullable NSString *)dateOfBirth
|
||||
gender:(nullable NSString *)gender
|
||||
city:(nullable NSString *)city
|
||||
state:(nullable NSString *)state
|
||||
zip:(nullable NSString *)zip
|
||||
country:(nullable NSString *)country
|
||||
{
|
||||
[FBSDKUserDataStore setUserDataAndHash:userData];
|
||||
}
|
||||
|
||||
+ (void)setUserEmail:(NSString *)email
|
||||
firstName:(NSString *)firstName
|
||||
lastName:(NSString *)lastName
|
||||
phone:(NSString *)phone
|
||||
dateOfBirth:(NSString *)dateOfBirth
|
||||
gender:(NSString *)gender
|
||||
city:(NSString *)city
|
||||
state:(NSString *)state
|
||||
zip:(NSString *)zip
|
||||
country:(NSString *)country
|
||||
{
|
||||
[FBSDKUserDataStore setUserDataAndHash:email
|
||||
firstName:firstName
|
||||
lastName:lastName
|
||||
phone:phone
|
||||
dateOfBirth:dateOfBirth
|
||||
gender:gender
|
||||
city:city
|
||||
state:state
|
||||
zip:zip
|
||||
country:country];
|
||||
[FBSDKUserDataStore setAndHashUserEmail:email
|
||||
firstName:firstName
|
||||
lastName:lastName
|
||||
phone:phone
|
||||
dateOfBirth:dateOfBirth
|
||||
gender:gender
|
||||
city:city
|
||||
state:state
|
||||
zip:zip
|
||||
country:country];
|
||||
}
|
||||
|
||||
+ (NSString*)getUserData
|
||||
{
|
||||
return [FBSDKUserDataStore getHashedUserData];
|
||||
return [FBSDKUserDataStore getHashedData];
|
||||
}
|
||||
|
||||
+ (void)clearUserData
|
||||
{
|
||||
[FBSDKUserDataStore setUserDataAndHash:nil
|
||||
firstName:nil
|
||||
lastName:nil
|
||||
phone:nil
|
||||
dateOfBirth:nil
|
||||
gender:nil
|
||||
city:nil
|
||||
state:nil
|
||||
zip:nil
|
||||
country:nil];
|
||||
[FBSDKUserDataStore setAndHashUserEmail:nil
|
||||
firstName:nil
|
||||
lastName:nil
|
||||
phone:nil
|
||||
dateOfBirth:nil
|
||||
gender:nil
|
||||
city:nil
|
||||
state:nil
|
||||
zip:nil
|
||||
country:nil];
|
||||
}
|
||||
|
||||
+ (void)updateUserProperties:(NSDictionary *)properties handler:(FBSDKGraphRequestHandler)handler
|
||||
+ (void)setUserData:(nullable NSString *)data
|
||||
forType:(FBSDKAppEventUserDataType)type
|
||||
{
|
||||
[FBSDKUserDataStore setAndHashData:data forType:type];
|
||||
}
|
||||
|
||||
+ (void)clearUserDataForType:(FBSDKAppEventUserDataType)type
|
||||
{
|
||||
[FBSDKUserDataStore clearDataForType:type];
|
||||
}
|
||||
|
||||
|
||||
+ (void)updateUserProperties:(NSDictionary<NSString *, id> *)properties handler:(FBSDKGraphRequestBlock)handler
|
||||
{
|
||||
NSString *userID = [[self class] userID];
|
||||
|
||||
if (userID.length == 0) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Missing [FBSDKAppEvents userID] for [FBSDKAppEvents updateUserProperties:]"];
|
||||
NSError *error = [NSError fbRequiredArgumentErrorWithName:@"userID" message:@"Missing [FBSDKAppEvents userID] for [FBSDKAppEvents updateUserProperties:]"];
|
||||
NSError *error = [FBSDKError requiredArgumentErrorWithName:@"userID" message:@"Missing [FBSDKAppEvents userID] for [FBSDKAppEvents updateUserProperties:]"];
|
||||
if (handler) {
|
||||
handler(nil, nil, error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
NSMutableDictionary *dataDictionary = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
dataDictionary[@"user_unique_id"] = [FBSDKAppEvents userID];
|
||||
[FBSDKInternalUtility dictionary:dataDictionary setObject:[FBSDKAppEventsUtility advertiserID] forKey:@"advertiser_id"];
|
||||
[FBSDKInternalUtility dictionary:dataDictionary setObject:properties forKey:@"custom_data"];
|
||||
[FBSDKBasicUtility dictionary:dataDictionary setObject:[FBSDKAppEvents userID] forKey:@"user_unique_id"];
|
||||
[FBSDKBasicUtility dictionary:dataDictionary setObject:[FBSDKAppEventsUtility advertiserID] forKey:@"advertiser_id"];
|
||||
[FBSDKBasicUtility dictionary:dataDictionary setObject:properties forKey:@"custom_data"];
|
||||
|
||||
NSError *error;
|
||||
__block NSError *invalidObjectError;
|
||||
NSString *dataJSONString = [FBSDKInternalUtility JSONStringForObject:@[dataDictionary] error:&error invalidObjectHandler:^id(id object, BOOL *stop) {
|
||||
NSString *dataJSONString = [FBSDKBasicUtility JSONStringForObject:@[dataDictionary] error:&error invalidObjectHandler:^id(id object, BOOL *stop) {
|
||||
*stop = YES;
|
||||
invalidObjectError = [NSError fbUnknownErrorWithMessage:@"The values in the properties dictionary must be NSStrings or NSNumbers"];
|
||||
invalidObjectError = [FBSDKError unknownErrorWithMessage:@"The values in the properties dictionary must be NSStrings or NSNumbers"];
|
||||
return nil;
|
||||
}];
|
||||
if (!error) {
|
||||
@@ -798,7 +821,7 @@ static NSString *g_overrideAppID = nil;
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/user_properties", [[self singleton] appID]]
|
||||
parameters:params
|
||||
tokenString:[FBSDKAccessToken currentAccessToken].tokenString
|
||||
HTTPMethod:@"POST"
|
||||
HTTPMethod:FBSDKHTTPMethodPOST
|
||||
flags:FBSDKGraphRequestFlagDisableErrorRecovery |
|
||||
FBSDKGraphRequestFlagDoNotInvalidateTokenOnError |
|
||||
FBSDKGraphRequestFlagSkipClientToken
|
||||
@@ -864,6 +887,74 @@ static NSString *g_overrideAppID = nil;
|
||||
|
||||
#pragma mark - Internal Methods
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged;
|
||||
{
|
||||
[FBSDKAppEvents logInternalEvent:eventName
|
||||
parameters:@{}
|
||||
isImplicitlyLogged:isImplicitlyLogged];
|
||||
}
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged
|
||||
{
|
||||
[FBSDKAppEvents logInternalEvent:eventName
|
||||
valueToSum:valueToSum
|
||||
parameters:@{}
|
||||
isImplicitlyLogged:isImplicitlyLogged];
|
||||
}
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged
|
||||
{
|
||||
[FBSDKAppEvents logInternalEvent:eventName
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
isImplicitlyLogged:isImplicitlyLogged
|
||||
accessToken:nil];
|
||||
}
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged
|
||||
accessToken:(FBSDKAccessToken *)accessToken
|
||||
{
|
||||
[FBSDKAppEvents logInternalEvent:eventName
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
isImplicitlyLogged:isImplicitlyLogged
|
||||
accessToken:accessToken];
|
||||
}
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged
|
||||
{
|
||||
[FBSDKAppEvents logInternalEvent:eventName
|
||||
valueToSum:@(valueToSum)
|
||||
parameters:parameters
|
||||
isImplicitlyLogged:isImplicitlyLogged
|
||||
accessToken:nil];
|
||||
}
|
||||
|
||||
+ (void)logInternalEvent:(NSString *)eventName
|
||||
valueToSum:(NSNumber *)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged
|
||||
accessToken:(FBSDKAccessToken *)accessToken
|
||||
{
|
||||
if ([FBSDKSettings isAutoLogAppEventsEnabled]) {
|
||||
[[FBSDKAppEvents singleton] instanceLogEvent:eventName
|
||||
valueToSum:valueToSum
|
||||
parameters:parameters
|
||||
isImplicitlyLogged:isImplicitlyLogged
|
||||
accessToken:accessToken];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)logImplicitEvent:(NSString *)eventName
|
||||
valueToSum:(NSNumber *)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
@@ -882,7 +973,7 @@ static NSString *g_overrideAppID = nil;
|
||||
static FBSDKAppEvents *shared = nil;
|
||||
|
||||
dispatch_once(&pred, ^{
|
||||
shared = [[FBSDKAppEvents alloc] init];
|
||||
shared = [[self alloc] init];
|
||||
});
|
||||
return shared;
|
||||
}
|
||||
@@ -931,7 +1022,7 @@ static NSString *g_overrideAppID = nil;
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:path
|
||||
parameters:params
|
||||
tokenString:nil
|
||||
HTTPMethod:@"POST"
|
||||
HTTPMethod:FBSDKHTTPMethodPOST
|
||||
flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery];
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
if (!error) {
|
||||
@@ -947,9 +1038,10 @@ static NSString *g_overrideAppID = nil;
|
||||
#if !TARGET_OS_TV
|
||||
- (void)enableCodelessEvents {
|
||||
if (_serverConfiguration.isCodelessEventsEnabled) {
|
||||
[FBSDKCodelessIndexer enable];
|
||||
|
||||
if (!_eventBindingManager) {
|
||||
_eventBindingManager = [[FBSDKEventBindingManager alloc] init];
|
||||
[_eventBindingManager start];
|
||||
}
|
||||
|
||||
if ([FBSDKInternalUtility isUnity]) {
|
||||
@@ -963,18 +1055,28 @@ static NSString *g_overrideAppID = nil;
|
||||
#endif
|
||||
|
||||
// app events can use a server configuration up to 24 hours old to minimize network traffic.
|
||||
- (void)fetchServerConfiguration:(void (^)(void))callback
|
||||
- (void)fetchServerConfiguration:(FBSDKCodeBlock)callback
|
||||
{
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *error) {
|
||||
self->_serverConfiguration = serverConfiguration;
|
||||
|
||||
if (self->_serverConfiguration.implicitPurchaseLoggingEnabled) {
|
||||
if (self->_serverConfiguration.implicitPurchaseLoggingEnabled && [FBSDKSettings isAutoLogAppEventsEnabled]) {
|
||||
[FBSDKPaymentObserver startObservingTransactions];
|
||||
} else {
|
||||
[FBSDKPaymentObserver stopObservingTransactions];
|
||||
}
|
||||
#if !TARGET_OS_TV
|
||||
[self enableCodelessEvents];
|
||||
[FBSDKFeatureManager checkFeature:FBSDKFeatureCodelessEvents completionBlock:^(BOOL enabled) {
|
||||
if (enabled) {
|
||||
[self enableCodelessEvents];
|
||||
}
|
||||
}];
|
||||
[FBSDKFeatureManager checkFeature:FBSDKFeatureAAM completionBlock:^(BOOL enabled) {
|
||||
if (enabled) {
|
||||
// Enable AAM
|
||||
[FBSDKMetadataIndexer enable];
|
||||
}
|
||||
}];
|
||||
#endif
|
||||
if (callback) {
|
||||
callback();
|
||||
@@ -982,12 +1084,21 @@ static NSString *g_overrideAppID = nil;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)instanceLogEvent:(NSString *)eventName
|
||||
- (void)instanceLogEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(NSNumber *)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged
|
||||
accessToken:(FBSDKAccessToken *)accessToken
|
||||
{
|
||||
// Kill events if kill-switch is enabled
|
||||
if ([FBSDKGateKeeperManager boolForKey:FBSDKGateKeeperAppEventsKillSwitch
|
||||
defaultValue:NO]) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents
|
||||
formatString:@"FBSDKAppEvents: KillSwitch is enabled and fail to log app event: %@",
|
||||
eventName];
|
||||
return;
|
||||
}
|
||||
|
||||
if (isImplicitlyLogged && _serverConfiguration && !_serverConfiguration.isImplicitLoggingSupported) {
|
||||
return;
|
||||
}
|
||||
@@ -995,12 +1106,7 @@ static NSString *g_overrideAppID = nil;
|
||||
if (!isImplicitlyLogged && !_explicitEventsLoggedYet) {
|
||||
_explicitEventsLoggedYet = YES;
|
||||
}
|
||||
|
||||
__block BOOL failed = NO;
|
||||
|
||||
if (![FBSDKAppEventsUtility validateIdentifier:eventName]) {
|
||||
failed = YES;
|
||||
}
|
||||
__block BOOL failed = ![FBSDKAppEventsUtility validateIdentifier:eventName];
|
||||
|
||||
// Make sure parameter dictionary is well formed. Log and exit if not.
|
||||
[parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||
@@ -1022,32 +1128,43 @@ static NSString *g_overrideAppID = nil;
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *eventDictionary = [NSMutableDictionary dictionaryWithDictionary:parameters];
|
||||
parameters = [FBSDKRestrictiveDataFilterManager processParameters:parameters
|
||||
eventName:eventName];
|
||||
|
||||
NSMutableDictionary<NSString *, id> *eventDictionary = [NSMutableDictionary dictionaryWithDictionary:parameters];
|
||||
eventDictionary[FBSDKAppEventParameterEventName] = eventName;
|
||||
if (!eventDictionary[FBSDKAppEventParameterLogTime]) {
|
||||
eventDictionary[FBSDKAppEventParameterLogTime] = @([FBSDKAppEventsUtility unixTimeNow]);
|
||||
}
|
||||
[FBSDKInternalUtility dictionary:eventDictionary setObject:valueToSum forKey:@"_valueToSum"];
|
||||
[FBSDKBasicUtility dictionary:eventDictionary setObject:valueToSum forKey:@"_valueToSum"];
|
||||
if (isImplicitlyLogged) {
|
||||
eventDictionary[FBSDKAppEventParameterImplicitlyLogged] = @"1";
|
||||
}
|
||||
|
||||
NSString *currentViewControllerName;
|
||||
UIApplicationState applicationState;
|
||||
if ([NSThread isMainThread]) {
|
||||
// We only collect the view controller when on the main thread, as the behavior off
|
||||
// the main thread is unpredictable. Besides, UI state for off-main-thread computations
|
||||
// isn't really relevant anyhow.
|
||||
UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController;
|
||||
UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
|
||||
vc = vc.presentedViewController ?: vc;
|
||||
if (vc) {
|
||||
currentViewControllerName = [[vc class] description];
|
||||
} else {
|
||||
currentViewControllerName = @"no_ui";
|
||||
}
|
||||
applicationState = [UIApplication sharedApplication].applicationState;
|
||||
} else {
|
||||
currentViewControllerName = @"off_thread";
|
||||
applicationState = [FBSDKApplicationDelegate applicationState];
|
||||
}
|
||||
eventDictionary[@"_ui"] = currentViewControllerName;
|
||||
|
||||
if (applicationState == UIApplicationStateBackground) {
|
||||
eventDictionary[FBSDKAppEventParameterInBackground] = @"1";
|
||||
}
|
||||
|
||||
NSString *tokenString = [FBSDKAppEventsUtility tokenStringToUseFor:accessToken];
|
||||
NSString *appID = [self appID];
|
||||
|
||||
@@ -1135,7 +1252,7 @@ static NSString *g_overrideAppID = nil;
|
||||
[FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])];
|
||||
|
||||
[self fetchServerConfiguration:^(void) {
|
||||
NSString *receipt_data = [appEventsState extractReceiptData];
|
||||
NSString *receipt_data = appEventsState.extractReceiptData;
|
||||
NSString *encodedEvents = [appEventsState JSONStringForEvents:self->_serverConfiguration.implicitLoggingEnabled];
|
||||
if (!encodedEvents) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents
|
||||
@@ -1181,7 +1298,7 @@ static NSString *g_overrideAppID = nil;
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/activities", appEventsState.appID]
|
||||
parameters:postParameters
|
||||
tokenString:appEventsState.tokenString
|
||||
HTTPMethod:@"POST"
|
||||
HTTPMethod:FBSDKHTTPMethodPOST
|
||||
flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery];
|
||||
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
@@ -1297,7 +1414,7 @@ static NSString *g_overrideAppID = nil;
|
||||
// 3) if we have a user session token, then no need to send attribution ID / advertiser ID back as the udid parameter
|
||||
// 4) otherwise, send back the udid parameter.
|
||||
|
||||
if ([FBSDKAppEventsUtility advertisingTrackingStatus] == FBSDKAdvertisingTrackingDisallowed || [FBSDKSettings limitEventAndDataUsage]) {
|
||||
if ([FBSDKAppEventsUtility advertisingTrackingStatus] == FBSDKAdvertisingTrackingDisallowed || FBSDKSettings.shouldLimitEventAndDataUsage) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
+6
-2
@@ -18,8 +18,12 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FBSDKAccessTokenCaching.h"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface FBSDKAccessTokenCacheV3_21 : NSObject<FBSDKAccessTokenCaching>
|
||||
@interface FBSDKMetadataIndexer : NSObject
|
||||
|
||||
+ (void)enable;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
Generated
+323
@@ -0,0 +1,323 @@
|
||||
// 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 "FBSDKMetadataIndexer.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#import <sys/sysctl.h>
|
||||
#import <sys/utsname.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
static const int FBSDKMetadataIndexerMaxTextLength = 100;
|
||||
static const int FBSDKMetadataIndexerMaxIndicatorLength = 100;
|
||||
static const int FBSDKMetadataIndexerMaxValue = 5;
|
||||
|
||||
static NSString * const FIELD_K = @"k";
|
||||
static NSString * const FIELD_V = @"v";
|
||||
static NSString * const FIELD_K_DELIMITER = @",";
|
||||
|
||||
FBSDKAppEventUserDataType FBSDKAppEventRule1 = @"r1";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventRule2 = @"r2";
|
||||
|
||||
static NSArray<FBSDKAppEventUserDataType> *FBSDKMetadataIndexerKeys;
|
||||
static NSMutableDictionary<NSString *, NSDictionary<NSString *, NSString *> *> *_rules;
|
||||
static NSMutableDictionary<NSString *, NSMutableArray<NSString *> *> *_store;
|
||||
static dispatch_queue_t serialQueue;
|
||||
|
||||
@implementation FBSDKMetadataIndexer
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
FBSDKMetadataIndexerKeys = @[FBSDKAppEventRule1, FBSDKAppEventRule2];
|
||||
serialQueue = dispatch_queue_create("com.facebook.appevents.MetadataIndexer", DISPATCH_QUEUE_SERIAL);
|
||||
}
|
||||
|
||||
+ (void)enable
|
||||
{
|
||||
if (FBSDKAdvertisingTrackingAllowed != [FBSDKAppEventsUtility advertisingTrackingStatus]) {
|
||||
return;
|
||||
}
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *error) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
[FBSDKMetadataIndexer setupWithRules:serverConfiguration.AAMRules];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)setupWithRules:(NSDictionary<NSString *, id> * _Nullable)rules
|
||||
{
|
||||
if (0 == rules.count) {
|
||||
return;
|
||||
}
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[FBSDKMetadataIndexer constructRules:rules];
|
||||
[FBSDKMetadataIndexer initStore];
|
||||
|
||||
BOOL isEnabled = NO;
|
||||
for (NSString *key in FBSDKMetadataIndexerKeys) {
|
||||
BOOL isRuleEnabled = (nil != [_rules objectForKey:key]);
|
||||
if (isRuleEnabled) {
|
||||
isEnabled = YES;
|
||||
}
|
||||
if (!isRuleEnabled) {
|
||||
[_store removeObjectForKey:key];
|
||||
[FBSDKUserDataStore setHashData:nil forType:key];
|
||||
}
|
||||
}
|
||||
|
||||
if (isEnabled) {
|
||||
[FBSDKMetadataIndexer setupMetadataIndexing];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)initStore
|
||||
{
|
||||
_store = [[NSMutableDictionary alloc] init];
|
||||
for (NSString *key in FBSDKMetadataIndexerKeys) {
|
||||
NSString *data = [FBSDKUserDataStore getHashedDataForType:key];
|
||||
if (data.length > 0) {
|
||||
_store[key] = [NSMutableArray arrayWithArray:[data componentsSeparatedByString:FIELD_K_DELIMITER]];
|
||||
}
|
||||
}
|
||||
|
||||
for (NSString *key in FBSDKMetadataIndexerKeys) {
|
||||
if (!_store[key]) {
|
||||
_store[key] = [[NSMutableArray alloc] init];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)constructRules:(NSDictionary<NSString *, id> * _Nullable)rules
|
||||
{
|
||||
if (!_rules) {
|
||||
_rules = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
for (NSString *key in rules) {
|
||||
NSDictionary<NSString *, NSString *> *value = [FBSDKTypeUtility dictionaryValue:rules[key]];
|
||||
if (value && value[FIELD_K].length > 0 && value[FIELD_V].length > 0) {
|
||||
_rules[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setupMetadataIndexing
|
||||
{
|
||||
void (^block)(UIView *) = ^(UIView *view) {
|
||||
// Indexing when the view is removed from window and conforms to UITextInput, and skip UIFieldEditor, which is an internval view of UITextField
|
||||
if (![view window] && ![NSStringFromClass([view class]) isEqualToString:@"UIFieldEditor"] && [view conformsToProtocol:@protocol(UITextInput)]) {
|
||||
NSString *text = [FBSDKViewHierarchy getText:view];
|
||||
NSString *placeholder = [FBSDKViewHierarchy getHint:view];
|
||||
BOOL secureTextEntry = [self checkSecureTextEntry:view];
|
||||
NSArray<NSString *> *labels = [self getLabelsOfView:view];
|
||||
UIKeyboardType keyboardType = [self getKeyboardType:view];
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
|
||||
[self getMetadataWithText:[self normalizedValue:text]
|
||||
placeholder:[self normalizeField:placeholder]
|
||||
labels:labels
|
||||
secureTextEntry:secureTextEntry
|
||||
inputType:keyboardType];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
[FBSDKSwizzler swizzleSelector:@selector(didMoveToWindow) onClass:[UIView class] withBlock:block named:@"metadataIndexingUIView"];
|
||||
|
||||
// iOS 12: UITextField implements didMoveToWindow without calling parent implementation
|
||||
if (@available(iOS 12, *)) {
|
||||
[FBSDKSwizzler swizzleSelector:@selector(didMoveToWindow) onClass:[UITextField class] withBlock:block named:@"metadataIndexingUITextField"];
|
||||
} else {
|
||||
[FBSDKSwizzler swizzleSelector:@selector(didMoveToWindow) onClass:[UIControl class] withBlock:block named:@"metadataIndexingUIControl"];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSArray<UIView *> *)getSiblingViewsOfView:(UIView *)view
|
||||
{
|
||||
NSObject *parent = [FBSDKViewHierarchy getParent:view];
|
||||
if (parent) {
|
||||
NSArray<id> *views = [FBSDKViewHierarchy getChildren:parent];
|
||||
if (views) {
|
||||
NSMutableArray<id> *siblings = [NSMutableArray arrayWithArray:views];
|
||||
[siblings removeObject:view];
|
||||
return [siblings copy];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)getLabelsOfView:(UIView *)view
|
||||
{
|
||||
NSMutableArray<NSString *> *labels = [[NSMutableArray alloc] init];
|
||||
|
||||
NSString *placeholder = [self normalizeField:[FBSDKViewHierarchy getHint:view]];
|
||||
if (placeholder) {
|
||||
[labels addObject:placeholder];
|
||||
}
|
||||
|
||||
NSArray<id> *siblingViews = [self getSiblingViewsOfView:view];
|
||||
for (id sibling in siblingViews) {
|
||||
if ([sibling isKindOfClass:[UILabel class]]) {
|
||||
NSString *text = [self normalizeField:[FBSDKViewHierarchy getText:sibling]];
|
||||
if (text) {
|
||||
[labels addObject:text];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [labels copy];
|
||||
}
|
||||
|
||||
+ (BOOL)checkSecureTextEntry:(UIView *)view
|
||||
{
|
||||
if ([view isKindOfClass:[UITextField class]]) {
|
||||
return ((UITextField *)view).secureTextEntry;
|
||||
}
|
||||
if ([view isKindOfClass:[UITextView class]]) {
|
||||
return ((UITextView *)view).secureTextEntry;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (UIKeyboardType)getKeyboardType:(UIView *)view
|
||||
{
|
||||
if ([view isKindOfClass:[UITextField class]]) {
|
||||
return ((UITextField *)view).keyboardType;
|
||||
}
|
||||
if ([view isKindOfClass:[UITextView class]]) {
|
||||
return ((UITextView *)view).keyboardType;
|
||||
}
|
||||
|
||||
return UIKeyboardTypeDefault;
|
||||
}
|
||||
|
||||
+ (void)getMetadataWithText:(NSString *)text
|
||||
placeholder:(NSString *)placeholder
|
||||
labels:(NSArray<NSString *> *)labels
|
||||
secureTextEntry:(BOOL)secureTextEntry
|
||||
inputType:(UIKeyboardType)inputType
|
||||
{
|
||||
if (secureTextEntry ||
|
||||
[placeholder containsString:@"password"] ||
|
||||
text.length == 0 ||
|
||||
text.length > FBSDKMetadataIndexerMaxTextLength ||
|
||||
placeholder.length >= FBSDKMetadataIndexerMaxIndicatorLength) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (NSString *key in _rules) {
|
||||
NSDictionary<NSString *, NSString *> *rule = _rules[key];
|
||||
BOOL isRuleKMatched = [self checkMetadataHint:placeholder matchRuleK:rule[FIELD_K]]
|
||||
|| [self checkMetadataLabels:labels matchRuleK:rule[FIELD_K]];
|
||||
BOOL isRuleVMatched = [self checkMetadataText:text matchRuleV:rule[FIELD_V]];
|
||||
if (isRuleKMatched && isRuleVMatched) {
|
||||
[FBSDKMetadataIndexer checkAndAppendData:text forKey:key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
+ (void)checkAndAppendData:(NSString *)data
|
||||
forKey:(NSString *)key
|
||||
{
|
||||
NSString *hashData = [FBSDKUtility SHA256Hash:data];
|
||||
dispatch_async(serialQueue, ^{
|
||||
if (hashData.length == 0 || [_store[key] containsObject:hashData]) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (_store[key].count >= FBSDKMetadataIndexerMaxValue) {
|
||||
[_store[key] removeObjectAtIndex:0];
|
||||
}
|
||||
[_store[key] addObject:hashData];
|
||||
[FBSDKUserDataStore setHashData:[_store[key] componentsJoinedByString:@","]
|
||||
forType:key];
|
||||
});
|
||||
}
|
||||
|
||||
+ (BOOL)checkMetadataLabels:(NSArray<NSString *> *)labels
|
||||
matchRuleK:(NSString *)ruleK
|
||||
{
|
||||
for (NSString *label in labels) {
|
||||
if ([self checkMetadataHint:label matchRuleK:ruleK]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)checkMetadataHint:(NSString *)hint
|
||||
matchRuleK:(NSString *)ruleK
|
||||
{
|
||||
if (hint.length > 0 && ruleK) {
|
||||
NSArray<NSString *> *items = [ruleK componentsSeparatedByString:@","];
|
||||
for (NSString *item in items) {
|
||||
if ([hint containsString:item]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)checkMetadataText:(NSString *)text
|
||||
matchRuleV:(NSString *)ruleV
|
||||
{
|
||||
if (text.length > 0 && ruleV) {
|
||||
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:ruleV
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:nil];
|
||||
NSUInteger matches = [regex numberOfMatchesInString:text options:0 range:NSMakeRange(0, text.length)];
|
||||
|
||||
NSString *prunedText = [[text componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"+- ()."]] componentsJoinedByString:@""];
|
||||
NSUInteger prunedMatches = [regex numberOfMatchesInString:prunedText options:0 range:NSMakeRange(0, prunedText.length)];
|
||||
|
||||
return matches > 0 || prunedMatches > 0;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString *)normalizeField:(NSString *)field
|
||||
{
|
||||
if (!field) {
|
||||
return nil;
|
||||
}
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[_-]|\\s"
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:nil];
|
||||
return [regex stringByReplacingMatchesInString:field
|
||||
options:0
|
||||
range:NSMakeRange(0, field.length)
|
||||
withTemplate:@""].lowercaseString;
|
||||
}
|
||||
|
||||
+ (NSString *)normalizedValue:(NSString *)value
|
||||
{
|
||||
if (!value) {
|
||||
return nil;
|
||||
}
|
||||
return [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].lowercaseString;
|
||||
}
|
||||
|
||||
@end
|
||||
+9
-2
@@ -18,10 +18,17 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef void(^FBSDKCodelessSettingLoadBlock)(BOOL isCodelessSetupEnabled, NSError *error);
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void(^FBSDKCodelessSettingLoadBlock)(BOOL isCodelessSetupEnabled, NSError *_Nullable error);
|
||||
|
||||
NS_SWIFT_NAME(CodelessIndexer)
|
||||
@interface FBSDKCodelessIndexer : NSObject
|
||||
|
||||
+ (NSString *)extInfo;
|
||||
@property (class, nonatomic, copy, readonly) NSString *extInfo;
|
||||
|
||||
+ (void)enable;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+17
-13
@@ -24,16 +24,16 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequest.h>
|
||||
#import <FBSDKCoreKit/FBSDKSettings.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
@implementation FBSDKCodelessIndexer
|
||||
|
||||
static BOOL _isCodelessIndexing;
|
||||
static BOOL _isCheckingSession;
|
||||
static BOOL _isCodelessIndexingEnabled;
|
||||
static BOOL _isGestureSet;
|
||||
|
||||
static NSMutableDictionary<NSString *, id> *_codelessSetting;
|
||||
static const NSTimeInterval kTimeout = 4.0;
|
||||
@@ -42,8 +42,11 @@ static NSString *_deviceSessionID;
|
||||
static NSTimer *_appIndexingTimer;
|
||||
static NSString *_lastTreeHash;
|
||||
|
||||
+ (void)load
|
||||
+ (void)enable
|
||||
{
|
||||
if (_isGestureSet) {
|
||||
return;
|
||||
}
|
||||
#if TARGET_OS_SIMULATOR
|
||||
[self setupGesture];
|
||||
#else
|
||||
@@ -138,6 +141,7 @@ static NSString *_lastTreeHash;
|
||||
|
||||
+ (void)setupGesture
|
||||
{
|
||||
_isGestureSet = YES;
|
||||
[UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;
|
||||
Class class = [UIApplication class];
|
||||
|
||||
@@ -160,8 +164,8 @@ static NSString *_lastTreeHash;
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
|
||||
initWithGraphPath:[NSString stringWithFormat:@"%@/%@",
|
||||
[FBSDKSettings appID], CODELESS_INDEXING_SESSION_ENDPOINT]
|
||||
parameters: parameters
|
||||
HTTPMethod:@"POST"];
|
||||
parameters:parameters
|
||||
HTTPMethod:FBSDKHTTPMethodPOST];
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
_isCheckingSession = NO;
|
||||
if ([result isKindOfClass:[NSDictionary class]]) {
|
||||
@@ -213,13 +217,13 @@ static NSString *_lastTreeHash;
|
||||
localeString = [NSString stringWithFormat:@"%@_%@", languageCode, countryCode];
|
||||
}
|
||||
|
||||
NSString *extinfo = [FBSDKInternalUtility JSONStringForObject:@[machine,
|
||||
advertiserID,
|
||||
debugStatus,
|
||||
isSimulator,
|
||||
localeString]
|
||||
error:NULL
|
||||
invalidObjectHandler:NULL];
|
||||
NSString *extinfo = [FBSDKBasicUtility JSONStringForObject:@[machine,
|
||||
advertiserID,
|
||||
debugStatus,
|
||||
isSimulator,
|
||||
localeString]
|
||||
error:NULL
|
||||
invalidObjectHandler:NULL];
|
||||
|
||||
return extinfo ?: @"";
|
||||
}
|
||||
@@ -289,7 +293,7 @@ static NSString *_lastTreeHash;
|
||||
CODELESS_INDEXING_PLATFORM_KEY: @"iOS",
|
||||
CODELESS_INDEXING_SESSION_ID_KEY: [self currentSessionDeviceID]
|
||||
}
|
||||
HTTPMethod:@"POST"];
|
||||
HTTPMethod:FBSDKHTTPMethodPOST];
|
||||
_isCodelessIndexing = YES;
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
_isCodelessIndexing = NO;
|
||||
File renamed without changes.
+1
@@ -18,6 +18,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_SWIFT_NAME(CodelessParameterComponent)
|
||||
@interface FBSDKCodelessParameterComponent : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *name;
|
||||
File renamed without changes.
+1
@@ -27,6 +27,7 @@ typedef NS_OPTIONS(int, FBSDKCodelessMatchBitmaskField)
|
||||
FBSDKCodelessMatchBitmaskFieldHint = 1 << 4
|
||||
};
|
||||
|
||||
NS_SWIFT_NAME(CodelessPathComponent)
|
||||
@interface FBSDKCodelessPathComponent : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *className;
|
||||
File renamed without changes.
+1
@@ -20,6 +20,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_SWIFT_NAME(EventBinding)
|
||||
@interface FBSDKEventBinding : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *eventName;
|
||||
+5
-2
@@ -19,6 +19,7 @@
|
||||
#import "FBSDKEventBinding.h"
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKAppEvents.h>
|
||||
#import <FBSDKCoreKit/FBSDKUtility.h>
|
||||
|
||||
#import "FBSDKAppEventsUtility.h"
|
||||
#import "FBSDKCodelessMacros.h"
|
||||
@@ -175,7 +176,8 @@ pathComponent:(FBSDKCodelessPathComponent *)component
|
||||
if ((pathComponent.matchBitmask & FBSDKCodelessMatchBitmaskFieldText) > 0) {
|
||||
NSString *text = viewPathComponent.text;
|
||||
BOOL match = ((text.length == 0 && pathComponent.text.length == 0)
|
||||
|| [text isEqualToString:pathComponent.text]);
|
||||
|| [text isEqualToString:pathComponent.text]
|
||||
|| [[FBSDKUtility SHA256Hash:text] isEqualToString:pathComponent.text]);
|
||||
if (!match) {
|
||||
return NO;
|
||||
}
|
||||
@@ -189,7 +191,8 @@ pathComponent:(FBSDKCodelessPathComponent *)component
|
||||
if ((pathComponent.matchBitmask & FBSDKCodelessMatchBitmaskFieldHint) > 0) {
|
||||
NSString *hint = viewPathComponent.hint;
|
||||
BOOL match = ((hint.length == 0 && pathComponent.hint.length == 0)
|
||||
|| [hint isEqualToString:pathComponent.hint]);
|
||||
|| [hint isEqualToString:pathComponent.hint]
|
||||
|| [[FBSDKUtility SHA256Hash:hint] isEqualToString:pathComponent.hint]);
|
||||
if (!match) {
|
||||
return NO;
|
||||
}
|
||||
+1
-1
@@ -18,10 +18,10 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_SWIFT_NAME(EventBindingManager)
|
||||
@interface FBSDKEventBindingManager : NSObject
|
||||
|
||||
- (FBSDKEventBindingManager*)initWithJSON:(NSDictionary*)dict;
|
||||
- (void)start;
|
||||
- (void)updateBindings:(NSArray *)bindings;
|
||||
+ (NSArray *)parseArray:(NSArray *)array;
|
||||
|
||||
+14
-1
@@ -38,7 +38,11 @@
|
||||
#define ReactNativeClassRCTTouchHandler "RCTTouchHandler"
|
||||
|
||||
static void fb_dispatch_on_main_thread(dispatch_block_t block) {
|
||||
dispatch_async(dispatch_get_main_queue(), block);
|
||||
if ([NSThread isMainThread]) {
|
||||
block();
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), block);
|
||||
}
|
||||
}
|
||||
|
||||
static void fb_dispatch_on_default_thread(dispatch_block_t block) {
|
||||
@@ -122,6 +126,11 @@ static void fb_dispatch_on_default_thread(dispatch_block_t block) {
|
||||
if (isStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 == eventBindings.count) {
|
||||
return;
|
||||
}
|
||||
|
||||
isStarted = YES;
|
||||
|
||||
void (^blockToWindow)(id view) = ^(id view) {
|
||||
@@ -382,6 +391,10 @@ static void fb_dispatch_on_default_thread(dispatch_block_t block) {
|
||||
- (void)updateBindings:(NSArray *)bindings {
|
||||
eventBindings = bindings;
|
||||
[reactBindings removeAllObjects];
|
||||
if (!isStarted) {
|
||||
[self start];
|
||||
}
|
||||
|
||||
fb_dispatch_on_main_thread(^{
|
||||
[self rematchBindings];
|
||||
});
|
||||
+1
@@ -19,6 +19,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_SWIFT_NAME(ViewHierarchy)
|
||||
@interface FBSDKViewHierarchy : NSObject
|
||||
|
||||
+ (NSObject *)getParent:(NSObject *)obj;
|
||||
+26
-14
@@ -22,32 +22,33 @@
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
#import "FBSDKCodelessMacros.h"
|
||||
#import "FBSDKCodelessPathComponent.h"
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
#define MAX_VIEW_HIERARCHY_LEVEL 35
|
||||
|
||||
typedef NS_ENUM(NSUInteger, FBCodelessClassBitmask) {
|
||||
/*! Indicates that the class is subclass of UIControl */
|
||||
/** Indicates that the class is subclass of UIControl */
|
||||
FBCodelessClassBitmaskUIControl = 1 << 3,
|
||||
/*! Indicates that the class is subclass of UIControl */
|
||||
/** Indicates that the class is subclass of UIControl */
|
||||
FBCodelessClassBitmaskUIButton = 1 << 4,
|
||||
/*! Indicates that the class is ReactNative Button */
|
||||
/** Indicates that the class is ReactNative Button */
|
||||
FBCodelessClassBitmaskReactNativeButton = 1 << 6,
|
||||
/*! Indicates that the class is UITableViewCell */
|
||||
/** Indicates that the class is UITableViewCell */
|
||||
FBCodelessClassBitmaskUITableViewCell = 1 << 7,
|
||||
/*! Indicates that the class is UICollectionViewCell */
|
||||
/** Indicates that the class is UICollectionViewCell */
|
||||
FBCodelessClassBitmaskUICollectionViewCell = 1 << 8,
|
||||
/*! Indicates that the class is UILabel */
|
||||
/** Indicates that the class is UILabel */
|
||||
FBCodelessClassBitmaskLabel = 1 << 10,
|
||||
/*! Indicates that the class is UITextView or UITextField*/
|
||||
/** Indicates that the class is UITextView or UITextField*/
|
||||
FBCodelessClassBitmaskInput = 1 << 11,
|
||||
/*! Indicates that the class is UIPicker*/
|
||||
/** Indicates that the class is UIPicker*/
|
||||
FBCodelessClassBitmaskPicker = 1 << 12,
|
||||
/*! Indicates that the class is UISwitch*/
|
||||
/** Indicates that the class is UISwitch*/
|
||||
FBCodelessClassBitmaskSwitch = 1 << 13,
|
||||
/*! Indicates that the class is UIViewController*/
|
||||
/** Indicates that the class is UIViewController*/
|
||||
FBCodelessClassBitmaskUIViewController = 1 << 17,
|
||||
};
|
||||
|
||||
@@ -268,6 +269,11 @@ typedef NS_ENUM(NSUInteger, FBCodelessClassBitmask) {
|
||||
}
|
||||
|
||||
+ (NSMutableDictionary<NSString *, id> *)getDetailAttributesOf:(NSObject *)obj
|
||||
{
|
||||
return [self getDetailAttributesOf:obj WithHash:YES];
|
||||
}
|
||||
|
||||
+ (NSMutableDictionary<NSString *, id> *)getDetailAttributesOf:(NSObject *)obj WithHash:(BOOL)hash
|
||||
{
|
||||
if (!obj) {
|
||||
return nil;
|
||||
@@ -308,6 +314,12 @@ typedef NS_ENUM(NSUInteger, FBCodelessClassBitmask) {
|
||||
result[CODELESS_VIEW_TREE_TEXT_STYLE_KEY] = textStyle;
|
||||
}
|
||||
|
||||
if (hash) {
|
||||
// hash text and hint
|
||||
result[CODELESS_VIEW_TREE_TEXT_KEY] = [FBSDKUtility SHA256Hash:result[CODELESS_VIEW_TREE_TEXT_KEY]];
|
||||
result[CODELESS_VIEW_TREE_HINT_KEY] = [FBSDKUtility SHA256Hash:result[CODELESS_VIEW_TREE_HINT_KEY]];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -357,9 +369,9 @@ typedef NS_ENUM(NSUInteger, FBCodelessClassBitmask) {
|
||||
}
|
||||
|
||||
if (titles.count > 0) {
|
||||
text = [FBSDKInternalUtility JSONStringForObject:titles
|
||||
error:NULL
|
||||
invalidObjectHandler:NULL];
|
||||
text = [FBSDKBasicUtility JSONStringForObject:titles
|
||||
error:NULL
|
||||
invalidObjectHandler:NULL];
|
||||
}
|
||||
} else if ([obj isKindOfClass:[UIDatePicker class]]) {
|
||||
UIDatePicker *picker = (UIDatePicker *)obj;
|
||||
+34
-8
@@ -24,8 +24,6 @@
|
||||
|
||||
// Internally known event names
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNamePurchased;
|
||||
|
||||
/** Use to log that the share dialog was launched */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameShareSheetLaunch;
|
||||
|
||||
@@ -41,10 +39,10 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventNamePermissionsUIDismiss;
|
||||
/** Use to log that the login view was used */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameLoginViewUsage;
|
||||
|
||||
/*! Use to log that the share tray launched. */
|
||||
/** Use to log that the share tray launched. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameShareTrayDidLaunch;
|
||||
|
||||
/*! Use to log that the person selected a sharing target. */
|
||||
/** Use to log that the person selected a sharing target. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameShareTrayDidSelectActivity;
|
||||
|
||||
// Internally known event parameters
|
||||
@@ -105,7 +103,7 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKLiveStreamingMic;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKLiveStreamingCamera;
|
||||
|
||||
/** Use to log the results of a share dialog */
|
||||
FOUNDATION_EXPORT NSString *const FBSDLAppEventNameFBSDKEventShareDialogResult;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKEventShareDialogResult;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKEventMessengerShareDialogResult;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult;
|
||||
|
||||
@@ -118,11 +116,11 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterDialogShareContentType;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterDialogShareContentUUID;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterDialogShareContentPageID;
|
||||
|
||||
/*! Use to log parameters for share tray use */
|
||||
/** Use to log parameters for share tray use */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterShareTrayActivityName;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterShareTrayResult;
|
||||
|
||||
/*! Use to log parameters for live streaming*/
|
||||
/** Use to log parameters for live streaming*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterLiveStreamingPrevStatus;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterLiveStreamingStatus;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppEventParameterLiveStreamingError;
|
||||
@@ -199,12 +197,40 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventsWKWebViewMessagesPixelIDKey;
|
||||
|
||||
@interface FBSDKAppEvents (Internal)
|
||||
|
||||
@property (class, nonatomic, strong, readonly) FBSDKAppEvents *singleton;
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged;
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged;
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged;
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged
|
||||
accessToken:(FBSDKAccessToken *)accessToken;
|
||||
|
||||
+ (void)logInternalEvent:(FBSDKAppEventName)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged;
|
||||
|
||||
+ (void)logInternalEvent:(NSString *)eventName
|
||||
valueToSum:(NSNumber *)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
isImplicitlyLogged:(BOOL)isImplicitlyLogged
|
||||
accessToken:(FBSDKAccessToken *)accessToken;
|
||||
|
||||
+ (void)logImplicitEvent:(NSString *)eventName
|
||||
valueToSum:(NSNumber *)valueToSum
|
||||
parameters:(NSDictionary *)parameters
|
||||
accessToken:(FBSDKAccessToken *)accessToken;
|
||||
|
||||
+ (FBSDKAppEvents *)singleton;
|
||||
- (void)flushForReason:(FBSDKAppEventsFlushReason)flushReason;
|
||||
- (void)registerNotifications;
|
||||
|
||||
+1
@@ -18,6 +18,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_SWIFT_NAME(AppEventsDeviceInfo)
|
||||
@interface FBSDKAppEventsDeviceInfo : NSObject
|
||||
|
||||
+ (void)extendDictionaryWithDeviceInfo:(NSMutableDictionary *)dictionary;
|
||||
+2
-1
@@ -25,6 +25,7 @@
|
||||
#import <CoreTelephony/CTCarrier.h>
|
||||
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
|
||||
#endif
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -228,7 +229,7 @@ static const u_int FB_GIGABYTE = 1024 * 1024 * 1024; // bytes
|
||||
_timeZoneName ?: @""
|
||||
];
|
||||
|
||||
return [FBSDKInternalUtility JSONStringForObject:arr error:NULL invalidObjectHandler:NULL];
|
||||
return [FBSDKBasicUtility JSONStringForObject:arr error:NULL invalidObjectHandler:NULL];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
+2
-1
@@ -19,13 +19,14 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// this type is not thread safe.
|
||||
NS_SWIFT_NAME(AppEventsState)
|
||||
@interface FBSDKAppEventsState : NSObject<NSCopying, NSSecureCoding>
|
||||
|
||||
@property (nonatomic, readonly, copy) NSArray *events;
|
||||
@property (nonatomic, readonly, assign) NSUInteger numSkipped;
|
||||
@property (nonatomic, readonly, copy) NSString *tokenString;
|
||||
@property (nonatomic, readonly, copy) NSString *appID;
|
||||
@property (nonatomic, readonly) BOOL areAllEventsImplicit;
|
||||
@property (nonatomic, readonly, getter=areAllEventsImplicit) BOOL allEventsImplicit;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
+5
-2
@@ -18,7 +18,8 @@
|
||||
|
||||
#import "FBSDKAppEventsState.h"
|
||||
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKBasicUtility.h"
|
||||
#import "FBSDKRestrictiveDataFilterManager.h"
|
||||
|
||||
#define FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY @"isImplicit"
|
||||
|
||||
@@ -163,6 +164,8 @@
|
||||
|
||||
- (NSString *)JSONStringForEvents:(BOOL)includeImplicitEvents
|
||||
{
|
||||
[FBSDKRestrictiveDataFilterManager processEvents:_mutableEvents];
|
||||
|
||||
NSMutableArray *events = [[NSMutableArray alloc] initWithCapacity:_mutableEvents.count];
|
||||
for (NSDictionary *eventAndImplicitFlag in _mutableEvents) {
|
||||
if (!includeImplicitEvents && [eventAndImplicitFlag[FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY] boolValue]) {
|
||||
@@ -175,7 +178,7 @@
|
||||
[events addObject:event];
|
||||
}
|
||||
|
||||
return [FBSDKInternalUtility JSONStringForObject:events error:NULL invalidObjectHandler:NULL];
|
||||
return [FBSDKBasicUtility JSONStringForObject:events error:NULL invalidObjectHandler:NULL];
|
||||
}
|
||||
|
||||
@end
|
||||
+1
@@ -20,6 +20,7 @@
|
||||
|
||||
@class FBSDKAppEventsState;
|
||||
|
||||
NS_SWIFT_NAME(AppEventsStateManager)
|
||||
@interface FBSDKAppEventsStateManager : NSObject
|
||||
|
||||
+ (void)clearPersistedAppEventsStates;
|
||||
+2
-1
@@ -22,6 +22,7 @@
|
||||
|
||||
#import "FBSDKAppEventsState.h"
|
||||
#import "FBSDKAppEventsUtility.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKLogger.h"
|
||||
#import "FBSDKSettings.h"
|
||||
|
||||
@@ -73,6 +74,6 @@ static BOOL g_canSkipDiskCheck = NO;
|
||||
|
||||
+ (NSString *)filePath
|
||||
{
|
||||
return [FBSDKAppEventsUtility persistenceFilePath:@"com-facebook-sdk-AppEventsPersistedEvents.json"];
|
||||
return [FBSDKBasicUtility persistenceFilePath:@"com-facebook-sdk-AppEventsPersistedEvents.json"];
|
||||
}
|
||||
@end
|
||||
+10
-8
@@ -25,7 +25,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAdvertisingTrackingStatus)
|
||||
FBSDKAdvertisingTrackingAllowed,
|
||||
FBSDKAdvertisingTrackingDisallowed,
|
||||
FBSDKAdvertisingTrackingUnspecified
|
||||
};
|
||||
} NS_SWIFT_NAME(AppEventsUtility.AdvertisingTrackingStatus);
|
||||
|
||||
typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushReason)
|
||||
{
|
||||
@@ -35,30 +35,32 @@ typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushReason)
|
||||
FBSDKAppEventsFlushReasonPersistedEvents,
|
||||
FBSDKAppEventsFlushReasonEventThreshold,
|
||||
FBSDKAppEventsFlushReasonEagerlyFlushingEvent
|
||||
};
|
||||
} NS_SWIFT_NAME(AppEventsUtility.FlushReason);
|
||||
|
||||
NS_SWIFT_NAME(AppEventsUtility)
|
||||
@interface FBSDKAppEventsUtility : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
@property (class, nonatomic, copy, readonly) NSString *advertiserID;
|
||||
@property (class, nonatomic, assign, readonly) FBSDKAdvertisingTrackingStatus advertisingTrackingStatus;
|
||||
@property (class, nonatomic, strong, readonly) NSString *attributionID;
|
||||
@property (class, nonatomic, assign, readonly) long unixTimeNow;
|
||||
@property (class, nonatomic, assign, readonly) BOOL isDebugBuild;
|
||||
|
||||
+ (NSMutableDictionary *)activityParametersDictionaryForEvent:(NSString *)eventCategory
|
||||
implicitEventsOnly:(BOOL)implicitEventsOnly
|
||||
shouldAccessAdvertisingID:(BOOL)shouldAccessAdvertisingID;
|
||||
+ (NSString *)advertiserID;
|
||||
+ (FBSDKAdvertisingTrackingStatus)advertisingTrackingStatus;
|
||||
+ (NSString *)attributionID;
|
||||
|
||||
+ (void)ensureOnMainThread:(NSString *)methodName className:(NSString *)className;
|
||||
+ (NSString *)flushReasonToString:(FBSDKAppEventsFlushReason)flushReason;
|
||||
+ (void)logAndNotify:(NSString *)msg allowLogAsDeveloperError:(BOOL)allowLogAsDeveloperError;
|
||||
+ (void)logAndNotify:(NSString *)msg;
|
||||
+ (NSString *)persistenceFilePath:(NSString *)filename;
|
||||
+ (NSString *)tokenStringToUseFor:(FBSDKAccessToken *)token;
|
||||
+ (long)unixTimeNow;
|
||||
+ (BOOL)validateIdentifier:(NSString *)identifier;
|
||||
+ (id)getVariable:(NSString *)variableName fromInstance:(NSObject *)instance;
|
||||
+ (NSNumber *)getNumberValue:(NSString *)text;
|
||||
+ (BOOL)isDebugBuild;
|
||||
+ (BOOL)isSensitiveUserData:(NSString *)text;
|
||||
|
||||
@end
|
||||
+14
-58
@@ -47,21 +47,27 @@
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
|
||||
NSString *attributionID = [[self class] attributionID]; // Only present on iOS 6 and below.
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:attributionID forKey:@"attribution"];
|
||||
[FBSDKBasicUtility dictionary:parameters setObject:attributionID forKey:@"attribution"];
|
||||
#endif
|
||||
|
||||
if (!implicitEventsOnly && shouldAccessAdvertisingID) {
|
||||
NSString *advertiserID = [[self class] advertiserID];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:advertiserID forKey:@"advertiser_id"];
|
||||
[FBSDKBasicUtility dictionary:parameters setObject:advertiserID forKey:@"advertiser_id"];
|
||||
}
|
||||
|
||||
parameters[FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY] = [self anonymousID];
|
||||
parameters[FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY] = [FBSDKBasicUtility anonymousID];
|
||||
|
||||
FBSDKAdvertisingTrackingStatus advertisingTrackingStatus = [[self class] advertisingTrackingStatus];
|
||||
if (advertisingTrackingStatus != FBSDKAdvertisingTrackingUnspecified) {
|
||||
BOOL allowed = (advertisingTrackingStatus == FBSDKAdvertisingTrackingAllowed);
|
||||
parameters[@"advertiser_tracking_enabled"] = @(allowed).stringValue;
|
||||
}
|
||||
if (advertisingTrackingStatus == FBSDKAdvertisingTrackingAllowed) {
|
||||
NSString *userData = [FBSDKAppEvents getUserData];
|
||||
if (userData){
|
||||
parameters[@"ud"] = userData;
|
||||
}
|
||||
}
|
||||
|
||||
parameters[@"application_tracking_enabled"] = @(!FBSDKSettings.limitEventAndDataUsage).stringValue;
|
||||
|
||||
@@ -69,10 +75,6 @@
|
||||
if (userID) {
|
||||
parameters[@"app_user_id"] = userID;
|
||||
}
|
||||
NSString *userData = [FBSDKAppEvents getUserData];
|
||||
if (userData){
|
||||
parameters[@"ud"] = userData;
|
||||
}
|
||||
|
||||
[FBSDKAppEventsDeviceInfo extendDictionaryWithDeviceInfo:parameters];
|
||||
|
||||
@@ -91,7 +93,7 @@
|
||||
});
|
||||
|
||||
if (urlSchemes.count > 0) {
|
||||
parameters[@"url_schemes"] = [FBSDKInternalUtility JSONStringForObject:urlSchemes error:NULL invalidObjectHandler:NULL];
|
||||
parameters[@"url_schemes"] = [FBSDKBasicUtility JSONStringForObject:urlSchemes error:NULL invalidObjectHandler:NULL];
|
||||
}
|
||||
|
||||
return parameters;
|
||||
@@ -99,7 +101,7 @@
|
||||
|
||||
+ (NSString *)advertiserID
|
||||
{
|
||||
if (![[FBSDKSettings advertiserIDCollectionEnabled] boolValue]) {
|
||||
if (!FBSDKSettings.isAdvertiserIDCollectionEnabled) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -133,22 +135,6 @@
|
||||
return status;
|
||||
}
|
||||
|
||||
+ (NSString *)anonymousID
|
||||
{
|
||||
// Grab previously written anonymous ID and, if none have been generated, create and
|
||||
// persist a new one which will remain associated with this app.
|
||||
NSString *result = [[self class] retrievePersistedAnonymousID];
|
||||
if (!result) {
|
||||
// Generate a new anonymous ID. Create as a UUID, but then prepend the fairly
|
||||
// arbitrary 'XZ' to the front so it's easily distinguishable from IDFA's which
|
||||
// will only contain hex.
|
||||
result = [NSString stringWithFormat:@"XZ%@", [NSUUID UUID].UUIDString];
|
||||
|
||||
[self persistAnonymousID:result];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSString *)attributionID
|
||||
{
|
||||
#if TARGET_OS_TV
|
||||
@@ -158,7 +144,8 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
// for tests only.
|
||||
#pragma mark - Internal, for testing
|
||||
|
||||
+ (void)clearLibraryFiles
|
||||
{
|
||||
[[NSFileManager defaultManager] removeItemAtPath:[[self class] persistenceFilePath:FBSDK_APPEVENTSUTILITY_ANONYMOUSIDFILENAME]
|
||||
@@ -218,7 +205,7 @@
|
||||
}
|
||||
|
||||
[FBSDKLogger singleShotLogEntry:behaviorToLog logEntry:msg];
|
||||
NSError *error = [NSError fbErrorWithCode:FBSDKErrorAppEventsFlush message:msg];
|
||||
NSError *error = [FBSDKError errorWithCode:FBSDKErrorAppEventsFlush message:msg];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAppEventsLoggingResultNotification object:error];
|
||||
}
|
||||
|
||||
@@ -285,37 +272,6 @@ restOfStringCharacterSet:(NSCharacterSet *)restOfStringCharacterSet
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (void)persistAnonymousID:(NSString *)anonymousID
|
||||
{
|
||||
[[self class] ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass(self)];
|
||||
NSDictionary *data = @{ FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY : anonymousID };
|
||||
NSString *content = [FBSDKInternalUtility JSONStringForObject:data error:NULL invalidObjectHandler:NULL];
|
||||
|
||||
[content writeToFile:[[self class] persistenceFilePath:FBSDK_APPEVENTSUTILITY_ANONYMOUSIDFILENAME]
|
||||
atomically:YES
|
||||
encoding:NSASCIIStringEncoding
|
||||
error:nil];
|
||||
}
|
||||
|
||||
+ (NSString *)persistenceFilePath:(NSString *)filename
|
||||
{
|
||||
NSSearchPathDirectory directory = NSLibraryDirectory;
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES);
|
||||
NSString *docDirectory = paths[0];
|
||||
return [docDirectory stringByAppendingPathComponent:filename];
|
||||
}
|
||||
|
||||
+ (NSString *)retrievePersistedAnonymousID
|
||||
{
|
||||
[[self class] ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass(self)];
|
||||
NSString *file = [[self class] persistenceFilePath:FBSDK_APPEVENTSUTILITY_ANONYMOUSIDFILENAME];
|
||||
NSString *content = [[NSString alloc] initWithContentsOfFile:file
|
||||
encoding:NSASCIIStringEncoding
|
||||
error:nil];
|
||||
NSDictionary *results = [FBSDKInternalUtility objectForJSONString:content error:NULL];
|
||||
return results[FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY];
|
||||
}
|
||||
|
||||
// Given a candidate token (which may be nil), find the real token to string to use.
|
||||
// Precedence: 1) provided token, 2) current token, 3) app | client token, 4) fully anonymous session.
|
||||
+ (NSString *)tokenStringToUseFor:(FBSDKAccessToken *)token
|
||||
+1
@@ -20,6 +20,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
NS_SWIFT_NAME(HybridAppEventsScriptMessageHandler)
|
||||
@interface FBSDKHybridAppEventsScriptMessageHandler : NSObject <WKScriptMessageHandler>
|
||||
|
||||
@end
|
||||
+4
-2
@@ -34,7 +34,7 @@ NSString *const FBSDKAppEventsWKWebViewMessagesPixelReferralParamKey = @"_fb_pix
|
||||
NSString *event = message.body[FBSDKAppEventsWKWebViewMessagesEventKey];
|
||||
if (event.length > 0) {
|
||||
NSString *stringedParams = message.body[FBSDKAppEventsWKWebViewMessagesParamsKey];
|
||||
NSMutableDictionary <NSObject *, NSObject *> *params = nil;
|
||||
NSMutableDictionary <NSString *, id> *params = nil;
|
||||
NSError *jsonParseError = nil;
|
||||
if ([stringedParams isKindOfClass:[NSString class]]) {
|
||||
params = [NSJSONSerialization JSONObjectWithData:[stringedParams dataUsingEncoding:NSUTF8StringEncoding]
|
||||
@@ -54,7 +54,9 @@ NSString *const FBSDKAppEventsWKWebViewMessagesPixelReferralParamKey = @"_fb_pix
|
||||
else {
|
||||
params[FBSDKAppEventsWKWebViewMessagesPixelReferralParamKey] = pixelID;
|
||||
}
|
||||
[FBSDKAppEvents logEvent:event parameters:params];
|
||||
[FBSDKAppEvents logInternalEvent:event
|
||||
parameters:params
|
||||
isImplicitlyLogged:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -19,6 +19,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// Class to encapsulate implicit logging of purchase events
|
||||
NS_SWIFT_NAME(PaymentObserver)
|
||||
@interface FBSDKPaymentObserver : NSObject
|
||||
+ (void)startObservingTransactions;
|
||||
+ (void)stopObservingTransactions;
|
||||
+248
-59
@@ -20,24 +20,34 @@
|
||||
|
||||
#import <StoreKit/StoreKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
#import "FBSDKAppEvents+Internal.h"
|
||||
#import "FBSDKDynamicFrameworkLoader.h"
|
||||
#import "FBSDKLogger.h"
|
||||
#import "FBSDKSettings.h"
|
||||
|
||||
static NSString *const FBSDKPaymentObserverOriginalTransactionKey = @"com.facebook.appevents.PaymentObserver.originalTransaction";
|
||||
static NSString *const FBSDKPaymentObserverDelimiter = @",";
|
||||
|
||||
static NSString *const FBSDKAppEventParameterImplicitlyLoggedPurchase = @"_implicitlyLogged";
|
||||
static NSString *const FBSDKAppEventNamePurchaseFailed = @"fb_mobile_purchase_failed";
|
||||
static NSString *const FBSDKAppEventNamePurchaseRestored = @"fb_mobile_purchase_restored";
|
||||
static NSString *const FBSDKAppEventParameterNameInAppPurchaseType = @"fb_iap_product_type";
|
||||
static NSString *const FBSDKAppEventParameterNameProductTitle = @"fb_content_title";
|
||||
static NSString *const FBSDKAppEventParameterNameOriginalTransactionID = @"fb_original_transaction_id";
|
||||
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 FBSDKAppEventParameterNameIsStartTrial = @"fb_iap_is_start_trial";
|
||||
static NSString *const FBSDKAppEventParameterNameHasFreeTrial = @"fb_iap_has_free_trial";
|
||||
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;
|
||||
|
||||
static NSString *const FBSDKGateKeeperAppEventsIfAutoLogSubs = @"app_events_if_auto_log_subs";
|
||||
|
||||
@interface FBSDKPaymentProductRequestor : NSObject<SKProductsRequestDelegate>
|
||||
|
||||
@property (nonatomic, retain) SKPaymentTransaction *transaction;
|
||||
@@ -65,9 +75,7 @@ static NSMutableArray *g_pendingRequestors;
|
||||
[[self singleton] stopObservingTransactions];
|
||||
}
|
||||
|
||||
//
|
||||
// Internal methods
|
||||
//
|
||||
#pragma mark - Internal Methods
|
||||
|
||||
+ (FBSDKPaymentObserver *)singleton
|
||||
{
|
||||
@@ -127,10 +135,6 @@ static NSMutableArray *g_pendingRequestors;
|
||||
|
||||
- (void)handleTransaction:(SKPaymentTransaction *)transaction
|
||||
{
|
||||
// Ignore restored transaction
|
||||
if (transaction.originalTransaction != nil) {
|
||||
return;
|
||||
}
|
||||
FBSDKPaymentProductRequestor *productRequest = [[FBSDKPaymentProductRequestor alloc] initWithTransaction:transaction];
|
||||
[productRequest resolveProducts];
|
||||
}
|
||||
@@ -142,6 +146,11 @@ static NSMutableArray *g_pendingRequestors;
|
||||
@end
|
||||
|
||||
@implementation FBSDKPaymentProductRequestor
|
||||
{
|
||||
NSMutableSet<NSString *> *_originalTransactionSet;
|
||||
NSSet<NSString *> *_eventsWithReceipt;
|
||||
NSDateFormatter *_formatter;
|
||||
}
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
@@ -155,6 +164,16 @@ static NSMutableArray *g_pendingRequestors;
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_transaction = transaction;
|
||||
_formatter = [[NSDateFormatter alloc] init];
|
||||
_formatter.dateFormat = @"yyyy-MM-dd HH:mm:ssZ";
|
||||
NSString *data = [[NSUserDefaults standardUserDefaults] stringForKey:FBSDKPaymentObserverOriginalTransactionKey];
|
||||
_eventsWithReceipt = [NSSet setWithArray:@[FBSDKAppEventNamePurchased, FBSDKAppEventNameSubscribe,
|
||||
FBSDKAppEventNameStartTrial]];
|
||||
if (data) {
|
||||
_originalTransactionSet = [NSMutableSet setWithArray:[data componentsSeparatedByString:FBSDKPaymentObserverDelimiter]];
|
||||
} else {
|
||||
_originalTransactionSet = [[NSMutableSet alloc] init];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -192,86 +211,182 @@ static NSMutableArray *g_pendingRequestors;
|
||||
|
||||
- (void)logTransactionEvent:(SKProduct *)product
|
||||
{
|
||||
NSString *eventName = nil;
|
||||
if ([self isSubscription:product] &&
|
||||
[FBSDKGateKeeperManager boolForKey:FBSDKGateKeeperAppEventsIfAutoLogSubs
|
||||
defaultValue:NO]) {
|
||||
[self logImplicitSubscribeTransaction:self.transaction ofProduct:product];
|
||||
} else {
|
||||
[self logImplicitPurchaseTransaction:self.transaction ofProduct:product];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isSubscription:(SKProduct *)product
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_11_1
|
||||
if (@available(iOS 11.2, *)) {
|
||||
return (product.subscriptionPeriod != nil) && ((unsigned long)product.subscriptionPeriod.numberOfUnits > 0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary<NSString *, id> *)getEventParametersOfProduct:(SKProduct *)product
|
||||
withTransaction:(SKPaymentTransaction *)transaction
|
||||
{
|
||||
NSString *transactionID = nil;
|
||||
NSString *transactionDate = nil;
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ssZ";
|
||||
switch (self.transaction.transactionState) {
|
||||
switch (transaction.transactionState) {
|
||||
case SKPaymentTransactionStatePurchasing:
|
||||
eventName = FBSDKAppEventNameInitiatedCheckout;
|
||||
break;
|
||||
case SKPaymentTransactionStatePurchased:
|
||||
eventName = FBSDKAppEventNamePurchased;
|
||||
transactionID = self.transaction.transactionIdentifier;
|
||||
transactionDate = [formatter stringFromDate:self.transaction.transactionDate];
|
||||
transactionDate = [_formatter stringFromDate:self.transaction.transactionDate];
|
||||
break;
|
||||
case SKPaymentTransactionStateFailed:
|
||||
eventName = FBSDKAppEventNamePurchaseFailed;
|
||||
break;
|
||||
case SKPaymentTransactionStateRestored:
|
||||
eventName = FBSDKAppEventNamePurchaseRestored;
|
||||
transactionDate = [formatter stringFromDate:self.transaction.transactionDate];
|
||||
transactionDate = [_formatter stringFromDate:self.transaction.transactionDate];
|
||||
break;
|
||||
case SKPaymentTransactionStateDeferred:
|
||||
return;
|
||||
default: break;
|
||||
}
|
||||
if (!eventName) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents
|
||||
formatString:@"FBSDKPaymentObserver logTransactionEvent: event name cannot be nil"];
|
||||
return;
|
||||
}
|
||||
|
||||
SKPayment *payment = self.transaction.payment;
|
||||
SKPayment *payment = transaction.payment;
|
||||
NSMutableDictionary *eventParameters = [NSMutableDictionary dictionaryWithDictionary: @{
|
||||
FBSDKAppEventParameterNameContentID: payment.productIdentifier ?: @"",
|
||||
FBSDKAppEventParameterNameNumItems: @(payment.quantity),
|
||||
FBSDKAppEventParameterNameTransactionDate: transactionDate ?: @"",
|
||||
}];
|
||||
double totalAmount = 0;
|
||||
if (product) {
|
||||
totalAmount = payment.quantity * product.price.doubleValue;
|
||||
[eventParameters addEntriesFromDictionary: @{
|
||||
FBSDKAppEventParameterNameCurrency: [product.priceLocale objectForKey:NSLocaleCurrencyCode],
|
||||
FBSDKAppEventParameterNameNumItems: @(payment.quantity),
|
||||
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
|
||||
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";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (transactionID) {
|
||||
eventParameters[FBSDKAppEventParameterNameTransactionID] = transactionID;
|
||||
}
|
||||
}
|
||||
|
||||
[self logImplicitPurchaseEvent:eventName
|
||||
valueToSum:totalAmount
|
||||
parameters:eventParameters];
|
||||
#if !TARGET_OS_TV
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_11_1
|
||||
if (@available(iOS 11.2, *)) {
|
||||
if ([self isSubscription:product]) {
|
||||
// subs inapp
|
||||
eventParameters[FBSDKAppEventParameterNameSubscriptionPeriod] = [self durationOfSubscriptionPeriod:product.subscriptionPeriod];
|
||||
eventParameters[FBSDKAppEventParameterNameInAppPurchaseType] = @"subs";
|
||||
eventParameters[FBSDKAppEventParameterNameIsStartTrial] = [self isStartTrial:transaction ofProduct:product] ? @"1" : @"0";
|
||||
// trial information for subs
|
||||
SKProductDiscount *discount = product.introductoryPrice;
|
||||
if (discount) {
|
||||
if (discount.paymentMode == SKProductDiscountPaymentModeFreeTrial) {
|
||||
eventParameters[FBSDKAppEventParameterNameHasFreeTrial] = @"1";
|
||||
} else {
|
||||
eventParameters[FBSDKAppEventParameterNameHasFreeTrial] = @"0";
|
||||
}
|
||||
eventParameters[FBSDKAppEventParameterNameTrialPeriod] = [self durationOfSubscriptionPeriod:discount.subscriptionPeriod];
|
||||
eventParameters[FBSDKAppEventParameterNameTrialPrice] = discount.price;
|
||||
}
|
||||
} else {
|
||||
eventParameters[FBSDKAppEventParameterNameInAppPurchaseType] = @"inapp";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return eventParameters;
|
||||
}
|
||||
|
||||
- (NSString *)lengthOfSubscriptionPeriod:(id)subcriptionPeriod
|
||||
- (void)appendOriginalTransactionID:(NSString *)transactionID
|
||||
{
|
||||
if (!transactionID) {
|
||||
return;
|
||||
}
|
||||
[_originalTransactionSet addObject:transactionID];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[[_originalTransactionSet allObjects] componentsJoinedByString:FBSDKPaymentObserverDelimiter]
|
||||
forKey:FBSDKPaymentObserverOriginalTransactionKey];
|
||||
}
|
||||
|
||||
- (void)clearOriginalTransactionID:(NSString *)transactionID
|
||||
{
|
||||
if (!transactionID) {
|
||||
return;
|
||||
}
|
||||
[_originalTransactionSet removeObject:transactionID];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[[_originalTransactionSet allObjects] componentsJoinedByString:FBSDKPaymentObserverDelimiter]
|
||||
forKey:FBSDKPaymentObserverOriginalTransactionKey];
|
||||
}
|
||||
|
||||
- (BOOL)isStartTrial:(SKPaymentTransaction *)transaction
|
||||
ofProduct:(SKProduct *)product
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_2
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_11_1
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_11_4
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_12_1
|
||||
// promotional offer starting from iOS 12.2
|
||||
if (@available(iOS 12.2, *)) {
|
||||
SKPaymentDiscount *paymentDiscount = transaction.payment.paymentDiscount;
|
||||
if (paymentDiscount) {
|
||||
NSArray<SKProductDiscount *> *discounts = product.discounts;
|
||||
for (SKProductDiscount *discount in discounts) {
|
||||
if (discount.paymentMode == SKProductDiscountPaymentModeFreeTrial &&
|
||||
[paymentDiscount.identifier isEqualToString:discount.identifier]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
// introductory offer starting from iOS 11.2
|
||||
if (@available(iOS 11.2, *)) {
|
||||
if (product.introductoryPrice &&
|
||||
product.introductoryPrice.paymentMode == SKProductDiscountPaymentModeFreeTrial) {
|
||||
NSString *originalTransactionID = transaction.originalTransaction.transactionIdentifier;
|
||||
// only consider the very first trial transaction as start trial
|
||||
if (!originalTransactionID) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)hasStartTrial:(SKProduct *)product
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_11_1
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_11_4
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_12_1
|
||||
// promotional offer starting from iOS 12.2
|
||||
if (@available(iOS 12.2, *)) {
|
||||
NSArray<SKProductDiscount *> *discounts = product.discounts;
|
||||
for (SKProductDiscount *discount in discounts) {
|
||||
if (discount.paymentMode == SKProductDiscountPaymentModeFreeTrial) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
// introductory offer starting from iOS 11.2
|
||||
if (@available(iOS 11.2, *)) {
|
||||
if (product.introductoryPrice && (product.introductoryPrice.paymentMode == SKProductDiscountPaymentModeFreeTrial)) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)durationOfSubscriptionPeriod:(id)subcriptionPeriod
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_11_1
|
||||
if (@available(iOS 11.2, *)) {
|
||||
if (subcriptionPeriod && [subcriptionPeriod isKindOfClass:[SKProductSubscriptionPeriod class]]) {
|
||||
SKProductSubscriptionPeriod *period = (SKProductSubscriptionPeriod *)subcriptionPeriod;
|
||||
@@ -323,12 +438,85 @@ static NSMutableArray *g_pendingRequestors;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)logImplicitPurchaseEvent:(NSString *)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
parameters:(NSDictionary *)parameters {
|
||||
- (void)logImplicitSubscribeTransaction:(SKPaymentTransaction *)transaction
|
||||
ofProduct:(SKProduct *)product
|
||||
{
|
||||
NSString *eventName = nil;
|
||||
NSString *originalTransactionID = transaction.originalTransaction.transactionIdentifier;
|
||||
switch (transaction.transactionState) {
|
||||
case SKPaymentTransactionStatePurchasing:
|
||||
eventName = @"SubscriptionInitiatedCheckout";
|
||||
break;
|
||||
case SKPaymentTransactionStatePurchased:
|
||||
if ([self isStartTrial:transaction ofProduct:product]) {
|
||||
eventName = FBSDKAppEventNameStartTrial;
|
||||
[self clearOriginalTransactionID:originalTransactionID];
|
||||
} else {
|
||||
if (originalTransactionID && [_originalTransactionSet containsObject:originalTransactionID]) {
|
||||
return;
|
||||
}
|
||||
eventName = FBSDKAppEventNameSubscribe;
|
||||
[self appendOriginalTransactionID:(originalTransactionID ?: transaction.transactionIdentifier)];
|
||||
}
|
||||
break;
|
||||
case SKPaymentTransactionStateFailed:
|
||||
eventName = @"SubscriptionFailed";
|
||||
break;
|
||||
case SKPaymentTransactionStateRestored:
|
||||
eventName = @"SubscriptionRestore";
|
||||
break;
|
||||
case SKPaymentTransactionStateDeferred:
|
||||
return;
|
||||
}
|
||||
|
||||
double totalAmount = 0;
|
||||
if (product) {
|
||||
totalAmount = transaction.payment.quantity * product.price.doubleValue;
|
||||
}
|
||||
|
||||
[self logImplicitTransactionEvent:eventName
|
||||
valueToSum:totalAmount
|
||||
parameters:[self getEventParametersOfProduct:product withTransaction:transaction]];
|
||||
}
|
||||
|
||||
- (void)logImplicitPurchaseTransaction:(SKPaymentTransaction *)transaction
|
||||
ofProduct:(SKProduct *)product
|
||||
{
|
||||
NSString *eventName = nil;
|
||||
switch (transaction.transactionState) {
|
||||
case SKPaymentTransactionStatePurchasing:
|
||||
eventName = FBSDKAppEventNameInitiatedCheckout;
|
||||
break;
|
||||
case SKPaymentTransactionStatePurchased:
|
||||
eventName = FBSDKAppEventNamePurchased;
|
||||
break;
|
||||
case SKPaymentTransactionStateFailed:
|
||||
eventName = FBSDKAppEventNamePurchaseFailed;
|
||||
break;
|
||||
case SKPaymentTransactionStateRestored:
|
||||
eventName = FBSDKAppEventNamePurchaseRestored;
|
||||
break;
|
||||
case SKPaymentTransactionStateDeferred:
|
||||
return;
|
||||
}
|
||||
|
||||
double totalAmount = 0;
|
||||
if (product) {
|
||||
totalAmount = transaction.payment.quantity * product.price.doubleValue;
|
||||
}
|
||||
|
||||
[self logImplicitTransactionEvent:eventName
|
||||
valueToSum:totalAmount
|
||||
parameters:[self getEventParametersOfProduct:product withTransaction:transaction]];
|
||||
}
|
||||
|
||||
- (void)logImplicitTransactionEvent:(NSString *)eventName
|
||||
valueToSum:(double)valueToSum
|
||||
parameters:(NSDictionary<NSString *, id> *)parameters
|
||||
{
|
||||
NSMutableDictionary *eventParameters = [NSMutableDictionary dictionaryWithDictionary:parameters];
|
||||
|
||||
if ([eventName isEqualToString:FBSDKAppEventNamePurchased]) {
|
||||
if ([_eventsWithReceipt containsObject:eventName]) {
|
||||
NSData* receipt = [self fetchDeviceReceipt];
|
||||
if (receipt) {
|
||||
NSString *base64encodedReceipt = [receipt base64EncodedStringWithOptions:0];
|
||||
@@ -349,7 +537,8 @@ static NSMutableArray *g_pendingRequestors;
|
||||
}
|
||||
|
||||
// Fetch the current receipt for this application.
|
||||
- (NSData*)fetchDeviceReceipt {
|
||||
- (NSData*)fetchDeviceReceipt
|
||||
{
|
||||
NSURL *receiptURL = [NSBundle bundleForClass:[self class]].appStoreReceiptURL;
|
||||
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
|
||||
return receipt;
|
||||
+1
@@ -22,6 +22,7 @@ FOUNDATION_EXPORT NSString *const FBSDKTimeSpentFilename;
|
||||
|
||||
// Class to encapsulate persisting of time spent data collected by [FBSDKAppEvents activateApp]. The activate app App Event is
|
||||
// logged when restore: is called with sufficient time since the last deactivation.
|
||||
NS_SWIFT_NAME(TimeSpentData)
|
||||
@interface FBSDKTimeSpentData : NSObject
|
||||
|
||||
+ (void)suspend;
|
||||
+4
-4
@@ -154,9 +154,9 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
FBSDKTimeSpentPersistKeySessionID : _sessionID,
|
||||
};
|
||||
|
||||
NSString *content = [FBSDKInternalUtility JSONStringForObject:timeSpentData error:NULL invalidObjectHandler:NULL];
|
||||
NSString *content = [FBSDKBasicUtility JSONStringForObject:timeSpentData error:NULL invalidObjectHandler:NULL];
|
||||
|
||||
[content writeToFile:[FBSDKAppEventsUtility persistenceFilePath:FBSDKTimeSpentFilename]
|
||||
[content writeToFile:[FBSDKBasicUtility persistenceFilePath:FBSDKTimeSpentFilename]
|
||||
atomically:YES
|
||||
encoding:NSASCIIStringEncoding
|
||||
error:nil];
|
||||
@@ -181,7 +181,7 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
if (!_isCurrentlyLoaded) {
|
||||
|
||||
NSString *content =
|
||||
[[NSString alloc] initWithContentsOfFile:[FBSDKAppEventsUtility persistenceFilePath:FBSDKTimeSpentFilename]
|
||||
[[NSString alloc] initWithContentsOfFile:[FBSDKBasicUtility persistenceFilePath:FBSDKTimeSpentFilename]
|
||||
usedEncoding:nil
|
||||
error:nil];
|
||||
|
||||
@@ -203,7 +203,7 @@ static const long INACTIVE_SECONDS_QUANTA[] =
|
||||
|
||||
} else {
|
||||
|
||||
NSDictionary *results = [FBSDKInternalUtility objectForJSONString:content error:NULL];
|
||||
NSDictionary<id, id> *results = [FBSDKBasicUtility objectForJSONString:content error:NULL];
|
||||
|
||||
_lastSuspendTime = [results[FBSDKTimeSpentPersistKeyLastSuspendTime] longValue];
|
||||
|
||||
Generated
+48
@@ -0,0 +1,48 @@
|
||||
// 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 "FBSDKAppEvents+Internal.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NS_SWIFT_NAME(UserDataStore)
|
||||
@interface FBSDKUserDataStore : NSObject
|
||||
|
||||
+ (void)setAndHashUserEmail:(nullable NSString *)email
|
||||
firstName:(nullable NSString *)firstName
|
||||
lastName:(nullable NSString *)lastName
|
||||
phone:(nullable NSString *)phone
|
||||
dateOfBirth:(nullable NSString *)dateOfBirth
|
||||
gender:(nullable NSString *)gender
|
||||
city:(nullable NSString *)city
|
||||
state:(nullable NSString *)state
|
||||
zip:(nullable NSString *)zip
|
||||
country:(nullable NSString *)country;
|
||||
+ (void)setAndHashData:(nullable NSString *)data
|
||||
forType:(FBSDKAppEventUserDataType)type;
|
||||
+ (void)setHashData:(nullable NSString *)hashData
|
||||
forType:(FBSDKAppEventUserDataType)type;
|
||||
+ (nullable NSString *)getHashedData;
|
||||
+ (nullable NSString *)getHashedDataForType:(FBSDKAppEventUserDataType)type;
|
||||
+ (void)clearDataForType:(FBSDKAppEventUserDataType)type;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
Generated
+199
@@ -0,0 +1,199 @@
|
||||
// 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 "FBSDKUserDataStore.h"
|
||||
|
||||
#import "FBSDKAppEventsUtility.h"
|
||||
#import "FBSDKLogger.h"
|
||||
#import "FBSDKSettings.h"
|
||||
#import "FBSDKUtility.h"
|
||||
|
||||
static NSString *const FBSDKUserDataKey = @"com.facebook.appevents.UserDataStore.userData";
|
||||
|
||||
static NSMutableDictionary<NSString *, NSString *> *hashedUserData;
|
||||
static dispatch_queue_t serialQueue;
|
||||
|
||||
@implementation FBSDKUserDataStore
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
serialQueue = dispatch_queue_create("com.facebook.appevents.UserDataStore", DISPATCH_QUEUE_SERIAL);
|
||||
NSString *userData = [[NSUserDefaults standardUserDefaults] stringForKey:FBSDKUserDataKey];
|
||||
if (userData) {
|
||||
hashedUserData = (NSMutableDictionary<NSString *, NSString *> *)[NSJSONSerialization JSONObjectWithData:[userData dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:NSJSONReadingMutableContainers
|
||||
error:nil];
|
||||
}
|
||||
if (!hashedUserData) {
|
||||
hashedUserData = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setAndHashUserEmail:(nullable NSString *)email
|
||||
firstName:(nullable NSString *)firstName
|
||||
lastName:(nullable NSString *)lastName
|
||||
phone:(nullable NSString *)phone
|
||||
dateOfBirth:(nullable NSString *)dateOfBirth
|
||||
gender:(nullable NSString *)gender
|
||||
city:(nullable NSString *)city
|
||||
state:(nullable NSString *)state
|
||||
zip:(nullable NSString *)zip
|
||||
country:(nullable NSString *)country
|
||||
{
|
||||
NSMutableDictionary *ud = [[NSMutableDictionary alloc] init];
|
||||
if (email) {
|
||||
ud[FBSDKAppEventEmail] = [FBSDKUserDataStore encryptData:email type:FBSDKAppEventEmail];
|
||||
}
|
||||
if (firstName) {
|
||||
ud[FBSDKAppEventFirstName] = [FBSDKUserDataStore encryptData:firstName type:FBSDKAppEventFirstName];
|
||||
}
|
||||
if (lastName) {
|
||||
ud[FBSDKAppEventLastName] = [FBSDKUserDataStore encryptData:lastName type:FBSDKAppEventLastName];
|
||||
}
|
||||
if (phone) {
|
||||
ud[FBSDKAppEventPhone] = [FBSDKUserDataStore encryptData:phone type:FBSDKAppEventPhone];
|
||||
}
|
||||
if (dateOfBirth) {
|
||||
ud[FBSDKAppEventDateOfBirth] = [FBSDKUserDataStore encryptData:dateOfBirth type:FBSDKAppEventDateOfBirth];
|
||||
}
|
||||
if (gender) {
|
||||
ud[FBSDKAppEventGender] = [FBSDKUserDataStore encryptData:gender type:FBSDKAppEventGender];
|
||||
}
|
||||
if (city) {
|
||||
ud[FBSDKAppEventCity] = [FBSDKUserDataStore encryptData:city type:FBSDKAppEventCity];
|
||||
}
|
||||
if (state) {
|
||||
ud[FBSDKAppEventState] = [FBSDKUserDataStore encryptData:state type:FBSDKAppEventState];
|
||||
}
|
||||
if (zip) {
|
||||
ud[FBSDKAppEventZip] = [FBSDKUserDataStore encryptData:zip type:FBSDKAppEventZip];
|
||||
}
|
||||
if (country) {
|
||||
ud[FBSDKAppEventCountry] = [FBSDKUserDataStore encryptData:country type:FBSDKAppEventCountry];
|
||||
}
|
||||
|
||||
dispatch_async(serialQueue, ^{
|
||||
hashedUserData = [ud mutableCopy];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[FBSDKUserDataStore stringByHashedData:hashedUserData]
|
||||
forKey:FBSDKUserDataKey];
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)setAndHashData:(nullable NSString *)data
|
||||
forType:(FBSDKAppEventUserDataType)type
|
||||
{
|
||||
[FBSDKUserDataStore setHashData:[FBSDKUserDataStore encryptData:data type:type]
|
||||
forType:type];
|
||||
}
|
||||
|
||||
+ (void)setHashData:(nullable NSString *)hashData
|
||||
forType:(FBSDKAppEventUserDataType)type
|
||||
{
|
||||
dispatch_async(serialQueue, ^{
|
||||
if (!hashData) {
|
||||
[hashedUserData removeObjectForKey:type];
|
||||
} else {
|
||||
hashedUserData[type] = hashData;
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[FBSDKUserDataStore stringByHashedData:hashedUserData]
|
||||
forKey:FBSDKUserDataKey];
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)clearDataForType:(FBSDKAppEventUserDataType)type
|
||||
{
|
||||
[FBSDKUserDataStore setAndHashData:nil forType:type];
|
||||
}
|
||||
|
||||
+ (NSString *)getHashedData
|
||||
{
|
||||
__block NSString *hashedUserDataString;
|
||||
dispatch_sync(serialQueue, ^{
|
||||
hashedUserDataString = [FBSDKUserDataStore stringByHashedData:hashedUserData];
|
||||
});
|
||||
return hashedUserDataString;
|
||||
}
|
||||
|
||||
+ (NSString *)getHashedDataForType:(FBSDKAppEventUserDataType)type
|
||||
{
|
||||
__block NSString *hashedData;
|
||||
dispatch_sync(serialQueue, ^{
|
||||
hashedData = [hashedUserData objectForKey:type];
|
||||
});
|
||||
return hashedData;
|
||||
}
|
||||
|
||||
+ (NSString *)stringByHashedData:(id)hashedData
|
||||
{
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:hashedData
|
||||
options:0
|
||||
error:&error];
|
||||
if (jsonData) {
|
||||
return [[NSString alloc] initWithData:jsonData
|
||||
encoding:NSUTF8StringEncoding];
|
||||
} else {
|
||||
[FBSDKAppEventsUtility logAndNotify:[NSString stringWithFormat:@"Invalid json object: %@", error]];
|
||||
return @"";
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)encryptData:(NSString *)data
|
||||
type:(FBSDKAppEventUserDataType)type
|
||||
{
|
||||
if (data.length == 0 || [FBSDKUserDataStore maybeSHA256Hashed:data]) {
|
||||
return data;
|
||||
}
|
||||
return [FBSDKUtility SHA256Hash:[FBSDKUserDataStore normalizeData:data type:type]];
|
||||
}
|
||||
|
||||
+ (NSString *)normalizeData:(NSString *)data
|
||||
type:(FBSDKAppEventUserDataType)type
|
||||
{
|
||||
NSString *normalizedData = @"";
|
||||
NSSet<FBSDKAppEventUserDataType> *set = [NSSet setWithArray:
|
||||
@[FBSDKAppEventEmail, FBSDKAppEventFirstName, FBSDKAppEventLastName, FBSDKAppEventCity, FBSDKAppEventState, FBSDKAppEventCountry]];
|
||||
if ([set containsObject:type]) {
|
||||
normalizedData = [data stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
normalizedData = normalizedData.lowercaseString;
|
||||
} else if ([type isEqualToString:FBSDKAppEventPhone]) {
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^0-9]"
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:&error
|
||||
];
|
||||
normalizedData = [regex stringByReplacingMatchesInString:data
|
||||
options:0
|
||||
range:NSMakeRange(0, data.length)
|
||||
withTemplate:@""
|
||||
];
|
||||
} else if ([type isEqualToString:FBSDKAppEventGender]) {
|
||||
NSString *temp = [data stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
temp = temp.lowercaseString;
|
||||
normalizedData = temp.length > 0 ? [temp substringToIndex:1]: @"";
|
||||
}
|
||||
return normalizedData;
|
||||
}
|
||||
|
||||
+ (BOOL)maybeSHA256Hashed:(NSString *)data
|
||||
{
|
||||
NSRange range = [data rangeOfString:@"[A-Fa-f0-9]{64}" options:NSRegularExpressionSearch];
|
||||
return (data.length == 64) && (range.location != NSNotFound);
|
||||
}
|
||||
|
||||
@end
|
||||
+9
-10
@@ -18,21 +18,20 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef void (^FBSDKURLSessionTaskHandler)(NSError *error,
|
||||
NSURLResponse *response,
|
||||
NSData *responseData);
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface FBSDKURLSessionTask : NSObject
|
||||
@interface FBSDKRestrictiveDataFilterManager : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithRequest:(NSURLRequest *)request
|
||||
fromSession:(NSURLSession *)session
|
||||
completionHandler:(FBSDKURLSessionTaskHandler)handler
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
+ (void)enable;
|
||||
+ (void)updateFilters:(nullable NSDictionary<NSString *, id> *)restrictiveParams;
|
||||
|
||||
- (void)cancel;
|
||||
- (void)start;
|
||||
+ (void)processEvents:(NSMutableArray<NSDictionary<NSString *, id> *> *)events;
|
||||
+ (nullable NSDictionary<NSString *, id> *)processParameters:(nullable NSDictionary<NSString *, id> *)parameters
|
||||
eventName:(NSString *)eventName;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
// 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 "FBSDKRestrictiveDataFilterManager.h"
|
||||
|
||||
#import "FBSDKBasicUtility.h"
|
||||
#import "FBSDKTypeUtility.h"
|
||||
|
||||
@interface FBSDKRestrictiveEventFilter : NSObject
|
||||
|
||||
@property (nonatomic, readonly, copy) NSString *eventName;
|
||||
@property (nonatomic, readonly, copy) NSDictionary<NSString *, id> *eventParams;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
-(instancetype)initWithEventName:(NSString *)eventName
|
||||
eventParams:(NSDictionary<NSString *, id> *)eventParams;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBSDKRestrictiveEventFilter
|
||||
|
||||
-(instancetype)initWithEventName:(NSString *)eventName
|
||||
eventParams:(NSDictionary<NSString *, id> *)eventParams
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_eventName = eventName;
|
||||
_eventParams = eventParams;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBSDKRestrictiveDataFilterManager
|
||||
|
||||
static BOOL isRestrictiveEventFilterEnabled = NO;
|
||||
|
||||
static NSMutableArray<FBSDKRestrictiveEventFilter *> *_params;
|
||||
static NSMutableSet<NSString *> *_deprecatedEvents;
|
||||
|
||||
+ (void)updateFilters:(nullable NSDictionary<NSString *, id> *)restrictiveParams
|
||||
{
|
||||
if (!isRestrictiveEventFilterEnabled) {
|
||||
return;
|
||||
}
|
||||
if (restrictiveParams.count > 0) {
|
||||
[_params removeAllObjects];
|
||||
[_deprecatedEvents removeAllObjects];
|
||||
NSMutableArray<FBSDKRestrictiveEventFilter *> *eventFilterArray = [NSMutableArray array];
|
||||
NSMutableSet<NSString *> *deprecatedEventSet = [NSMutableSet set];
|
||||
for (NSString *eventName in restrictiveParams.allKeys) {
|
||||
if (restrictiveParams[eventName][@"is_deprecated_event"]) {
|
||||
[deprecatedEventSet addObject:eventName];
|
||||
}
|
||||
if (restrictiveParams[eventName][@"restrictive_param"]) {
|
||||
FBSDKRestrictiveEventFilter *restrictiveEventFilter = [[FBSDKRestrictiveEventFilter alloc] initWithEventName:eventName
|
||||
eventParams:restrictiveParams[eventName][@"restrictive_param"]];
|
||||
[eventFilterArray addObject:restrictiveEventFilter];
|
||||
}
|
||||
}
|
||||
_params = eventFilterArray;
|
||||
_deprecatedEvents = deprecatedEventSet;
|
||||
}
|
||||
}
|
||||
|
||||
+ (nullable NSString *)getMatchedDataTypeWithEventName:(NSString *)eventName
|
||||
paramKey:(NSString *)paramKey
|
||||
{
|
||||
// match by params in custom events with event name
|
||||
for (FBSDKRestrictiveEventFilter *filter in _params) {
|
||||
if ([filter.eventName isEqualToString:eventName]) {
|
||||
NSString *type = [FBSDKTypeUtility stringValue:filter.eventParams[paramKey]];
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (BOOL)isDeprecatedEvent:(NSString *)eventName
|
||||
{
|
||||
return [_deprecatedEvents containsObject:eventName];
|
||||
}
|
||||
|
||||
+ (void)processEvents:(NSMutableArray<NSDictionary<NSString *, id> *> *)events
|
||||
{
|
||||
if (!isRestrictiveEventFilterEnabled) {
|
||||
return;
|
||||
}
|
||||
NSArray<NSDictionary<NSString *, id> *> *eventArray = [events copy];
|
||||
for (NSDictionary<NSString *, NSDictionary<NSString *, id> *> *event in eventArray) {
|
||||
if ([FBSDKRestrictiveDataFilterManager isDeprecatedEvent:event[@"event"][@"_eventName"]]) {
|
||||
[events removeObject:event];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSDictionary<NSString *,id> *)processParameters:(NSDictionary<NSString *,id> *)parameters
|
||||
eventName:(NSString *)eventName
|
||||
{
|
||||
if (!isRestrictiveEventFilterEnabled) {
|
||||
return parameters;
|
||||
}
|
||||
if (parameters) {
|
||||
NSMutableDictionary<NSString *, id> *params = [NSMutableDictionary dictionaryWithDictionary:parameters];
|
||||
NSMutableDictionary<NSString *, NSString *> *restrictedParams = [NSMutableDictionary dictionary];
|
||||
|
||||
for (NSString *key in [parameters keyEnumerator]) {
|
||||
NSString *type = [FBSDKRestrictiveDataFilterManager getMatchedDataTypeWithEventName:eventName
|
||||
paramKey:key];
|
||||
if (type) {
|
||||
[restrictedParams setObject:type forKey:key];
|
||||
[params removeObjectForKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
if ([[restrictedParams allKeys] count] > 0) {
|
||||
NSString *restrictedParamsJSONString = [FBSDKBasicUtility JSONStringForObject:restrictedParams
|
||||
error:NULL
|
||||
invalidObjectHandler:NULL];
|
||||
[FBSDKBasicUtility dictionary:params setObject:restrictedParamsJSONString forKey:@"_restrictedParams"];
|
||||
}
|
||||
|
||||
return [params copy];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void)enable
|
||||
{
|
||||
isRestrictiveEventFilterEnabled = YES;
|
||||
}
|
||||
|
||||
#pragma mark Helper functions
|
||||
|
||||
+ (BOOL)isMatchedWithPattern:(NSString *)pattern
|
||||
text:(NSString *)text
|
||||
{
|
||||
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
NSUInteger matches = [regex numberOfMatchesInString:text options:0 range:NSMakeRange(0, text.length)];
|
||||
return matches > 0;
|
||||
}
|
||||
|
||||
@end
|
||||
+16
-10
@@ -22,16 +22,21 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! The version of the App Link protocol that this library supports */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkVersion;
|
||||
/** The version of the App Link protocol that this library supports */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkVersion
|
||||
NS_SWIFT_NAME(AppLinkVersion);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Contains App Link metadata relevant for navigation on this device
|
||||
derived from the HTML at a given URL.
|
||||
*/
|
||||
NS_SWIFT_NAME(AppLink)
|
||||
@interface FBSDKAppLink : NSObject
|
||||
|
||||
/*!
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Creates a FBSDKAppLink with the given list of FBSDKAppLinkTargets and target URL.
|
||||
|
||||
Generally, this will only be used by implementers of the FBSDKAppLinkResolving protocol,
|
||||
@@ -42,20 +47,21 @@ FOUNDATION_EXPORT NSString *const FBSDKAppLinkVersion;
|
||||
from App Link metadata.
|
||||
@param webURL the fallback web URL, if any, for the app link.
|
||||
*/
|
||||
+ (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL
|
||||
+ (instancetype)appLinkWithSourceURL:(nullable NSURL *)sourceURL
|
||||
targets:(NSArray<FBSDKAppLinkTarget *> *)targets
|
||||
webURL:(nullable NSURL *)webURL;
|
||||
webURL:(nullable NSURL *)webURL
|
||||
NS_SWIFT_NAME(init(sourceURL:targets:webURL:));
|
||||
|
||||
/*! The URL from which this FBSDKAppLink was derived */
|
||||
@property (nonatomic, strong, readonly) NSURL *sourceURL;
|
||||
/** The URL from which this FBSDKAppLink was derived */
|
||||
@property (nonatomic, strong, readonly, nullable) NSURL *sourceURL;
|
||||
|
||||
/*!
|
||||
/**
|
||||
The ordered list of targets applicable to this platform that will be used
|
||||
for navigation.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSArray<FBSDKAppLinkTarget *> *targets;
|
||||
|
||||
/*! The fallback web URL to use if no targets are installed on this device. */
|
||||
/** The fallback web URL to use if no targets are installed on this device. */
|
||||
@property (nonatomic, strong, readonly, nullable) NSURL *webURL;
|
||||
|
||||
@end
|
||||
File renamed without changes.
+44
-40
@@ -23,17 +23,17 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
/**
|
||||
The result of calling navigate on a FBSDKAppLinkNavigation
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, FBSDKAppLinkNavigationType) {
|
||||
/*! Indicates that the navigation failed and no app was opened */
|
||||
/** Indicates that the navigation failed and no app was opened */
|
||||
FBSDKAppLinkNavigationTypeFailure,
|
||||
/*! Indicates that the navigation succeeded by opening the URL in the browser */
|
||||
/** Indicates that the navigation succeeded by opening the URL in the browser */
|
||||
FBSDKAppLinkNavigationTypeBrowser,
|
||||
/*! Indicates that the navigation succeeded by opening the URL in an app on the device */
|
||||
/** Indicates that the navigation succeeded by opening the URL in an app on the device */
|
||||
FBSDKAppLinkNavigationTypeApp
|
||||
};
|
||||
} NS_SWIFT_NAME(AppLinkNavigation.Type);
|
||||
|
||||
/**
|
||||
Describes the callback for appLinkFromURLInBackground.
|
||||
@@ -41,67 +41,83 @@ typedef NS_ENUM(NSInteger, FBSDKAppLinkNavigationType) {
|
||||
@param error the error during the request, if any
|
||||
|
||||
*/
|
||||
typedef void (^FBSDKAppLinkNavigationHandler)(FBSDKAppLinkNavigationType navType, NSError * _Nullable error);
|
||||
typedef void (^FBSDKAppLinkNavigationBlock)(FBSDKAppLinkNavigationType navType, NSError * _Nullable error)
|
||||
NS_SWIFT_NAME(AppLinkNavigationBlock);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Represents a pending request to navigate to an App Link. Most developers will
|
||||
simply use navigateToURLInBackground: to open a URL, but developers can build
|
||||
custom requests with additional navigation and app data attached to them by
|
||||
creating FBSDKAppLinkNavigations themselves.
|
||||
*/
|
||||
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension")
|
||||
NS_SWIFT_NAME(AppLinkNavigation)
|
||||
@interface FBSDKAppLinkNavigation : NSObject
|
||||
|
||||
/*!
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
The default resolver to be used for App Link resolution. If the developer has not set one explicitly,
|
||||
a basic, built-in FBSDKWebViewAppLinkResolver will be used.
|
||||
*/
|
||||
@property (class, nonatomic, strong) id<FBSDKAppLinkResolving> defaultResolver
|
||||
NS_SWIFT_NAME(default);
|
||||
|
||||
/**
|
||||
The extras for the AppLinkNavigation. This will generally contain application-specific
|
||||
data that should be passed along with the request, such as advertiser or affiliate IDs or
|
||||
other such metadata relevant on this device.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id> *extras;
|
||||
|
||||
/*!
|
||||
/**
|
||||
The al_applink_data for the AppLinkNavigation. This will generally contain data common to
|
||||
navigation attempts such as back-links, user agents, and other information that may be used
|
||||
in routing and handling an App Link request.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id> *appLinkData;
|
||||
|
||||
/*! The AppLink to navigate to */
|
||||
/** The AppLink to navigate to */
|
||||
@property (nonatomic, strong, readonly) FBSDKAppLink *appLink;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Return navigation type for current instance.
|
||||
No-side-effect version of navigate:
|
||||
*/
|
||||
@property (nonatomic, readonly) FBSDKAppLinkNavigationType navigationType;
|
||||
|
||||
/*! Creates an AppLinkNavigation with the given link, extras, and App Link data */
|
||||
/** Creates an AppLinkNavigation with the given link, extras, and App Link data */
|
||||
+ (instancetype)navigationWithAppLink:(FBSDKAppLink *)appLink
|
||||
extras:(NSDictionary<NSString *, id> *)extras
|
||||
appLinkData:(NSDictionary<NSString *, id> *)appLinkData;
|
||||
appLinkData:(NSDictionary<NSString *, id> *)appLinkData
|
||||
NS_SWIFT_NAME(init(appLink:extras:appLinkData:));
|
||||
|
||||
/*!
|
||||
/**
|
||||
Creates an NSDictionary with the correct format for iOS callback URLs,
|
||||
to be used as 'appLinkData' argument in the call to navigationWithAppLink:extras:appLinkData:
|
||||
*/
|
||||
+ (NSDictionary<NSString *, NSDictionary<NSString *, NSString *> *> *)callbackAppLinkDataForAppWithName:(NSString *)appName
|
||||
url:(NSString *)url;
|
||||
url:(NSString *)url
|
||||
NS_SWIFT_NAME(callbackAppLinkData(forApp:url:));
|
||||
|
||||
/*! Performs the navigation */
|
||||
- (FBSDKAppLinkNavigationType)navigate:(NSError *__autoreleasing *)error;
|
||||
/** Performs the navigation */
|
||||
- (FBSDKAppLinkNavigationType)navigate:(NSError **)error
|
||||
__attribute__((swift_error(nonnull_error)));
|
||||
|
||||
/*! Returns a FBSDKAppLink for the given URL */
|
||||
+ (void)resolveAppLink:(NSURL *)destination handler:(FBSDKAppLinkFromURLHandler)handler;
|
||||
/** Returns a FBSDKAppLink for the given URL */
|
||||
+ (void)resolveAppLink:(NSURL *)destination handler:(FBSDKAppLinkBlock)handler;
|
||||
|
||||
/*! Returns a FBSDKAppLink for the given URL using the given App Link resolution strategy */
|
||||
/** Returns a FBSDKAppLink for the given URL using the given App Link resolution strategy */
|
||||
+ (void)resolveAppLink:(NSURL *)destination
|
||||
resolver:(id<FBSDKAppLinkResolving>)resolver
|
||||
handler:(FBSDKAppLinkFromURLHandler)handler;
|
||||
handler:(FBSDKAppLinkBlock)handler;
|
||||
|
||||
/*! Navigates to a FBSDKAppLink and returns whether it opened in-app or in-browser */
|
||||
+ (FBSDKAppLinkNavigationType)navigateToAppLink:(FBSDKAppLink *)link error:(NSError *__autoreleasing *)error;
|
||||
/** Navigates to a FBSDKAppLink and returns whether it opened in-app or in-browser */
|
||||
+ (FBSDKAppLinkNavigationType)navigateToAppLink:(FBSDKAppLink *)link error:(NSError **)error
|
||||
__attribute__((swift_error(nonnull_error)));
|
||||
|
||||
/*!
|
||||
/**
|
||||
Returns a FBSDKAppLinkNavigationType based on a FBSDKAppLink.
|
||||
It's essentially a no-side-effect version of navigateToAppLink:error:,
|
||||
allowing apps to determine flow based on the link type (e.g. open an
|
||||
@@ -109,28 +125,16 @@ NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension")
|
||||
*/
|
||||
+ (FBSDKAppLinkNavigationType)navigationTypeForLink:(FBSDKAppLink *)link;
|
||||
|
||||
/*! Navigates to a URL (an asynchronous action) and returns a FBSDKNavigationType */
|
||||
+ (void)navigateToURL:(NSURL *)destination handler:(FBSDKAppLinkNavigationHandler)handler;
|
||||
/** Navigates to a URL (an asynchronous action) and returns a FBSDKNavigationType */
|
||||
+ (void)navigateToURL:(NSURL *)destination handler:(FBSDKAppLinkNavigationBlock)handler;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Navigates to a URL (an asynchronous action) using the given App Link resolution
|
||||
strategy and returns a FBSDKNavigationType
|
||||
*/
|
||||
+ (void)navigateToURL:(NSURL *)destination
|
||||
resolver:(id<FBSDKAppLinkResolving>)resolver
|
||||
handler:(FBSDKAppLinkNavigationHandler)handler;
|
||||
|
||||
/*!
|
||||
Gets the default resolver to be used for App Link resolution. If the developer has not set one explicitly,
|
||||
a basic, built-in resolver will be used.
|
||||
*/
|
||||
+ (id<FBSDKAppLinkResolving>)defaultResolver;
|
||||
|
||||
/*!
|
||||
Sets the default resolver to be used for App Link resolution. Setting this to nil will revert the
|
||||
default resolver to the basic, built-in resolver provided by FBSDK.
|
||||
*/
|
||||
+ (void)setDefaultResolver:(id<FBSDKAppLinkResolving>)resolver;
|
||||
handler:(FBSDKAppLinkNavigationBlock)handler;
|
||||
|
||||
@end
|
||||
|
||||
+4
-4
@@ -208,21 +208,21 @@ static id<FBSDKAppLinkResolving> defaultResolver;
|
||||
|
||||
+ (void)resolveAppLink:(NSURL *)destination
|
||||
resolver:(id<FBSDKAppLinkResolving>)resolver
|
||||
handler:(FBSDKAppLinkFromURLHandler)handler {
|
||||
handler:(FBSDKAppLinkBlock)handler {
|
||||
[resolver appLinkFromURL:destination handler:handler];
|
||||
}
|
||||
|
||||
+ (void)resolveAppLink:(NSURL *)destination handler:(FBSDKAppLinkFromURLHandler)handler {
|
||||
+ (void)resolveAppLink:(NSURL *)destination handler:(FBSDKAppLinkBlock)handler {
|
||||
[self resolveAppLink:destination resolver:[self defaultResolver] handler:handler];
|
||||
}
|
||||
|
||||
+ (void)navigateToURL:(NSURL *)destination handler:(FBSDKAppLinkNavigationHandler)handler {
|
||||
+ (void)navigateToURL:(NSURL *)destination handler:(FBSDKAppLinkNavigationBlock)handler {
|
||||
[self navigateToURL:destination resolver:[self defaultResolver] handler:handler];
|
||||
}
|
||||
|
||||
+ (void)navigateToURL:(NSURL *)destination
|
||||
resolver:(id<FBSDKAppLinkResolving>)resolver
|
||||
handler:(FBSDKAppLinkNavigationHandler)handler {
|
||||
handler:(FBSDKAppLinkNavigationBlock)handler {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self resolveAppLink:destination
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
// 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 "FBSDKAppLinkResolving.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Describes the callback for appLinkFromURLInBackground.
|
||||
@param appLinks the FBSDKAppLinks representing the deferred App Links
|
||||
@param error the error during the request, if any
|
||||
*/
|
||||
typedef void (^FBSDKAppLinksBlock)(NSDictionary<NSURL *, FBSDKAppLink *> * appLinks,
|
||||
NSError * _Nullable error)
|
||||
NS_SWIFT_NAME(AppLinksBlock);
|
||||
|
||||
/**
|
||||
|
||||
Provides an implementation of the FBSDKAppLinkResolving protocol that uses the Facebook App Link
|
||||
Index API to resolve App Links given a URL. It also provides an additional helper method that can resolve
|
||||
multiple App Links in a single call.
|
||||
|
||||
Usage of this type requires a client token. See `[FBSDKSettings setClientToken:]`
|
||||
*/
|
||||
|
||||
NS_SWIFT_NAME(AppLinkResolver)
|
||||
@interface FBSDKAppLinkResolver : NSObject<FBSDKAppLinkResolving>
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Asynchronously resolves App Link data for a given array of URLs.
|
||||
|
||||
@param urls The URLs to resolve into an App Link.
|
||||
@param handler The completion block that will return an App Link for the given URL.
|
||||
*/
|
||||
- (void)appLinksFromURLs:(NSArray<NSURL *> *)urls handler:(FBSDKAppLinksBlock)handler
|
||||
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension");
|
||||
|
||||
/**
|
||||
Allocates and initializes a new instance of FBSDKAppLinkResolver.
|
||||
*/
|
||||
+ (instancetype)resolver
|
||||
NS_SWIFT_NAME(init());
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+4
-129
@@ -20,13 +20,9 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <Bolts/BFAppLink.h>
|
||||
#import <Bolts/BFAppLinkTarget.h>
|
||||
#import <Bolts/BFTask.h>
|
||||
#import <Bolts/BFTaskCompletionSource.h>
|
||||
|
||||
#import "FBSDKAccessToken.h"
|
||||
#import "FBSDKAppLink.h"
|
||||
#import "FBSDKAppLinkTarget.h"
|
||||
#import "FBSDKGraphRequest+Internal.h"
|
||||
#import "FBSDKGraphRequestConnection.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
@@ -46,47 +42,35 @@ static NSString *const kAppLinksKey = @"app_links";
|
||||
|
||||
@interface FBSDKAppLinkResolver ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary<NSURL *, BFAppLink *> *cachedBFAppLinks;
|
||||
@property (nonatomic, strong) NSMutableDictionary<NSURL *, FBSDKAppLink *> *cachedFBSDKAppLinks;
|
||||
@property (nonatomic, assign) UIUserInterfaceIdiom userInterfaceIdiom;
|
||||
@end
|
||||
|
||||
@implementation FBSDKAppLinkResolver
|
||||
|
||||
static Class g_BFTaskCompletionSourceClass;
|
||||
static Class g_BFAppLinkTargetClass;
|
||||
static Class g_BFAppLinkClass;
|
||||
static Class g_BFTaskClass;
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [FBSDKAppLinkResolver class]) {
|
||||
g_BFTaskCompletionSourceClass = [FBSDKInternalUtility
|
||||
resolveBoltsClassWithName:@"BFTaskCompletionSource"];
|
||||
g_BFAppLinkTargetClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFAppLinkTarget"];
|
||||
g_BFTaskClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFTask"];
|
||||
g_BFAppLinkClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFAppLink"];
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom
|
||||
{
|
||||
if (self = [super init]) {
|
||||
self.cachedBFAppLinks = [NSMutableDictionary dictionary];
|
||||
self.cachedFBSDKAppLinks = [NSMutableDictionary dictionary];
|
||||
self.userInterfaceIdiom = userInterfaceIdiom;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)appLinkFromURL:(NSURL *)url handler:(FBSDKAppLinkFromURLHandler)handler
|
||||
- (void)appLinkFromURL:(NSURL *)url handler:(FBSDKAppLinkBlock)handler
|
||||
{
|
||||
[self appLinksFromURLs:@[url] handler:^(NSDictionary<NSURL *, FBSDKAppLink *> *urls, NSError * _Nullable error) {
|
||||
handler(urls[url], error);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)appLinksFromURLs:(NSArray<NSURL *> *)urls handler:(FBSDKAppLinksFromURLArrayHandler)handler
|
||||
- (void)appLinksFromURLs:(NSArray<NSURL *> *)urls handler:(FBSDKAppLinksBlock)handler
|
||||
{
|
||||
if (![FBSDKSettings clientToken] && ![FBSDKAccessToken currentAccessToken]) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
|
||||
@@ -166,7 +150,7 @@ static Class g_BFTaskClass;
|
||||
NSURL *fallbackUrl = webFallbackString ? [NSURL URLWithString:webFallbackString] : url;
|
||||
|
||||
NSNumber *shouldFallback = webTarget[kShouldFallbackKey];
|
||||
if (shouldFallback && !shouldFallback.boolValue) {
|
||||
if (shouldFallback != nil && !shouldFallback.boolValue) {
|
||||
fallbackUrl = nil;
|
||||
}
|
||||
|
||||
@@ -182,115 +166,6 @@ static Class g_BFTaskClass;
|
||||
}];
|
||||
}
|
||||
|
||||
- (BFTask *)appLinksFromURLsInBackground:(NSArray *)urls
|
||||
{
|
||||
if (![FBSDKSettings clientToken] && ![FBSDKAccessToken currentAccessToken]) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
|
||||
logEntry:@"A user access token or clientToken is required to use FBAppLinkResolver"];
|
||||
}
|
||||
NSMutableDictionary<NSURL *, BFAppLink *> *appLinks = [NSMutableDictionary dictionary];
|
||||
NSMutableArray<NSURL *> *toFind = [NSMutableArray array];
|
||||
NSMutableArray<NSString *> *toFindStrings = [NSMutableArray array];
|
||||
|
||||
@synchronized (self.cachedBFAppLinks) {
|
||||
for (NSURL *url in urls) {
|
||||
if (self.cachedBFAppLinks[url]) {
|
||||
appLinks[url] = self.cachedBFAppLinks[url];
|
||||
} else {
|
||||
[toFind addObject:url];
|
||||
#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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (toFind.count == 0) {
|
||||
// All of the URLs have already been found.
|
||||
return [g_BFTaskClass taskWithResult:appLinks];
|
||||
}
|
||||
NSMutableArray<NSString *> *fields = [NSMutableArray arrayWithObject:kIOSKey];
|
||||
|
||||
NSString *idiomSpecificField = nil;
|
||||
|
||||
switch (self.userInterfaceIdiom) {
|
||||
case UIUserInterfaceIdiomPad:
|
||||
idiomSpecificField = kIPadKey;
|
||||
break;
|
||||
case UIUserInterfaceIdiomPhone:
|
||||
idiomSpecificField = kIPhoneKey;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (idiomSpecificField) {
|
||||
[fields addObject:idiomSpecificField];
|
||||
}
|
||||
NSString *path = [NSString stringWithFormat:@"?fields=%@.fields(%@)&ids=%@",
|
||||
kAppLinksKey,
|
||||
[fields componentsJoinedByString:@","],
|
||||
[toFindStrings componentsJoinedByString:@","]];
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:path
|
||||
parameters:nil
|
||||
flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery];
|
||||
BFTaskCompletionSource *tcs = [g_BFTaskCompletionSourceClass taskCompletionSource];
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
if (error) {
|
||||
[tcs setError:error];
|
||||
return;
|
||||
}
|
||||
for (NSURL *url in toFind) {
|
||||
id nestedObject = result[url.absoluteString][kAppLinksKey];
|
||||
NSMutableArray *rawTargets = [NSMutableArray array];
|
||||
if (idiomSpecificField) {
|
||||
[rawTargets addObjectsFromArray:nestedObject[idiomSpecificField]];
|
||||
}
|
||||
[rawTargets addObjectsFromArray:nestedObject[kIOSKey]];
|
||||
|
||||
NSMutableArray<BFAppLinkTarget *> *targets = [NSMutableArray arrayWithCapacity:rawTargets.count];
|
||||
for (id rawTarget in rawTargets) {
|
||||
[targets addObject:[g_BFAppLinkTargetClass appLinkTargetWithURL:[NSURL URLWithString:rawTarget[kURLKey]]
|
||||
appStoreId:rawTarget[kIOSAppStoreIdKey]
|
||||
appName:rawTarget[kIOSAppNameKey]]];
|
||||
}
|
||||
|
||||
id webTarget = nestedObject[kWebKey];
|
||||
NSString *webFallbackString = webTarget[kURLKey];
|
||||
NSURL *fallbackUrl = webFallbackString ? [NSURL URLWithString:webFallbackString] : url;
|
||||
|
||||
NSNumber *shouldFallback = webTarget[kShouldFallbackKey];
|
||||
if (shouldFallback && !shouldFallback.boolValue) {
|
||||
fallbackUrl = nil;
|
||||
}
|
||||
|
||||
BFAppLink *link = [g_BFAppLinkClass appLinkWithSourceURL:url
|
||||
targets:targets
|
||||
webURL:fallbackUrl];
|
||||
@synchronized (self.cachedBFAppLinks) {
|
||||
self.cachedBFAppLinks[url] = link;
|
||||
}
|
||||
appLinks[url] = link;
|
||||
}
|
||||
[tcs setResult:appLinks];
|
||||
}];
|
||||
return tcs.task;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
- (BFTask *)appLinkFromURLInBackground:(NSURL *)url
|
||||
{
|
||||
// Implement in terms of appLinksFromURLsInBackground
|
||||
BFTask *resolveTask = [self appLinksFromURLsInBackground:@[url]];
|
||||
return [resolveTask continueWithSuccessBlock:^id(BFTask *task) {
|
||||
return task.result[url];
|
||||
}];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
+ (instancetype)resolver
|
||||
{
|
||||
return [[self alloc] initWithUserInterfaceIdiom:UI_USER_INTERFACE_IDIOM()];
|
||||
+4
-10
@@ -28,22 +28,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@param error the error during the request, if any
|
||||
|
||||
*/
|
||||
typedef void (^FBSDKAppLinkFromURLHandler)(FBSDKAppLink * _Nullable appLink, NSError * _Nullable error);
|
||||
typedef void (^FBSDKAppLinkBlock)(FBSDKAppLink * _Nullable appLink, NSError * _Nullable error)
|
||||
NS_SWIFT_NAME(AppLinkBlock);
|
||||
|
||||
|
||||
/**
|
||||
Describes the callback for appLinkFromURLInBackground.
|
||||
@param appLinks the FBSDKAppLinks representing the deferred App Links
|
||||
@param error the error during the request, if any
|
||||
*/
|
||||
typedef void (^FBSDKAppLinksFromURLArrayHandler)(NSDictionary<NSURL *, FBSDKAppLink *> * appLinks,
|
||||
NSError * _Nullable error);
|
||||
|
||||
/*!
|
||||
Implement this protocol to provide an alternate strategy for resolving
|
||||
App Links that may include pre-fetching, caching, or querying for App Link
|
||||
data from an index provided by a service provider.
|
||||
*/
|
||||
NS_SWIFT_NAME(AppLinkResolving)
|
||||
@protocol FBSDKAppLinkResolving <NSObject>
|
||||
|
||||
/**
|
||||
@@ -52,7 +46,7 @@ typedef void (^FBSDKAppLinksFromURLArrayHandler)(NSDictionary<NSURL *, FBSDKAppL
|
||||
@param url The URL to resolve into an App Link.
|
||||
@param handler The completion block that will return an App Link for the given URL.
|
||||
*/
|
||||
- (void)appLinkFromURL:(NSURL *)url handler:(FBSDKAppLinkFromURLHandler)handler
|
||||
- (void)appLinkFromURL:(NSURL *)url handler:(FBSDKAppLinkBlock)handler
|
||||
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension");
|
||||
|
||||
@end
|
||||
+27
-18
@@ -26,71 +26,80 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@class FBSDKAppLink;
|
||||
@class FBSDKAppLinkReturnToRefererController;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Protocol that a class can implement in order to be notified when the user has navigated back
|
||||
to the referer of an App Link.
|
||||
*/
|
||||
NS_SWIFT_NAME(AppLinkReturnToRefererControllerDelegate)
|
||||
@protocol FBSDKAppLinkReturnToRefererControllerDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
/*! Called when the user has tapped to navigate, but before the navigation has been performed. */
|
||||
/** Called when the user has tapped to navigate, but before the navigation has been performed. */
|
||||
- (void)returnToRefererController:(FBSDKAppLinkReturnToRefererController *)controller
|
||||
willNavigateToAppLink:(FBSDKAppLink *)appLink;
|
||||
willNavigateToAppLink:(FBSDKAppLink *)appLink
|
||||
NS_SWIFT_NAME(return(to:willNavigateTo:));
|
||||
|
||||
/*! Called after the navigation has been attempted, with an indication of whether the referer
|
||||
/** Called after the navigation has been attempted, with an indication of whether the referer
|
||||
app link was successfully opened. */
|
||||
- (void)returnToRefererController:(FBSDKAppLinkReturnToRefererController *)controller
|
||||
didNavigateToAppLink:(FBSDKAppLink *)url
|
||||
type:(FBSDKAppLinkNavigationType)type;
|
||||
type:(FBSDKAppLinkNavigationType)type
|
||||
NS_SWIFT_NAME(return(to:didNavigateTo:type:));
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
/**
|
||||
A controller class that implements default behavior for a FBSDKAppLinkReturnToRefererView, including
|
||||
the ability to display the view above the navigation bar for navigation-based apps.
|
||||
*/
|
||||
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension")
|
||||
NS_SWIFT_NAME(AppLinkReturnToRefererController)
|
||||
@interface FBSDKAppLinkReturnToRefererController : NSObject <FBSDKAppLinkReturnToRefererViewDelegate>
|
||||
|
||||
/*!
|
||||
/**
|
||||
The delegate that will be notified when the user navigates back to the referer.
|
||||
*/
|
||||
@property (nonatomic, weak, nullable) id<FBSDKAppLinkReturnToRefererControllerDelegate> delegate;
|
||||
|
||||
/*!
|
||||
/**
|
||||
The FBSDKAppLinkReturnToRefererView this controller is controlling.
|
||||
*/
|
||||
@property (nonatomic, strong) FBSDKAppLinkReturnToRefererView *view;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Initializes a controller suitable for controlling a FBSDKAppLinkReturnToRefererView that is to be displayed
|
||||
contained within another UIView (i.e., not displayed above the navigation bar).
|
||||
*/
|
||||
- (instancetype)init NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Initializes a controller suitable for controlling a FBSDKAppLinkReturnToRefererView that is to be displayed
|
||||
displayed above the navigation bar.
|
||||
*/
|
||||
- (instancetype)initForDisplayAboveNavController:(UINavigationController *)navController;
|
||||
|
||||
/*!
|
||||
@param navController The Navigation Controller for display above
|
||||
*/
|
||||
- (instancetype)initForDisplayAboveNavController:(UINavigationController *)navController
|
||||
NS_SWIFT_NAME(init(navController:));
|
||||
|
||||
/**
|
||||
Removes the view entirely from the navigation controller it is currently displayed in.
|
||||
*/
|
||||
- (void)removeFromNavController;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Shows the FBSDKAppLinkReturnToRefererView with the specified referer information. If nil or missing data,
|
||||
the view will not be displayed. */
|
||||
- (void)showViewForRefererAppLink:(FBSDKAppLink *)refererAppLink;
|
||||
- (void)showViewForRefererAppLink:(FBSDKAppLink *)refererAppLink
|
||||
NS_SWIFT_NAME(showView(forReferer:));
|
||||
|
||||
/*!
|
||||
/**
|
||||
Shows the FBSDKAppLinkReturnToRefererView with referer information extracted from the specified URL.
|
||||
If nil or missing referer App Link data, the view will not be displayed. */
|
||||
- (void)showViewForRefererURL:(NSURL *)url;
|
||||
- (void)showViewForRefererURL:(NSURL *)url
|
||||
NS_SWIFT_NAME(showView(forReferer:));
|
||||
|
||||
/*!
|
||||
/**
|
||||
Closes the view, possibly animating it.
|
||||
*/
|
||||
- (void)closeViewAnimated:(BOOL)animated;
|
||||
File renamed without changes.
+18
-14
@@ -25,33 +25,35 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, FBSDKIncludeStatusBarInSize) {
|
||||
FBSDKIncludeStatusBarInSizeNever,
|
||||
FBSDKIncludeStatusBarInSizeIOS7AndLater,
|
||||
FBSDKIncludeStatusBarInSizeAlways,
|
||||
};
|
||||
} NS_SWIFT_NAME(FBAppLinkReturnToRefererView.StatusBarSizeInclude);
|
||||
|
||||
@class FBSDKAppLinkReturnToRefererView;
|
||||
@class FBSDKURL;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Protocol that a class can implement in order to be notified when the user has navigated back
|
||||
to the referer of an App Link.
|
||||
*/
|
||||
NS_SWIFT_NAME(AppLinkReturnToRefererViewDelegate)
|
||||
@protocol FBSDKAppLinkReturnToRefererViewDelegate <NSObject>
|
||||
|
||||
/*!
|
||||
/**
|
||||
Called when the user has tapped inside the close button.
|
||||
*/
|
||||
- (void)returnToRefererViewDidTapInsideCloseButton:(FBSDKAppLinkReturnToRefererView *)view;
|
||||
- (void)returnToRefererViewDidTapInsideCloseButton:(FBSDKAppLinkReturnToRefererView *)view
|
||||
NS_SWIFT_NAME(returnToRefererViewDidTapInsideCloseButton(_:));
|
||||
|
||||
/*!
|
||||
/**
|
||||
Called when the user has tapped inside the App Link portion of the view.
|
||||
*/
|
||||
- (void)returnToRefererViewDidTapInsideLink:(FBSDKAppLinkReturnToRefererView *)view
|
||||
link:(FBSDKAppLink *)link;
|
||||
link:(FBSDKAppLink *)link
|
||||
NS_SWIFT_NAME(returnToRefererView(_:didTapInside:));
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
/**
|
||||
Provides a UIView that displays a button allowing users to navigate back to the
|
||||
application that launched the App Link currently being handled, if the App Link
|
||||
contained referer data. The user can also close the view by clicking a close button
|
||||
@@ -59,31 +61,33 @@ typedef NS_ENUM(NSUInteger, FBSDKIncludeStatusBarInSize) {
|
||||
referer data, it will have zero size and no UI will be displayed.
|
||||
*/
|
||||
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension")
|
||||
NS_SWIFT_NAME(FBAppLinkReturnToRefererView)
|
||||
@interface FBSDKAppLinkReturnToRefererView : UIView
|
||||
|
||||
/*!
|
||||
/**
|
||||
The delegate that will be notified when the user navigates back to the referer.
|
||||
*/
|
||||
@property (nonatomic, weak, nullable) id<FBSDKAppLinkReturnToRefererViewDelegate> delegate;
|
||||
|
||||
/*!
|
||||
/**
|
||||
The color of the text label and close button.
|
||||
*/
|
||||
@property (nonatomic, strong) UIColor *textColor;
|
||||
|
||||
@property (nonatomic, strong) FBSDKAppLink *refererAppLink;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Indicates whether to extend the size of the view to include the current status bar
|
||||
size, for use in scenarios where the view might extend under the status bar on iOS 7 and
|
||||
above; this property has no effect on earlier versions of iOS.
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKIncludeStatusBarInSize includeStatusBarInSize;
|
||||
@property (nonatomic, assign) FBSDKIncludeStatusBarInSize includeStatusBarInSize
|
||||
NS_SWIFT_NAME(statusBarSizeInclude);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Indicates whether the user has closed the view by clicking the close button.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL closed;
|
||||
@property (nonatomic, assign, getter=isClosed) BOOL closed;
|
||||
|
||||
@end
|
||||
|
||||
+1
-6
@@ -63,7 +63,7 @@ static const CGFloat FBSDKCloseButtonHeight = 12.0;
|
||||
|
||||
- (void)commonInit {
|
||||
// Initialization code
|
||||
_includeStatusBarInSize = FBSDKIncludeStatusBarInSizeIOS7AndLater;
|
||||
_includeStatusBarInSize = FBSDKIncludeStatusBarInSizeAlways;
|
||||
|
||||
// iOS 7 system blue color
|
||||
self.backgroundColor = [UIColor colorWithRed:0.0f green:122.0f / 255.0f blue:1.0f alpha:1.0f];
|
||||
@@ -151,11 +151,6 @@ static const CGFloat FBSDKCloseButtonHeight = 12.0;
|
||||
case FBSDKIncludeStatusBarInSizeAlways:
|
||||
include = YES;
|
||||
break;
|
||||
case FBSDKIncludeStatusBarInSizeIOS7AndLater: {
|
||||
float systemVersion = [UIDevice currentDevice].systemVersion.floatValue;
|
||||
include = (systemVersion >= 7.0);
|
||||
break;
|
||||
}
|
||||
case FBSDKIncludeStatusBarInSizeNever:
|
||||
include = NO;
|
||||
break;
|
||||
+13
-8
@@ -20,24 +20,29 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
/**
|
||||
Represents a target defined in App Link metadata, consisting of at least
|
||||
a URL, and optionally an App Store ID and name.
|
||||
*/
|
||||
NS_SWIFT_NAME(AppLinkTarget)
|
||||
@interface FBSDKAppLinkTarget : NSObject
|
||||
|
||||
/*! Creates a FBSDKAppLinkTarget with the given app site and target URL. */
|
||||
+ (instancetype)appLinkTargetWithURL:(NSURL *)url
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/** Creates a FBSDKAppLinkTarget with the given app site and target URL. */
|
||||
+ (instancetype)appLinkTargetWithURL:(nullable NSURL *)url
|
||||
appStoreId:(nullable NSString *)appStoreId
|
||||
appName:(NSString *)appName;
|
||||
appName:(NSString *)appName
|
||||
NS_SWIFT_NAME(init(url:appStoreId:appName:));
|
||||
|
||||
/*! The URL prefix for this app link target */
|
||||
@property (nonatomic, strong, readonly) NSURL *URL;
|
||||
/** The URL prefix for this app link target */
|
||||
@property (nonatomic, strong, readonly, nullable) NSURL *URL;
|
||||
|
||||
/*! The app ID for the app store */
|
||||
/** The app ID for the app store */
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *appStoreId;
|
||||
|
||||
/*! The name of the app */
|
||||
/** The name of the app */
|
||||
@property (nonatomic, copy, readonly) NSString *appName;
|
||||
|
||||
@end
|
||||
File renamed without changes.
+13
-22
@@ -18,6 +18,8 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Describes the callback for fetchDeferredAppLink.
|
||||
@param url the url representing the deferred App Link
|
||||
@@ -27,21 +29,19 @@
|
||||
The url may also have a fb_click_time_utc query parameter that
|
||||
represents when the click occurred that caused the deferred App Link to be created.
|
||||
*/
|
||||
typedef void (^FBSDKDeferredAppLinkHandler)(NSURL *url, NSError *error);
|
||||
|
||||
|
||||
/**
|
||||
Describes the callback for fetchOrganicDeferredAppLink.
|
||||
@param url the url representing the deferred App Link
|
||||
*/
|
||||
typedef void (^FBSDKDeferredAppInviteHandler)(NSURL *url);
|
||||
typedef void (^FBSDKURLBlock)(NSURL *_Nullable url, NSError *_Nullable error)
|
||||
NS_SWIFT_NAME(URLBlock);
|
||||
|
||||
|
||||
/**
|
||||
Class containing App Links related utility methods.
|
||||
*/
|
||||
NS_SWIFT_NAME(AppLinkUtility)
|
||||
@interface FBSDKAppLinkUtility : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Call this method from the main thread to fetch deferred applink data if you use Mobile App
|
||||
Engagement Ads (https://developers.facebook.com/docs/ads-for-apps/mobile-app-ads-engagement).
|
||||
@@ -59,21 +59,10 @@ typedef void (^FBSDKDeferredAppInviteHandler)(NSURL *url);
|
||||
been processed (e.g., you should call this method from your application delegate's
|
||||
applicationDidBecomeActive:).
|
||||
*/
|
||||
+ (void)fetchDeferredAppLink:(FBSDKDeferredAppLinkHandler)handler;
|
||||
|
||||
/**
|
||||
|
||||
@warning This method is no longer available and will always return NO.
|
||||
*/
|
||||
+ (BOOL)fetchDeferredAppInvite:(FBSDKDeferredAppInviteHandler)handler
|
||||
DEPRECATED_MSG_ATTRIBUTE("This method is no longer available.");
|
||||
+ (void)fetchDeferredAppLink:(nullable FBSDKURLBlock)handler;
|
||||
|
||||
/*
|
||||
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.
|
||||
Call this method to fetch promotion code from the url, if it's present.
|
||||
|
||||
@param url App Link url that was passed to the app.
|
||||
|
||||
@@ -84,6 +73,8 @@ DEPRECATED_MSG_ATTRIBUTE("This method is no longer available.");
|
||||
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;
|
||||
+ (nullable NSString *)appInvitePromotionCodeFromURL:(NSURL *)url;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+6
-12
@@ -18,12 +18,11 @@
|
||||
|
||||
#import "FBSDKAppLinkUtility.h"
|
||||
|
||||
#import <Bolts/BFURL.h>
|
||||
|
||||
#import "FBSDKAppEventsUtility.h"
|
||||
#import "FBSDKGraphRequest.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKSettings.h"
|
||||
#import "FBSDKURL.h"
|
||||
#import "FBSDKUtility.h"
|
||||
|
||||
static NSString *const FBSDKLastDeferredAppLink = @"com.facebook.sdk:lastDeferredAppLink%@";
|
||||
@@ -31,7 +30,7 @@ static NSString *const FBSDKDeferredAppLinkEvent = @"DEFERRED_APP_LINK";
|
||||
|
||||
@implementation FBSDKAppLinkUtility {}
|
||||
|
||||
+ (void)fetchDeferredAppLink:(FBSDKDeferredAppLinkHandler)handler
|
||||
+ (void)fetchDeferredAppLink:(FBSDKURLBlock)handler
|
||||
{
|
||||
NSAssert([NSThread isMainThread], @"FBSDKAppLink fetchDeferredAppLink: must be invoked from main thread.");
|
||||
|
||||
@@ -49,7 +48,7 @@ static NSString *const FBSDKDeferredAppLinkEvent = @"DEFERRED_APP_LINK";
|
||||
parameters:deferredAppLinkParameters
|
||||
tokenString:nil
|
||||
version:nil
|
||||
HTTPMethod:@"POST"];
|
||||
HTTPMethod:FBSDKHTTPMethodPOST];
|
||||
|
||||
[deferredAppLinkRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
|
||||
id result,
|
||||
@@ -80,14 +79,9 @@ static NSString *const FBSDKDeferredAppLinkEvent = @"DEFERRED_APP_LINK";
|
||||
}];
|
||||
}
|
||||
|
||||
+ (BOOL)fetchDeferredAppInvite:(FBSDKDeferredAppInviteHandler)handler
|
||||
+ (NSString *)appInvitePromotionCodeFromURL:(NSURL *)url
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString*)appInvitePromotionCodeFromURL:(NSURL*)url;
|
||||
{
|
||||
BFURL *parsedUrl = [[FBSDKInternalUtility resolveBoltsClassWithName:@"BFURL"] URLWithURL:url];
|
||||
FBSDKURL *parsedUrl = [FBSDKURL URLWithURL:url];
|
||||
NSDictionary *extras = parsedUrl.appLinkExtras;
|
||||
if (extras) {
|
||||
NSString *deeplinkContextString = extras[@"deeplink_context"];
|
||||
@@ -95,7 +89,7 @@ static NSString *const FBSDKDeferredAppLinkEvent = @"DEFERRED_APP_LINK";
|
||||
// Parse deeplinkContext and extract promo code
|
||||
if (deeplinkContextString.length > 0) {
|
||||
NSError *error = nil;
|
||||
NSDictionary *deeplinkContextData = [FBSDKInternalUtility objectForJSONString:deeplinkContextString error:&error];
|
||||
NSDictionary<id, id> *deeplinkContextData = [FBSDKBasicUtility objectForJSONString:deeplinkContextString error:&error];
|
||||
if (!error && [deeplinkContextData isKindOfClass:[NSDictionary class]]) {
|
||||
return deeplinkContextData[@"promo_code"];
|
||||
}
|
||||
+6
-4
@@ -22,16 +22,18 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
A reference implementation for an App Link resolver that uses a hidden UIWebView
|
||||
/**
|
||||
A reference implementation for an App Link resolver that uses a hidden WKWebView
|
||||
to parse the HTML containing App Link metadata.
|
||||
*/
|
||||
NS_SWIFT_NAME(WebViewAppLinkResolver)
|
||||
@interface FBSDKWebViewAppLinkResolver : NSObject <FBSDKAppLinkResolving>
|
||||
|
||||
/*!
|
||||
/**
|
||||
Gets the instance of a FBSDKWebViewAppLinkResolver.
|
||||
*/
|
||||
+ (instancetype)sharedInstance;
|
||||
@property (class, nonatomic, readonly, strong) FBSDKWebViewAppLinkResolver *sharedInstance
|
||||
NS_SWIFT_NAME(shared);
|
||||
|
||||
@end
|
||||
|
||||
+63
-48
@@ -19,6 +19,7 @@
|
||||
#import "FBSDKWebViewAppLinkResolver.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
#import "FBSDKAppLink.h"
|
||||
#import "FBSDKAppLinkTarget.h"
|
||||
@@ -29,7 +30,8 @@
|
||||
@param error the error during the request, if any
|
||||
|
||||
*/
|
||||
typedef void (^FBSDKURLFollowRedirectsHandler)(NSDictionary<NSString *, id> *result, NSError * _Nullable error);
|
||||
typedef void (^FBSDKURLFollowRedirectsBlock)(NSDictionary<NSString *, id> *result, NSError * _Nullable error)
|
||||
NS_SWIFT_NAME(URLFollowRedirectsBlock);
|
||||
|
||||
// Defines JavaScript to extract app link tags from HTML content
|
||||
static NSString *const FBSDKWebViewAppLinkResolverTagExtractionJavaScript = @""
|
||||
@@ -61,40 +63,39 @@ static NSString *const FBSDKWebViewAppLinkResolverIPadKey = @"ipad";
|
||||
static NSString *const FBSDKWebViewAppLinkResolverWebURLKey = @"url";
|
||||
static NSString *const FBSDKWebViewAppLinkResolverShouldFallbackKey = @"should_fallback";
|
||||
|
||||
@interface FBSDKWebViewAppLinkResolverWebViewDelegate : NSObject <UIWebViewDelegate>
|
||||
@interface FBSDKWebViewAppLinkResolverWebViewDelegate : NSObject <WKNavigationDelegate>
|
||||
|
||||
@property (nonatomic, copy) void (^didFinishLoad)(UIWebView *webView);
|
||||
@property (nonatomic, copy) void (^didFailLoadWithError)(UIWebView *webView, NSError *error);
|
||||
@property (nonatomic, copy) void (^didFinishLoad)(WKWebView *webView);
|
||||
@property (nonatomic, copy) void (^didFailLoadWithError)(WKWebView *webView, NSError *error);
|
||||
@property (nonatomic, assign) BOOL hasLoaded;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBSDKWebViewAppLinkResolverWebViewDelegate
|
||||
|
||||
- (void)webViewDidFinishLoad:(UIWebView *)webView {
|
||||
if (self.didFinishLoad) {
|
||||
self.didFinishLoad(webView);
|
||||
}
|
||||
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
|
||||
{
|
||||
if (self.didFinishLoad) {
|
||||
self.didFinishLoad(webView);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webViewDidStartLoad:(UIWebView *)webView {
|
||||
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
|
||||
{
|
||||
if (self.didFailLoadWithError) {
|
||||
self.didFailLoadWithError(webView, error);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
|
||||
if (self.didFailLoadWithError) {
|
||||
self.didFailLoadWithError(webView, error);
|
||||
}
|
||||
}
|
||||
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
||||
{
|
||||
if (self.hasLoaded) {
|
||||
self.didFinishLoad(webView);
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
}
|
||||
|
||||
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
|
||||
if (self.hasLoaded) {
|
||||
// Consider loading a second resource to be "success", since it indicates an inner frame
|
||||
// or redirect is happening. We can run the tag extraction script at this point.
|
||||
self.didFinishLoad(webView);
|
||||
return NO;
|
||||
}
|
||||
self.hasLoaded = YES;
|
||||
return YES;
|
||||
self.hasLoaded = YES;
|
||||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -110,7 +111,7 @@ static NSString *const FBSDKWebViewAppLinkResolverShouldFallbackKey = @"should_f
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (void)followRedirects:(NSURL *)url handler:(FBSDKURLFollowRedirectsHandler)handler
|
||||
- (void)followRedirects:(NSURL *)url handler:(FBSDKURLFollowRedirectsBlock)handler
|
||||
{
|
||||
// This task will be resolved with either the redirect NSURL
|
||||
// or a dictionary with the response data to be returned.
|
||||
@@ -145,7 +146,7 @@ static NSString *const FBSDKWebViewAppLinkResolverShouldFallbackKey = @"should_f
|
||||
}] resume];
|
||||
}
|
||||
|
||||
- (void)appLinkFromURL:(NSURL *)url handler:(FBSDKAppLinkFromURLHandler)handler
|
||||
- (void)appLinkFromURL:(NSURL *)url handler:(FBSDKAppLinkBlock)handler
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self followRedirects:url handler:^(NSDictionary<NSString *,id> *result, NSError * _Nullable error) {
|
||||
@@ -158,32 +159,41 @@ static NSString *const FBSDKWebViewAppLinkResolverShouldFallbackKey = @"should_f
|
||||
NSData *responseData = result[@"data"];
|
||||
NSHTTPURLResponse *response = result[@"response"];
|
||||
|
||||
UIWebView *webView = [[UIWebView alloc] init];
|
||||
WKWebView *webView = [[WKWebView alloc] init];
|
||||
|
||||
FBSDKWebViewAppLinkResolverWebViewDelegate *listener = [[FBSDKWebViewAppLinkResolverWebViewDelegate alloc] init];
|
||||
__block FBSDKWebViewAppLinkResolverWebViewDelegate *retainedListener = listener;
|
||||
listener.didFinishLoad = ^(UIWebView *view) {
|
||||
listener.didFinishLoad = ^(WKWebView *view) {
|
||||
if (retainedListener) {
|
||||
NSDictionary<NSString *, id> *ogData = [self getALDataFromLoadedPage:view];
|
||||
[view removeFromSuperview];
|
||||
view.delegate = nil;
|
||||
retainedListener = nil;
|
||||
handler([self appLinkFromALData:ogData destination:url], nil);
|
||||
[self getALDataFromLoadedPage:view handler:^(NSDictionary<NSString *,id> *ogData) {
|
||||
[view removeFromSuperview];
|
||||
view.navigationDelegate = nil;
|
||||
retainedListener = nil;
|
||||
handler([self appLinkFromALData:ogData destination:url], nil);
|
||||
}];
|
||||
}
|
||||
};
|
||||
listener.didFailLoadWithError = ^(UIWebView* view, NSError *loadError) {
|
||||
listener.didFailLoadWithError = ^(WKWebView *view, NSError *loadError) {
|
||||
if (retainedListener) {
|
||||
[view removeFromSuperview];
|
||||
view.delegate = nil;
|
||||
view.navigationDelegate = nil;
|
||||
retainedListener = nil;
|
||||
handler(nil, loadError);
|
||||
}
|
||||
};
|
||||
webView.delegate = listener;
|
||||
webView.navigationDelegate = listener;
|
||||
webView.hidden = YES;
|
||||
[webView loadData:responseData
|
||||
MIMEType:response.MIMEType
|
||||
textEncodingName:response.textEncodingName
|
||||
baseURL:response.URL];
|
||||
if (@available(iOS 9.0, *)) {
|
||||
[webView loadData:responseData
|
||||
MIMEType:response.MIMEType
|
||||
characterEncodingName:response.textEncodingName
|
||||
baseURL:response.URL];
|
||||
} else {
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
|
||||
[request setValue:FBSDKWebViewAppLinkResolverMetaTagPrefix forHTTPHeaderField:FBSDKWebViewAppLinkResolverPreferHeader];
|
||||
[webView loadRequest:request];
|
||||
}
|
||||
|
||||
UIWindow *window = [UIApplication sharedApplication].windows.firstObject;
|
||||
[window addSubview:webView];
|
||||
}];
|
||||
@@ -227,15 +237,20 @@ static NSString *const FBSDKWebViewAppLinkResolverShouldFallbackKey = @"should_f
|
||||
return al;
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, id> *)getALDataFromLoadedPage:(UIWebView *)webView {
|
||||
// Run some JavaScript in the webview to fetch the meta tags.
|
||||
NSString *jsonString = [webView stringByEvaluatingJavaScriptFromString:FBSDKWebViewAppLinkResolverTagExtractionJavaScript];
|
||||
NSError *error = nil;
|
||||
NSArray<NSDictionary<NSString *, id> *> *arr =
|
||||
[NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:0
|
||||
error:&error];
|
||||
return [self parseALData:arr];
|
||||
- (void)getALDataFromLoadedPage:(WKWebView *)webView
|
||||
handler:(void (^)(NSDictionary<NSString *, id> *))handler
|
||||
{
|
||||
// Run some JavaScript in the webview to fetch the meta tags.
|
||||
[webView evaluateJavaScript:FBSDKWebViewAppLinkResolverTagExtractionJavaScript
|
||||
completionHandler:^(id _Nullable evaluateResult, NSError * _Nullable error) {
|
||||
NSString *jsonString = [evaluateResult isKindOfClass:[NSString class]] ? evaluateResult : nil;
|
||||
error = nil;
|
||||
NSArray<NSDictionary<NSString *, id> *> *arr =
|
||||
[NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:0
|
||||
error:&error];
|
||||
handler([self parseALData:arr]);
|
||||
}];
|
||||
}
|
||||
|
||||
/*
|
||||
+7
-5
@@ -18,12 +18,14 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FBSDKAccessTokenCaching.h"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKTokenInformationUUIDKey;
|
||||
NS_SWIFT_NAME(MeasurementEventListener)
|
||||
@interface FBSDKMeasurementEventListener : NSObject
|
||||
|
||||
@interface FBSDKAccessTokenCacheV3 : NSObject<FBSDKAccessTokenCaching>
|
||||
|
||||
+ (FBSDKAccessToken *)accessTokenForV3Dictionary:(NSDictionary *)dictionary;
|
||||
@property (class, nonatomic, strong, readonly) FBSDKMeasurementEventListener *defaultListener
|
||||
NS_SWIFT_NAME(default);
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+16
-17
@@ -16,37 +16,37 @@
|
||||
// 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 "FBSDKBoltsMeasurementEventListener.h"
|
||||
#import "FBSDKMeasurementEventListener.h"
|
||||
|
||||
#import "FBSDKAppEvents+Internal.h"
|
||||
#import "FBSDKTimeSpentData.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
static NSNotificationName const BoltsMeasurementEventNotification = @"com.parse.bolts.measurement_event";
|
||||
static NSNotificationName const FBSDKMeasurementEventNotification = @"com.facebook.facebook-objc-sdk.measurement_event";
|
||||
|
||||
#else
|
||||
|
||||
static NSString *const BoltsMeasurementEventNotification = @"com.parse.bolts.measurement_event";
|
||||
static NSString *const FBSDKMeasurementEventNotification = @"com.facebook.facebook-objc-sdk.measurement_event";
|
||||
|
||||
#endif
|
||||
|
||||
static NSString *const BoltsMeasurementEventName = @"event_name";
|
||||
static NSString *const BoltsMeasurementEventArgs = @"event_args";
|
||||
static NSString *const BoltsMeasurementEventPrefix = @"bf_";
|
||||
static NSString *const FBSDKMeasurementEventName = @"event_name";
|
||||
static NSString *const FBSDKMeasurementEventArgs = @"event_args";
|
||||
static NSString *const FBSDKMeasurementEventPrefix = @"bf_";
|
||||
|
||||
@implementation FBSDKBoltsMeasurementEventListener
|
||||
@implementation FBSDKMeasurementEventListener
|
||||
|
||||
+ (instancetype)defaultListener
|
||||
{
|
||||
static dispatch_once_t dispatchOnceLocker = 0;
|
||||
static FBSDKBoltsMeasurementEventListener *defaultListener = nil;
|
||||
static FBSDKMeasurementEventListener *defaultListener = nil;
|
||||
dispatch_once(&dispatchOnceLocker, ^{
|
||||
defaultListener = [[self alloc] init];
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:defaultListener
|
||||
selector:@selector(logFBAppEventForNotification:)
|
||||
name:BoltsMeasurementEventNotification
|
||||
name:FBSDKMeasurementEventNotification
|
||||
object:nil];
|
||||
});
|
||||
return defaultListener;
|
||||
@@ -55,15 +55,15 @@ static NSString *const BoltsMeasurementEventPrefix = @"bf_";
|
||||
- (void)logFBAppEventForNotification:(NSNotification *)note
|
||||
{
|
||||
// when catch al_nav_in event, we set source application for FBAppEvents.
|
||||
if ([note.userInfo[BoltsMeasurementEventName] isEqualToString:@"al_nav_in"]) {
|
||||
NSString *sourceApplication = note.userInfo[BoltsMeasurementEventArgs][@"sourceApplication"];
|
||||
if ([note.userInfo[FBSDKMeasurementEventName] isEqualToString:@"al_nav_in"]) {
|
||||
NSString *sourceApplication = note.userInfo[FBSDKMeasurementEventArgs][@"sourceApplication"];
|
||||
if (sourceApplication) {
|
||||
[FBSDKTimeSpentData setSourceApplication:sourceApplication isFromAppLink:YES];
|
||||
}
|
||||
}
|
||||
NSDictionary *eventArgs = note.userInfo[BoltsMeasurementEventArgs];
|
||||
NSMutableDictionary *logData = [[NSMutableDictionary alloc] init];
|
||||
for(NSString *key in eventArgs.allKeys) {
|
||||
NSDictionary<NSString *, id> *eventArgs = note.userInfo[FBSDKMeasurementEventArgs];
|
||||
NSMutableDictionary<NSString *, id> *logData = [[NSMutableDictionary alloc] init];
|
||||
for (NSString *key in eventArgs.allKeys) {
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^0-9a-zA-Z _-]" options:0 error:&error];
|
||||
NSString *safeKey = [regex stringByReplacingMatchesInString:key
|
||||
@@ -73,10 +73,9 @@ static NSString *const BoltsMeasurementEventPrefix = @"bf_";
|
||||
safeKey = [safeKey stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -"]];
|
||||
logData[safeKey] = eventArgs[key];
|
||||
}
|
||||
[FBSDKAppEvents logImplicitEvent:[BoltsMeasurementEventPrefix stringByAppendingString:note.userInfo[BoltsMeasurementEventName]]
|
||||
valueToSum:nil
|
||||
[FBSDKAppEvents logInternalEvent:[FBSDKMeasurementEventPrefix stringByAppendingString:note.userInfo[FBSDKMeasurementEventName]]
|
||||
parameters:logData
|
||||
accessToken:nil];
|
||||
isImplicitlyLogged:YES];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
// 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 "FBSDKCrashObserving.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface FBSDKCrashHandler : NSObject
|
||||
|
||||
+ (void)disable;
|
||||
+ (void)addObserver:(id<FBSDKCrashObserving>)observer;
|
||||
+ (void)removeObserver:(id<FBSDKCrashObserving>)observer;
|
||||
+ (void)clearCrashReportFiles;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+322
@@ -0,0 +1,322 @@
|
||||
// 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 "FBSDKCrashHandler.h"
|
||||
|
||||
#import <sys/utsname.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "FBSDKLibAnalyzer.h"
|
||||
|
||||
#define FBSDK_MAX_CRASH_LOGS 5
|
||||
#define FBSDK_CRASH_PATH_NAME @"instrument"
|
||||
|
||||
static NSUncaughtExceptionHandler *previousExceptionHandler = NULL;
|
||||
static NSString *mappingTableIdentifier = NULL;
|
||||
static NSString *directoryPath;
|
||||
|
||||
NSString *const kFBSDKAppVersion = @"app_version";
|
||||
NSString *const kFBSDKCallstack = @"callstack";
|
||||
NSString *const kFBSDKCrashReason = @"reason";
|
||||
NSString *const kFBSDKCrashTimestamp = @"timestamp";
|
||||
NSString *const kFBSDKDeviceModel = @"device_model";
|
||||
NSString *const kFBSDKDeviceOSVersion = @"device_os_version";
|
||||
|
||||
NSString *const kFBSDKMapingTable = @"mapping_table";
|
||||
NSString *const kFBSDKMappingTableIdentifier = @"mapping_table_identifier";
|
||||
|
||||
@implementation FBSDKCrashHandler
|
||||
|
||||
static NSHashTable<id<FBSDKCrashObserving>> *_observers;
|
||||
static NSArray<NSDictionary<NSString *, id> *> *_processedCrashLogs;
|
||||
static BOOL _isTurnedOff;
|
||||
|
||||
# pragma mark - Class Methods
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
NSString *dirPath = [NSTemporaryDirectory() stringByAppendingPathComponent:FBSDK_CRASH_PATH_NAME];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:dirPath]) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:NO attributes:NULL error:NULL];
|
||||
}
|
||||
directoryPath = dirPath;
|
||||
NSString *identifier = [[NSUUID UUID] UUIDString];
|
||||
mappingTableIdentifier = [identifier stringByReplacingOccurrencesOfString:@"-" withString:@""];
|
||||
_observers = [[NSHashTable alloc] init];
|
||||
}
|
||||
|
||||
+ (void)sendCrashLogs
|
||||
{
|
||||
NSArray<id<FBSDKCrashObserving>> *observers = [_observers copy];
|
||||
for (id<FBSDKCrashObserving> observer in observers) {
|
||||
if (observer && [observer respondsToSelector:@selector(didReceiveCrashLogs:)]) {
|
||||
NSArray<NSDictionary<NSString *, id> *> *filteredCrashLogs = [self filterCrashLogs:observer.prefixes];
|
||||
[observer didReceiveCrashLogs:filteredCrashLogs];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSArray<NSDictionary<NSString *, id> *> *)filterCrashLogs:(NSArray<NSString *> *)prefixList
|
||||
{
|
||||
NSMutableArray<NSDictionary<NSString *, id> *> *crashLogs = [NSMutableArray array];
|
||||
for (NSDictionary<NSString *, id> *crashLog in _processedCrashLogs) {
|
||||
NSArray<NSString *> *callstack = crashLog[kFBSDKCallstack];
|
||||
if ([self callstack:callstack containsPrefix:prefixList]) {
|
||||
[crashLogs addObject:crashLog];
|
||||
}
|
||||
}
|
||||
return crashLogs;
|
||||
}
|
||||
|
||||
+ (BOOL)callstack:(NSArray<NSString *> *)callstack
|
||||
containsPrefix:(NSArray<NSString *> *)prefixList
|
||||
{
|
||||
NSString *callStackString = [callstack componentsJoinedByString:@""];
|
||||
for (NSString *prefix in prefixList) {
|
||||
if ([callStackString containsString:prefix]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (void)disable
|
||||
{
|
||||
_isTurnedOff = YES;
|
||||
[FBSDKCrashHandler uninstallExceptionsHandler];
|
||||
_observers = nil;
|
||||
}
|
||||
|
||||
+ (void)addObserver:(id<FBSDKCrashObserving>)observer
|
||||
{
|
||||
if (_isTurnedOff || ![self isSafeToGenerateMapping]) {
|
||||
return;
|
||||
}
|
||||
static dispatch_once_t onceToken = 0;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[FBSDKCrashHandler installExceptionsHandler];
|
||||
_processedCrashLogs = [self getProcessedCrashLogs];
|
||||
});
|
||||
if (![_observers containsObject:observer]) {
|
||||
[_observers addObject:observer];
|
||||
[self generateMethodMapping:observer];
|
||||
[self sendCrashLogs];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)removeObserver:(id<FBSDKCrashObserving>)observer
|
||||
{
|
||||
if ([_observers containsObject:observer]) {
|
||||
[_observers removeObject:observer];
|
||||
if (_observers.count == 0) {
|
||||
[FBSDKCrashHandler uninstallExceptionsHandler];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# pragma mark handler function
|
||||
|
||||
+ (void)installExceptionsHandler
|
||||
{
|
||||
NSUncaughtExceptionHandler *currentHandler = NSGetUncaughtExceptionHandler();
|
||||
|
||||
if (currentHandler != FBSDKExceptionHandler) {
|
||||
previousExceptionHandler = currentHandler;
|
||||
NSSetUncaughtExceptionHandler(&FBSDKExceptionHandler);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)uninstallExceptionsHandler
|
||||
{
|
||||
NSSetUncaughtExceptionHandler(previousExceptionHandler);
|
||||
previousExceptionHandler = nil;
|
||||
}
|
||||
|
||||
static void FBSDKExceptionHandler(NSException *exception)
|
||||
{
|
||||
[FBSDKCrashHandler saveException:exception];
|
||||
if (previousExceptionHandler) {
|
||||
previousExceptionHandler(exception);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Storage
|
||||
|
||||
+ (void)saveException:(NSException *)exception
|
||||
{
|
||||
if (exception.callStackSymbols && exception.name) {
|
||||
NSArray<NSString *> *stackSymbols = [NSArray arrayWithArray:exception.callStackSymbols];
|
||||
[self saveCrashLog:@{
|
||||
kFBSDKCallstack : stackSymbols,
|
||||
kFBSDKCrashReason : exception.name,
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)saveSignal:(int)signal withCallStack:(NSArray<NSString *> *)callStack
|
||||
{
|
||||
if (callStack) {
|
||||
NSString *signalDescription = [NSString stringWithCString:strsignal(signal) encoding:NSUTF8StringEncoding] ?: [NSString stringWithFormat:@"SIGNUM(%i)", signal];
|
||||
[self saveCrashLog:@{
|
||||
kFBSDKCallstack : callStack,
|
||||
kFBSDKCrashReason : signalDescription,
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSArray<NSDictionary<NSString *, id> *> *)getProcessedCrashLogs
|
||||
{
|
||||
NSArray<NSDictionary<NSString *, id> *> *crashLogs = [self loadCrashLogs];
|
||||
if (0 == crashLogs.count) {
|
||||
[self clearCrashReportFiles];
|
||||
return nil;
|
||||
}
|
||||
NSMutableArray<NSDictionary<NSString *, id> *> *processedCrashLogs = [NSMutableArray array];
|
||||
|
||||
for (NSDictionary<NSString *, id> *crashLog in crashLogs) {
|
||||
NSArray<NSString *> *callstack = crashLog[kFBSDKCallstack];
|
||||
NSDictionary<NSString *, id> *methodMapping = [self loadLibData:crashLog];
|
||||
NSArray<NSString *> *symbolicatedCallstack = [FBSDKLibAnalyzer symbolicateCallstack:callstack methodMapping:methodMapping];
|
||||
NSMutableDictionary<NSString *, id> *symbolicatedCrashLog = [NSMutableDictionary dictionaryWithDictionary:crashLog];
|
||||
if (symbolicatedCallstack) {
|
||||
[symbolicatedCrashLog setObject:symbolicatedCallstack forKey:kFBSDKCallstack];
|
||||
[symbolicatedCrashLog removeObjectForKey:kFBSDKMappingTableIdentifier];
|
||||
[processedCrashLogs addObject:symbolicatedCrashLog];
|
||||
}
|
||||
}
|
||||
return processedCrashLogs;
|
||||
}
|
||||
|
||||
+ (NSArray<NSDictionary<NSString *, id> *> *)loadCrashLogs
|
||||
{
|
||||
NSArray<NSString *> *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:NULL];
|
||||
NSArray<NSString *> *fileNames = [[self getCrashLogFileNames:files] sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2){
|
||||
return [obj2 compare:obj1];
|
||||
}];
|
||||
NSMutableArray<NSDictionary<NSString *, id> *> *crashLogArray = [NSMutableArray array];
|
||||
|
||||
for (NSUInteger i = 0; i < MIN(fileNames.count, FBSDK_MAX_CRASH_LOGS); i++) {
|
||||
NSDictionary<NSString *, id> *crashLog = [self loadCrashLog:fileNames[i]];
|
||||
[crashLogArray addObject:crashLog];
|
||||
}
|
||||
return [crashLogArray copy];
|
||||
}
|
||||
|
||||
+ (NSDictionary<NSString *,id> *)loadCrashLog:(NSString *)fileName
|
||||
{
|
||||
return [NSDictionary dictionaryWithContentsOfFile:[directoryPath stringByAppendingPathComponent:fileName]];
|
||||
}
|
||||
|
||||
+ (void)clearCrashReportFiles
|
||||
{
|
||||
NSArray<NSString *> *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:nil];
|
||||
|
||||
for (NSUInteger i = 0; i < files.count; i++) {
|
||||
// remove all crash related files except for the current mapping table
|
||||
if ([files[i] hasPrefix:@"crash_"] && ![files[i] containsString:mappingTableIdentifier]) {
|
||||
[[NSFileManager defaultManager] removeItemAtPath:[directoryPath stringByAppendingPathComponent:files[i]] error:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)getCrashLogFileNames:(NSArray<NSString *> *)files
|
||||
{
|
||||
NSMutableArray<NSString *> *fileNames = [NSMutableArray array];
|
||||
|
||||
for (NSString *fileName in files) {
|
||||
if ([fileName hasPrefix:@"crash_log_"] && [fileName hasSuffix:@".json"]) {
|
||||
[fileNames addObject:fileName];
|
||||
}
|
||||
}
|
||||
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
+ (void)saveCrashLog:(NSDictionary<NSString *, id> *)crashLog
|
||||
{
|
||||
NSMutableDictionary<NSString *, id> *completeCrashLog = [NSMutableDictionary dictionaryWithDictionary:crashLog];
|
||||
NSString *currentTimestamp = [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]];
|
||||
|
||||
[completeCrashLog setObject:currentTimestamp forKey:kFBSDKCrashTimestamp];
|
||||
[completeCrashLog setObject:mappingTableIdentifier forKey:kFBSDKMappingTableIdentifier];
|
||||
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSString *version = [mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
|
||||
NSString *build = [mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
|
||||
[completeCrashLog setObject:[NSString stringWithFormat:@"%@(%@)", version, build] forKey:kFBSDKAppVersion];
|
||||
|
||||
struct utsname systemInfo;
|
||||
uname(&systemInfo);
|
||||
[completeCrashLog setObject:@(systemInfo.machine) forKey:kFBSDKDeviceModel];
|
||||
|
||||
[completeCrashLog setObject:[UIDevice currentDevice].systemVersion forKey:kFBSDKDeviceOSVersion];
|
||||
|
||||
[completeCrashLog writeToFile:[self getPathToCrashFile:currentTimestamp]
|
||||
atomically:YES];
|
||||
}
|
||||
|
||||
+ (void)generateMethodMapping:(id<FBSDKCrashObserving>)observer
|
||||
{
|
||||
if (observer.prefixes.count == 0) {
|
||||
return;
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:mappingTableIdentifier forKey:kFBSDKMappingTableIdentifier];
|
||||
NSDictionary<NSString *, NSString *> *methodMapping = [FBSDKLibAnalyzer getMethodsTable:observer.prefixes
|
||||
frameworks:observer.frameworks];
|
||||
if (methodMapping.count > 0){
|
||||
[methodMapping writeToFile:[self getPathToLibDataFile:mappingTableIdentifier]
|
||||
atomically:YES];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSDictionary<NSString *, id> *)loadLibData:(NSDictionary<NSString *, id> *)crashLog
|
||||
{
|
||||
NSString *identifier = [crashLog objectForKey:kFBSDKMappingTableIdentifier];
|
||||
return [NSDictionary dictionaryWithContentsOfFile:[self getPathToLibDataFile:identifier]];
|
||||
}
|
||||
|
||||
+ (NSString *)getPathToCrashFile:(NSString *)timestamp
|
||||
{
|
||||
return [directoryPath stringByAppendingPathComponent:
|
||||
[NSString stringWithFormat:@"crash_log_%@.json", timestamp]];
|
||||
}
|
||||
|
||||
+ (NSString *)getPathToLibDataFile:(NSString *)identifier
|
||||
{
|
||||
return [directoryPath stringByAppendingPathComponent:
|
||||
[NSString stringWithFormat:@"crash_lib_data_%@.json", identifier]];
|
||||
|
||||
}
|
||||
|
||||
+ (BOOL)isSafeToGenerateMapping
|
||||
{
|
||||
#if TARGET_OS_SIMULATOR
|
||||
return YES;
|
||||
#else
|
||||
NSString *identifier = [[NSUserDefaults standardUserDefaults] objectForKey:kFBSDKMappingTableIdentifier];
|
||||
//first app start
|
||||
if (!identifier) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
return [[NSFileManager defaultManager] fileExistsAtPath:[self getPathToLibDataFile:identifier]];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
Generated
+34
@@ -0,0 +1,34 @@
|
||||
// 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>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol FBSDKCrashObserving <NSObject>
|
||||
|
||||
@property (nonatomic, copy) NSArray<NSString *> *prefixes;
|
||||
@property (nonatomic, copy, nullable) NSArray<NSString *> *frameworks;
|
||||
|
||||
@optional
|
||||
|
||||
- (void)didReceiveCrashLogs:(NSArray<NSDictionary<NSString *, id> *> *)crashLogs;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// 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>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface FBSDKLibAnalyzer : NSObject
|
||||
|
||||
+ (NSDictionary<NSString *, NSString *> *)getMethodsTable:(NSArray<NSString *> *)prefixes
|
||||
frameworks:(NSArray<NSString *> * _Nullable)frameworks;
|
||||
+ (nullable NSArray<NSString *> *)symbolicateCallstack:(NSArray<NSString *> *)callstack
|
||||
methodMapping:(NSDictionary<NSString *,id> *)methodMapping;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
// 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 "FBSDKLibAnalyzer.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation FBSDKLibAnalyzer
|
||||
|
||||
static NSMutableDictionary<NSString *, NSString *> *_methodMapping;
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
_methodMapping = [NSMutableDictionary dictionary];
|
||||
}
|
||||
|
||||
+ (NSDictionary<NSString *, NSString *> *)getMethodsTable:(NSArray<NSString *> *)prefixes
|
||||
frameworks:(NSArray<NSString *> *)frameworks
|
||||
{
|
||||
NSArray<NSString *> *allClasses = [self getClassNames:prefixes frameworks:frameworks];
|
||||
for (NSString *className in allClasses) {
|
||||
Class class = NSClassFromString(className);
|
||||
if (class) {
|
||||
[self addClass:class isClassMethod:NO];
|
||||
[self addClass:object_getClass(class) isClassMethod:YES];
|
||||
}
|
||||
}
|
||||
return [_methodMapping copy];
|
||||
}
|
||||
|
||||
#pragma mark - private methods
|
||||
|
||||
+ (NSArray<NSString *> *)getClassNames:(NSArray<NSString *> *)prefixes
|
||||
frameworks:(NSArray<NSString *> *)frameworks
|
||||
{
|
||||
NSMutableArray<NSString *> *classNames = [NSMutableArray new];
|
||||
// from main bundle
|
||||
[classNames addObjectsFromArray:[self getClassesFrom:[[NSBundle mainBundle] executablePath]
|
||||
prefixes:prefixes]];
|
||||
// from dynamic libraries
|
||||
if (frameworks.count > 0) {
|
||||
unsigned int count = 0;
|
||||
const char **images = objc_copyImageNames(&count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
NSString *image = [NSString stringWithUTF8String:images[i]];
|
||||
for (NSString *framework in frameworks) {
|
||||
if ([image containsString:framework]) {
|
||||
[classNames addObjectsFromArray:[self getClassesFrom:image
|
||||
prefixes:nil]];
|
||||
}
|
||||
}
|
||||
}
|
||||
free(images);
|
||||
}
|
||||
|
||||
return [classNames copy];
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)getClassesFrom:(NSString *)image
|
||||
prefixes:(NSArray<NSString *> *)prefixes
|
||||
{
|
||||
NSMutableArray<NSString *> *classNames = [NSMutableArray array];
|
||||
unsigned int count = 0;
|
||||
const char **classes = objc_copyClassNamesForImage([image UTF8String], &count);
|
||||
for (unsigned int i = 0; i < count; i++){
|
||||
NSString *className = [NSString stringWithUTF8String:classes[i]];
|
||||
if (prefixes.count > 0) {
|
||||
for (NSString *prefix in prefixes) {
|
||||
if ([className hasPrefix:prefix]) {
|
||||
[classNames addObject:className];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
[classNames addObject:className];
|
||||
}
|
||||
}
|
||||
free(classes);
|
||||
return [classNames copy];
|
||||
}
|
||||
|
||||
+ (void)addClass:(Class)class
|
||||
isClassMethod:(BOOL)isClassMethod
|
||||
{
|
||||
unsigned int methodsCount = 0;
|
||||
Method *methods = class_copyMethodList(class, &methodsCount);
|
||||
|
||||
NSString *methodType = isClassMethod ? @"+" : @"-";
|
||||
|
||||
for (unsigned int i = 0; i < methodsCount; i++) {
|
||||
Method method = methods[i];
|
||||
|
||||
if (method) {
|
||||
SEL selector = method_getName(method);
|
||||
|
||||
IMP methodImplementation = class_getMethodImplementation(class, selector);
|
||||
NSString *methodAddress = [NSString stringWithFormat:@"0x%010lx", (unsigned long)methodImplementation];
|
||||
NSString *methodName = [NSString stringWithFormat:@"%@[%@ %@]",
|
||||
methodType,
|
||||
NSStringFromClass(class),
|
||||
NSStringFromSelector(selector)];
|
||||
|
||||
if (methodAddress && methodName) {
|
||||
[_methodMapping setObject:methodName forKey:methodAddress];
|
||||
}
|
||||
}
|
||||
}
|
||||
free(methods);
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)symbolicateCallstack:(NSArray<NSString *> *)callstack
|
||||
methodMapping:(NSDictionary<NSString *,id> *)methodMapping
|
||||
{
|
||||
if (!callstack || !methodMapping) {
|
||||
return nil;
|
||||
}
|
||||
NSArray<NSString *> *sortedAllAddress = [methodMapping.allKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
|
||||
return [obj1 compare:obj2];
|
||||
}];
|
||||
|
||||
BOOL containsFBSDKFunction = NO;
|
||||
NSInteger nonSDKMethodCount = 0;
|
||||
NSMutableArray<NSString *> *symbolicatedCallstack = [NSMutableArray array];
|
||||
|
||||
for (NSUInteger i = 0; i < callstack.count; i++){
|
||||
NSString *rawAddress = [self getAddress:callstack[i]];
|
||||
NSString *addressString = [NSString stringWithFormat:@"0x%@",[rawAddress substringWithRange:NSMakeRange(rawAddress.length - 10, 10)]];
|
||||
NSString *methodAddress = [self searchMethod:addressString sortedAllAddress:sortedAllAddress];
|
||||
|
||||
if (methodAddress) {
|
||||
containsFBSDKFunction = YES;
|
||||
nonSDKMethodCount == 0 ?: [symbolicatedCallstack addObject:[NSString stringWithFormat:@"(%ld DEV METHODS)", (long)nonSDKMethodCount]];
|
||||
nonSDKMethodCount = 0;
|
||||
NSString *methodName = [methodMapping objectForKey:methodAddress];
|
||||
[symbolicatedCallstack addObject:[NSString stringWithFormat:@"%@%@", methodName, [self getOffset:addressString secondString:methodAddress]]];
|
||||
} else {
|
||||
nonSDKMethodCount++;
|
||||
}
|
||||
}
|
||||
nonSDKMethodCount == 0 ?: [symbolicatedCallstack addObject:[NSString stringWithFormat:@"(%ld DEV METHODS)", (long)nonSDKMethodCount]];
|
||||
|
||||
return containsFBSDKFunction ? symbolicatedCallstack : nil;
|
||||
}
|
||||
|
||||
+ (NSString *)getAddress:(NSString *)callstackEntry
|
||||
{
|
||||
NSArray<NSString *> *components = [callstackEntry componentsSeparatedByString:@" "];
|
||||
for (NSString *component in components) {
|
||||
if ([component containsString:@"0x"]) {
|
||||
return component;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSString *)getOffset:(NSString *)firstString
|
||||
secondString:(NSString *)secondString
|
||||
{
|
||||
if (!firstString || !secondString) {
|
||||
return nil;
|
||||
}
|
||||
unsigned long long first = 0, second = 0;
|
||||
NSScanner *scanner = [NSScanner scannerWithString:firstString];
|
||||
[scanner scanHexLongLong:&first];
|
||||
|
||||
scanner = [NSScanner scannerWithString:secondString];
|
||||
[scanner scanHexLongLong:&second];
|
||||
|
||||
unsigned long long difference = first - second;
|
||||
return [NSString stringWithFormat:@"+%llu", difference];
|
||||
}
|
||||
|
||||
+ (NSString *)searchMethod:(NSString *)address
|
||||
sortedAllAddress:(NSArray<NSString *> *)sortedAllAddress
|
||||
{
|
||||
if (0 == sortedAllAddress.count) {
|
||||
return nil;
|
||||
}
|
||||
NSString *lowestAddress = sortedAllAddress[0];
|
||||
NSString *highestAddress = sortedAllAddress[sortedAllAddress.count - 1];
|
||||
|
||||
if ([address compare:lowestAddress] == NSOrderedAscending || [address compare:highestAddress] == NSOrderedDescending) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([address compare:lowestAddress] == NSOrderedSame) {
|
||||
return lowestAddress;
|
||||
}
|
||||
|
||||
if ([address compare:highestAddress] == NSOrderedSame) {
|
||||
return highestAddress;
|
||||
}
|
||||
|
||||
NSUInteger index = [sortedAllAddress indexOfObject:address
|
||||
inSortedRange:NSMakeRange(0, sortedAllAddress.count - 1)
|
||||
options:NSBinarySearchingInsertionIndex
|
||||
usingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
|
||||
return [obj1 compare:obj2];
|
||||
}];
|
||||
return sortedAllAddress[index - 1];
|
||||
}
|
||||
|
||||
@end
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
// 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>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Describes the callback for appLinkFromURLInBackground.
|
||||
@param object the FBSDKAppLink representing the deferred App Link
|
||||
@param stop the error during the request, if any
|
||||
|
||||
*/
|
||||
typedef id _Nullable (^FBSDKInvalidObjectHandler)(id object, BOOL *stop)
|
||||
NS_SWIFT_NAME(InvalidObjectHandler);
|
||||
|
||||
@interface FBSDKBasicUtility : NSObject
|
||||
|
||||
/**
|
||||
Converts an object into a JSON string.
|
||||
@param object The object to convert to JSON.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@param invalidObjectHandler Handles objects that are invalid, returning a replacement value or nil to ignore.
|
||||
@return A JSON string or nil if the object cannot be converted to JSON.
|
||||
*/
|
||||
+ (nullable NSString *)JSONStringForObject:(id)object
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
invalidObjectHandler:(nullable FBSDKInvalidObjectHandler)invalidObjectHandler;
|
||||
|
||||
/**
|
||||
Sets an object for a key in a dictionary if it is not nil.
|
||||
@param dictionary The dictionary to set the value for.
|
||||
@param object The value to set.
|
||||
@param key The key to set the value for.
|
||||
*/
|
||||
+ (void)dictionary:(NSMutableDictionary<NSString *, id> *)dictionary
|
||||
setObject:(nullable id)object
|
||||
forKey:(nullable id<NSCopying>)key;
|
||||
|
||||
/**
|
||||
Sets an object for a key in a dictionary if it is not nil.
|
||||
@param dictionary The dictionary to set the value for.
|
||||
@param object The value to set after serializing to JSON.
|
||||
@param key The key to set the value for.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@return NO if an error occurred while serializing the object, otherwise YES.
|
||||
*/
|
||||
+ (BOOL)dictionary:(NSMutableDictionary<id, id> *)dictionary
|
||||
setJSONStringForObject:(id)object
|
||||
forKey:(id<NSCopying>)key
|
||||
error:(NSError *__autoreleasing *)errorRef;
|
||||
|
||||
/**
|
||||
Adds an object to an array if it is not nil.
|
||||
@param array The array to add the object to.
|
||||
@param object The object to add to the array.
|
||||
*/
|
||||
+ (void)array:(NSMutableArray *)array addObject:(nullable id)object;
|
||||
|
||||
/**
|
||||
Converts a JSON string into an object
|
||||
@param string The JSON string to convert.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@return An NSDictionary, NSArray, NSString or NSNumber containing the object representation, or nil if the string
|
||||
cannot be converted.
|
||||
*/
|
||||
+ (nullable id)objectForJSONString:(NSString *)string error:(NSError *__autoreleasing *)errorRef;
|
||||
|
||||
/**
|
||||
Constructs a query string from a dictionary.
|
||||
@param dictionary The dictionary with key/value pairs for the query string.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@param invalidObjectHandler Handles objects that are invalid, returning a replacement value or nil to ignore.
|
||||
@return Query string representation of the parameters.
|
||||
*/
|
||||
+ (NSString *)queryStringWithDictionary:(NSDictionary<NSString *, id> *)dictionary
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
invalidObjectHandler:(nullable FBSDKInvalidObjectHandler)invalidObjectHandler;
|
||||
|
||||
/**
|
||||
Converts simple value types to the string equivalent for serializing to a request query or body.
|
||||
@param value The value to be converted.
|
||||
@return The value that may have been converted if able (otherwise the input param).
|
||||
*/
|
||||
+ (id)convertRequestValue:(id)value;
|
||||
|
||||
/**
|
||||
Encodes a value for an URL.
|
||||
@param value The value to encode.
|
||||
@return The encoded value.
|
||||
*/
|
||||
+ (NSString *)URLEncode:(NSString *)value;
|
||||
|
||||
/**
|
||||
Parses a query string into a dictionary.
|
||||
@param queryString The query string value.
|
||||
@return A dictionary with the key/value pairs.
|
||||
*/
|
||||
+ (NSDictionary<NSString *, NSString *> *)dictionaryWithQueryString:(NSString *)queryString;
|
||||
|
||||
/**
|
||||
Decodes a value from an URL.
|
||||
@param value The value to decode.
|
||||
@return The decoded value.
|
||||
*/
|
||||
+ (NSString *)URLDecode:(NSString *)value;
|
||||
|
||||
/**
|
||||
Gzip data with default compression level if possible.
|
||||
@param data The raw data.
|
||||
@return nil if unable to gzip the data, otherwise gzipped data.
|
||||
*/
|
||||
+ (nullable NSData *)gzip:(NSData *)data;
|
||||
|
||||
+ (NSString *)anonymousID;
|
||||
+ (NSString *)persistenceFilePath:(NSString *)filename;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+341
@@ -0,0 +1,341 @@
|
||||
// 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 "FBSDKBasicUtility.h"
|
||||
|
||||
#import <zlib.h>
|
||||
|
||||
#import "FBSDKTypeUtility.h"
|
||||
|
||||
#define kChunkSize 1024
|
||||
|
||||
static NSString *const FBSDK_BASICUTILITY_ANONYMOUSIDFILENAME = @"com-facebook-sdk-PersistedAnonymousID.json";
|
||||
static NSString *const FBSDK_BASICUTILITY_ANONYMOUSID_KEY = @"anon_id";
|
||||
|
||||
@protocol BASIC_FBSDKError
|
||||
|
||||
+ (NSError *)invalidArgumentErrorWithName:(NSString *)name value:(id)value message:(NSString *)message;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBSDKBasicUtility
|
||||
|
||||
+ (NSString *)JSONStringForObject:(id)object
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
invalidObjectHandler:(FBSDKInvalidObjectHandler)invalidObjectHandler
|
||||
{
|
||||
if (invalidObjectHandler || ![NSJSONSerialization isValidJSONObject:object]) {
|
||||
object = [self _convertObjectToJSONObject:object invalidObjectHandler:invalidObjectHandler stop:NULL];
|
||||
if (![NSJSONSerialization isValidJSONObject:object]) {
|
||||
if (errorRef != NULL) {
|
||||
Class FBSDKErrorClass = NSClassFromString(@"FBSDKError");
|
||||
if ([FBSDKErrorClass respondsToSelector:@selector(invalidArgumentErrorWithName:value:message:)]) {
|
||||
*errorRef = [FBSDKErrorClass invalidArgumentErrorWithName:@"object"
|
||||
value:object
|
||||
message:@"Invalid object for JSON serialization."];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
NSData *data = [NSJSONSerialization dataWithJSONObject:object options:0 error:errorRef];
|
||||
if (!data) {
|
||||
return nil;
|
||||
}
|
||||
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
+ (BOOL)dictionary:(NSMutableDictionary<NSString *, id> *)dictionary
|
||||
setJSONStringForObject:(id)object
|
||||
forKey:(id<NSCopying>)key
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (!object || !key) {
|
||||
return YES;
|
||||
}
|
||||
NSString *JSONString = [self JSONStringForObject:object error:errorRef invalidObjectHandler:NULL];
|
||||
if (!JSONString) {
|
||||
return NO;
|
||||
}
|
||||
[self dictionary:dictionary setObject:JSONString forKey:key];
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (id)_convertObjectToJSONObject:(id)object
|
||||
invalidObjectHandler:(FBSDKInvalidObjectHandler)invalidObjectHandler
|
||||
stop:(BOOL *)stopRef
|
||||
{
|
||||
__block BOOL stop = NO;
|
||||
if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) {
|
||||
// good to go, keep the object
|
||||
} else if ([object isKindOfClass:[NSURL class]]) {
|
||||
object = ((NSURL *)object).absoluteString;
|
||||
} else if ([object isKindOfClass:[NSDictionary class]]) {
|
||||
NSMutableDictionary<NSString *, id> *dictionary = [[NSMutableDictionary alloc] init];
|
||||
[(NSDictionary<id, id> *)object enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *dictionaryStop) {
|
||||
[self dictionary:dictionary
|
||||
setObject:[self _convertObjectToJSONObject:obj invalidObjectHandler:invalidObjectHandler stop:&stop]
|
||||
forKey:[FBSDKTypeUtility stringValue:key]];
|
||||
if (stop) {
|
||||
*dictionaryStop = YES;
|
||||
}
|
||||
}];
|
||||
object = dictionary;
|
||||
} else if ([object isKindOfClass:[NSArray class]]) {
|
||||
NSMutableArray<id> *array = [[NSMutableArray alloc] init];
|
||||
for (id obj in (NSArray *)object) {
|
||||
id convertedObj = [self _convertObjectToJSONObject:obj invalidObjectHandler:invalidObjectHandler stop:&stop];
|
||||
[self array:array addObject:convertedObj];
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
object = array;
|
||||
} else {
|
||||
object = invalidObjectHandler(object, stopRef);
|
||||
}
|
||||
if (stopRef != NULL) {
|
||||
*stopRef = stop;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
+ (void)dictionary:(NSMutableDictionary<NSString *, id> *)dictionary setObject:(id)object forKey:(id<NSCopying>)key
|
||||
{
|
||||
if (object && key) {
|
||||
dictionary[key] = object;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)array:(NSMutableArray *)array addObject:(id)object
|
||||
{
|
||||
if (object) {
|
||||
[array addObject:object];
|
||||
}
|
||||
}
|
||||
|
||||
+ (id)objectForJSONString:(NSString *)string error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
|
||||
if (!data) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
return [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:errorRef];
|
||||
}
|
||||
|
||||
+ (NSString *)queryStringWithDictionary:(NSDictionary<id, id> *)dictionary
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
invalidObjectHandler:(FBSDKInvalidObjectHandler)invalidObjectHandler
|
||||
{
|
||||
NSMutableString *queryString = [[NSMutableString alloc] init];
|
||||
__block BOOL hasParameters = NO;
|
||||
if (dictionary) {
|
||||
NSMutableArray<NSString *> *keys = [dictionary.allKeys mutableCopy];
|
||||
// remove non-string keys, as they are not valid
|
||||
[keys filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary<id, id> *bindings) {
|
||||
return [evaluatedObject isKindOfClass:[NSString class]];
|
||||
}]];
|
||||
// sort the keys so that the query string order is deterministic
|
||||
[keys sortUsingSelector:@selector(compare:)];
|
||||
BOOL stop = NO;
|
||||
for (NSString *key in keys) {
|
||||
id value = [self convertRequestValue:dictionary[key]];
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
value = [self URLEncode:value];
|
||||
}
|
||||
if (invalidObjectHandler && ![value isKindOfClass:[NSString class]]) {
|
||||
value = invalidObjectHandler(value, &stop);
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (value) {
|
||||
if (hasParameters) {
|
||||
[queryString appendString:@"&"];
|
||||
}
|
||||
[queryString appendFormat:@"%@=%@", key, value];
|
||||
hasParameters = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return (queryString.length ? [queryString copy] : nil);
|
||||
}
|
||||
|
||||
+ (id)convertRequestValue:(id)value
|
||||
{
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
value = ((NSNumber *)value).stringValue;
|
||||
} else if ([value isKindOfClass:[NSURL class]]) {
|
||||
value = ((NSURL *)value).absoluteString;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
+ (NSString *)URLEncode:(NSString *)value
|
||||
{
|
||||
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
|
||||
(CFStringRef)value,
|
||||
NULL, // characters to leave unescaped
|
||||
CFSTR(":!*();@/&?+$,='"),
|
||||
kCFStringEncodingUTF8);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
+ (NSDictionary<NSString *, NSString *> *)dictionaryWithQueryString:(NSString *)queryString
|
||||
{
|
||||
NSMutableDictionary<NSString *, NSString *> *result = [[NSMutableDictionary alloc] init];
|
||||
NSArray<NSString *> *parts = [queryString componentsSeparatedByString:@"&"];
|
||||
|
||||
for (NSString *part in parts) {
|
||||
if (part.length == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSRange index = [part rangeOfString:@"="];
|
||||
NSString *key;
|
||||
NSString *value;
|
||||
|
||||
if (index.location == NSNotFound) {
|
||||
key = part;
|
||||
value = @"";
|
||||
} else {
|
||||
key = [part substringToIndex:index.location];
|
||||
value = [part substringFromIndex:index.location + index.length];
|
||||
}
|
||||
|
||||
key = [self URLDecode:key];
|
||||
value = [self URLDecode:value];
|
||||
if (key && value) {
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSString *)URLDecode:(NSString *)value
|
||||
{
|
||||
value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "];
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
#pragma clang diagnostic pop
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSData *)gzip:(NSData *)data
|
||||
{
|
||||
const void *bytes = data.bytes;
|
||||
const NSUInteger length = data.length;
|
||||
|
||||
if (!bytes || !length) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if defined(__LP64__) && __LP64__
|
||||
if (length > UINT_MAX) {
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
// initialze stream
|
||||
z_stream stream;
|
||||
bzero(&stream, sizeof(z_stream));
|
||||
|
||||
if (deflateInit2(&stream, -1, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
|
||||
return nil;
|
||||
}
|
||||
stream.avail_in = (uint)length;
|
||||
stream.next_in = (Bytef *)bytes;
|
||||
|
||||
int retCode;
|
||||
NSMutableData *result = [NSMutableData dataWithCapacity:(length / 4)];
|
||||
unsigned char output[kChunkSize];
|
||||
do {
|
||||
stream.avail_out = kChunkSize;
|
||||
stream.next_out = output;
|
||||
retCode = deflate(&stream, Z_FINISH);
|
||||
if (retCode != Z_OK && retCode != Z_STREAM_END) {
|
||||
deflateEnd(&stream);
|
||||
return nil;
|
||||
}
|
||||
unsigned size = kChunkSize - stream.avail_out;
|
||||
if (size > 0) {
|
||||
[result appendBytes:output length:size];
|
||||
}
|
||||
} while (retCode == Z_OK);
|
||||
|
||||
deflateEnd(&stream);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSString *)anonymousID
|
||||
{
|
||||
// Grab previously written anonymous ID and, if none have been generated, create and
|
||||
// persist a new one which will remain associated with this app.
|
||||
NSString *result = [[self class] retrievePersistedAnonymousID];
|
||||
if (!result) {
|
||||
// Generate a new anonymous ID. Create as a UUID, but then prepend the fairly
|
||||
// arbitrary 'XZ' to the front so it's easily distinguishable from IDFA's which
|
||||
// will only contain hex.
|
||||
result = [NSString stringWithFormat:@"XZ%@", [NSUUID UUID].UUIDString];
|
||||
|
||||
[self persistAnonymousID:result];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSString *)retrievePersistedAnonymousID
|
||||
{
|
||||
NSString *file = [[self class] persistenceFilePath:FBSDK_BASICUTILITY_ANONYMOUSIDFILENAME];
|
||||
NSString *content = [[NSString alloc] initWithContentsOfFile:file
|
||||
encoding:NSASCIIStringEncoding
|
||||
error:nil];
|
||||
NSDictionary<NSString *, id> *results = [FBSDKBasicUtility objectForJSONString:content error:NULL];
|
||||
return results[FBSDK_BASICUTILITY_ANONYMOUSID_KEY];
|
||||
}
|
||||
|
||||
+ (NSString *)persistenceFilePath:(NSString *)filename
|
||||
{
|
||||
NSSearchPathDirectory directory = NSLibraryDirectory;
|
||||
NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES);
|
||||
NSString *docDirectory = paths[0];
|
||||
return [docDirectory stringByAppendingPathComponent:filename];
|
||||
}
|
||||
|
||||
+ (void)persistAnonymousID:(NSString *)anonymousID
|
||||
{
|
||||
NSDictionary<NSString *, NSString *> *data = @{ FBSDK_BASICUTILITY_ANONYMOUSID_KEY : anonymousID };
|
||||
NSString *content = [self JSONStringForObject:data error:NULL invalidObjectHandler:NULL];
|
||||
|
||||
[content writeToFile:[[self class] persistenceFilePath:FBSDK_BASICUTILITY_ANONYMOUSIDFILENAME]
|
||||
atomically:YES
|
||||
encoding:NSASCIIStringEncoding
|
||||
error:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
+1
@@ -18,6 +18,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_SWIFT_NAME(TypeUtility)
|
||||
@interface FBSDKTypeUtility : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+1
-1
@@ -105,7 +105,7 @@
|
||||
if ([object isKindOfClass:[NSURL class]]) {
|
||||
return (NSURL *)object;
|
||||
} else if ([object isKindOfClass:[NSString class]]) {
|
||||
return [[NSURL alloc] initWithString:(NSString *)object];
|
||||
return [NSURL URLWithString:(NSString *)object];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
+15
-14
@@ -18,26 +18,27 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FBSDKURLSessionTask.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface FBSDKUserDataStore : NSObject
|
||||
@interface FBSDKURLSession : NSObject
|
||||
|
||||
+ (void)initStore;
|
||||
@property (atomic, strong, nullable) NSURLSession *session;
|
||||
@property (nonatomic, weak, nullable) id<NSURLSessionDataDelegate> delegate;
|
||||
@property (nonatomic, retain, nullable) NSOperationQueue *delegateQueue;
|
||||
|
||||
+ (void)setUserDataAndHash:(NSDictionary *)ud;
|
||||
- (instancetype)initWithDelegate:(id<NSURLSessionDataDelegate>)delegate
|
||||
delegateQueue:(NSOperationQueue *)delegateQueue;
|
||||
|
||||
+ (void)setUserDataAndHash:(nullable NSString *)email
|
||||
firstName:(nullable NSString *)firstName
|
||||
lastName:(nullable NSString *)lastName
|
||||
phone:(nullable NSString *)phone
|
||||
dateOfBirth:(nullable NSString *)dateOfBirth
|
||||
gender:(nullable NSString *)gender
|
||||
city:(nullable NSString *)city
|
||||
state:(nullable NSString *)state
|
||||
zip:(nullable NSString *)zip
|
||||
country:(nullable NSString *)country;
|
||||
- (void)executeURLRequest:(NSURLRequest *)request
|
||||
completionHandler:(FBSDKURLSessionTaskBlock)handler;
|
||||
|
||||
+ (NSString *) getHashedUserData;
|
||||
- (void)updateSessionWithBlock:(dispatch_block_t)block;
|
||||
|
||||
- (void)invalidateAndCancel;
|
||||
|
||||
- (BOOL)valid;
|
||||
|
||||
@end
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
// 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 "FBSDKURLSession.h"
|
||||
|
||||
#import "FBSDKBasicUtility.h"
|
||||
#import "FBSDKURLSessionTask.h"
|
||||
|
||||
@implementation FBSDKURLSession
|
||||
|
||||
- (instancetype)initWithDelegate:(id<NSURLSessionDataDelegate>)delegate
|
||||
delegateQueue:(NSOperationQueue *)queue
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
self.delegate = delegate;
|
||||
self.delegateQueue = queue;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)executeURLRequest:(NSURLRequest *)request
|
||||
completionHandler:(FBSDKURLSessionTaskBlock)handler
|
||||
{
|
||||
if (!self.valid) {
|
||||
[self updateSessionWithBlock:^{
|
||||
FBSDKURLSessionTask *task = [[FBSDKURLSessionTask alloc] initWithRequest:request fromSession:self.session completionHandler:handler];
|
||||
[task start];
|
||||
}];
|
||||
} else {
|
||||
FBSDKURLSessionTask *task = [[FBSDKURLSessionTask alloc] initWithRequest:request fromSession:self.session completionHandler:handler];
|
||||
[task start];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateSessionWithBlock:(dispatch_block_t)block
|
||||
{
|
||||
if (!self.valid) {
|
||||
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
|
||||
delegate:_delegate
|
||||
delegateQueue:_delegateQueue];
|
||||
}
|
||||
block();
|
||||
}
|
||||
|
||||
- (void)invalidateAndCancel
|
||||
{
|
||||
[self.session invalidateAndCancel];
|
||||
self.session = nil;
|
||||
}
|
||||
|
||||
- (BOOL)valid
|
||||
{
|
||||
return self.session != nil;
|
||||
}
|
||||
|
||||
@end
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
// 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>
|
||||
|
||||
typedef void (^FBSDKURLSessionTaskBlock)(NSData *responseData,
|
||||
NSURLResponse *response,
|
||||
NSError *error)
|
||||
NS_SWIFT_NAME(URLSessionTaskBlock);
|
||||
|
||||
NS_SWIFT_NAME(URLSessionTask)
|
||||
@interface FBSDKURLSessionTask : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSURLSessionTask *task;
|
||||
@property (atomic, readonly) NSURLSessionTaskState state;
|
||||
@property (nonatomic, strong, readonly) NSDate *requestStartDate;
|
||||
@property (nonatomic, copy) FBSDKURLSessionTaskBlock handler;
|
||||
@property (nonatomic, assign) uint64_t requestStartTime;
|
||||
@property (nonatomic, assign) NSUInteger loggerSerialNumber;
|
||||
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithRequest:(NSURLRequest *)request
|
||||
fromSession:(NSURLSession *)session
|
||||
completionHandler:(FBSDKURLSessionTaskBlock)handler;
|
||||
|
||||
- (void)start;
|
||||
- (void)cancel;
|
||||
|
||||
@end
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
// 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 "FBSDKURLSessionTask.h"
|
||||
|
||||
@implementation FBSDKURLSessionTask
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_requestStartDate = [NSDate date];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRequest:(NSURLRequest *)request
|
||||
fromSession:(NSURLSession *)session
|
||||
completionHandler:(FBSDKURLSessionTaskBlock)handler
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
self.requestStartTime = (uint64_t)([self.requestStartDate timeIntervalSince1970] * 1000);
|
||||
self.task = [session dataTaskWithRequest:request completionHandler:handler];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSURLSessionTaskState)state
|
||||
{
|
||||
return self.task.state;
|
||||
}
|
||||
|
||||
#pragma mark - Task State
|
||||
|
||||
- (void)start
|
||||
{
|
||||
[self.task resume];
|
||||
}
|
||||
|
||||
- (void)cancel
|
||||
{
|
||||
[self.task cancel];
|
||||
self.handler = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -21,6 +21,8 @@
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequestConnection.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
/**
|
||||
@@ -30,19 +32,20 @@
|
||||
`FBSDKAccessTokenChangeOldKey` and
|
||||
`FBSDKAccessTokenChangeNewKey`.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSNotificationName const FBSDKAccessTokenDidChangeNotification;
|
||||
FOUNDATION_EXPORT NSNotificationName const FBSDKAccessTokenDidChangeNotification
|
||||
NS_SWIFT_NAME(AccessTokenDidChange);
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
Notification indicating that the `currentAccessToken` has changed.
|
||||
Notification indicating that the `currentAccessToken` has changed.
|
||||
|
||||
the userInfo dictionary of the notification will contain keys
|
||||
`FBSDKAccessTokenChangeOldKey` and
|
||||
`FBSDKAccessTokenChangeNewKey`.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidChangeNotification;
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidChangeNotification
|
||||
NS_SWIFT_NAME(AccessTokenDidChangeNotification);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -58,89 +61,111 @@ FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidChangeNotification;
|
||||
of an access token, this key will also exist since the access token
|
||||
is moving from a null state (no user) to a non-null state (user).
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidChangeUserIDKey;
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidChangeUserID
|
||||
DEPRECATED_MSG_ATTRIBUTE("Renamed `FBSDKAccessTokenDidChangeUserIDKey`");
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidChangeUserIDKey
|
||||
NS_SWIFT_NAME(AccessTokenDidChangeUserIDKey);
|
||||
|
||||
/*
|
||||
key in notification's userInfo object for getting the old token.
|
||||
|
||||
If there was no old token, the key will not be present.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenChangeOldKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenChangeOldKey
|
||||
NS_SWIFT_NAME(AccessTokenChangeOldKey);
|
||||
|
||||
/*
|
||||
key in notification's userInfo object for getting the new token.
|
||||
|
||||
If there is no new token, the key will not be present.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenChangeNewKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenChangeNewKey
|
||||
NS_SWIFT_NAME(AccessTokenChangeNewKey);
|
||||
|
||||
/*
|
||||
A key in the notification's userInfo that will be set
|
||||
if and only if the token has expired.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidExpireKey;
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidExpire
|
||||
DEPRECATED_MSG_ATTRIBUTE("Renamed `FBSDKAccessTokenDidExpireKey`");
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAccessTokenDidExpireKey
|
||||
NS_SWIFT_NAME(AccessTokenDidExpireKey);
|
||||
|
||||
|
||||
/**
|
||||
Represents an immutable access token for using Facebook services.
|
||||
*/
|
||||
NS_SWIFT_NAME(AccessToken)
|
||||
@interface FBSDKAccessToken : NSObject<FBSDKCopying, NSSecureCoding>
|
||||
|
||||
|
||||
/**
|
||||
The "global" access token that represents the currently logged in user.
|
||||
|
||||
The `currentAccessToken` is a convenient representation of the token of the
|
||||
current user and is used by other SDK components (like `FBSDKLoginManager`).
|
||||
*/
|
||||
@property (class, nonatomic, copy, nullable) FBSDKAccessToken *currentAccessToken;
|
||||
|
||||
/**
|
||||
Returns YES if currentAccessToken is not nil AND currentAccessToken is not expired
|
||||
|
||||
*/
|
||||
@property (class, nonatomic, assign, readonly, getter=isCurrentAccessTokenActive) BOOL currentAccessTokenIsActive;
|
||||
|
||||
/**
|
||||
Returns the app ID.
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) NSString *appID;
|
||||
@property (nonatomic, copy, readonly) NSString *appID;
|
||||
|
||||
/**
|
||||
Returns the expiration date for data access
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) NSDate *dataAccessExpirationDate;
|
||||
@property (nonatomic, copy, readonly) NSDate *dataAccessExpirationDate;
|
||||
|
||||
/**
|
||||
Returns the known declined permissions.
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) NSSet *declinedPermissions;
|
||||
@property (nonatomic, copy, readonly) NSSet<NSString *> *declinedPermissions
|
||||
NS_REFINED_FOR_SWIFT;
|
||||
|
||||
/**
|
||||
Returns the known declined permissions.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSSet<NSString *> *expiredPermissions
|
||||
NS_REFINED_FOR_SWIFT;
|
||||
|
||||
/**
|
||||
Returns the expiration date.
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) NSDate *expirationDate;
|
||||
@property (nonatomic, copy, readonly) NSDate *expirationDate;
|
||||
|
||||
/**
|
||||
Returns the known granted permissions.
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) NSSet *permissions;
|
||||
@property (nonatomic, copy, readonly) NSSet<NSString *> *permissions
|
||||
NS_REFINED_FOR_SWIFT;
|
||||
|
||||
/**
|
||||
Returns the date the token was last refreshed.
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) NSDate *refreshDate;
|
||||
@property (nonatomic, copy, readonly) NSDate *refreshDate;
|
||||
|
||||
/**
|
||||
Returns the opaque token string.
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) NSString *tokenString;
|
||||
@property (nonatomic, copy, readonly) NSString *tokenString;
|
||||
|
||||
/**
|
||||
Returns the user ID.
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) NSString *userID;
|
||||
@property (nonatomic, copy, readonly) NSString *userID;
|
||||
|
||||
/**
|
||||
Returns whether the access token is expired by checking its expirationDate property
|
||||
*/
|
||||
@property (readonly, assign, nonatomic, getter = isExpired) BOOL expired;
|
||||
@property (readonly, assign, nonatomic, getter=isExpired) BOOL expired;
|
||||
|
||||
/**
|
||||
Returns whether user data access is still active for the given access token
|
||||
*/
|
||||
@property (readonly, assign, nonatomic, getter = isDataAccessExpired) BOOL dataAccessExpired;
|
||||
@property (readonly, assign, nonatomic, getter=isDataAccessExpired) BOOL dataAccessExpired;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
@@ -152,29 +177,7 @@ DEPRECATED_MSG_ATTRIBUTE("Renamed `FBSDKAccessTokenDidExpireKey`");
|
||||
an NSArray for the convenience of literal syntax.
|
||||
@param declinedPermissions the declined permissions. Note this is converted to NSSet and is only
|
||||
an NSArray for the convenience of literal syntax.
|
||||
@param appID the app ID.
|
||||
@param userID the user ID.
|
||||
@param expirationDate the optional expiration date (defaults to distantFuture).
|
||||
@param refreshDate the optional date the token was last refreshed (defaults to today).
|
||||
|
||||
This initializer should only be used for advanced apps that
|
||||
manage tokens explicitly. Typical login flows only need to use `FBSDKLoginManager`
|
||||
along with `+currentAccessToken`.
|
||||
*/
|
||||
- (instancetype)initWithTokenString:(NSString *)tokenString
|
||||
permissions:(NSArray *)permissions
|
||||
declinedPermissions:(NSArray *)declinedPermissions
|
||||
appID:(NSString *)appID
|
||||
userID:(NSString *)userID
|
||||
expirationDate:(NSDate *)expirationDate
|
||||
refreshDate:(NSDate *)refreshDate;
|
||||
|
||||
/**
|
||||
Initializes a new instance.
|
||||
@param tokenString the opaque token string.
|
||||
@param permissions the granted permissions. Note this is converted to NSSet and is only
|
||||
an NSArray for the convenience of literal syntax.
|
||||
@param declinedPermissions the declined permissions. Note this is converted to NSSet and is only
|
||||
@param expiredPermissions the expired permissions. Note this is converted to NSSet and is only
|
||||
an NSArray for the convenience of literal syntax.
|
||||
@param appID the app ID.
|
||||
@param userID the user ID.
|
||||
@@ -188,20 +191,22 @@ DEPRECATED_MSG_ATTRIBUTE("Renamed `FBSDKAccessTokenDidExpireKey`");
|
||||
along with `+currentAccessToken`.
|
||||
*/
|
||||
- (instancetype)initWithTokenString:(NSString *)tokenString
|
||||
permissions:(NSArray *)permissions
|
||||
declinedPermissions:(NSArray *)declinedPermissions
|
||||
permissions:(NSArray<NSString *> *)permissions
|
||||
declinedPermissions:(NSArray<NSString *> *)declinedPermissions
|
||||
expiredPermissions:(NSArray<NSString *> *)expiredPermissions
|
||||
appID:(NSString *)appID
|
||||
userID:(NSString *)userID
|
||||
expirationDate:(NSDate *)expirationDate
|
||||
refreshDate:(NSDate *)refreshDate
|
||||
dataAccessExpirationDate:(NSDate *)dataAccessExpirationDate
|
||||
expirationDate:(nullable NSDate *)expirationDate
|
||||
refreshDate:(nullable NSDate *)refreshDate
|
||||
dataAccessExpirationDate:(nullable NSDate *)dataAccessExpirationDate
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
Convenience getter to determine if a permission has been granted
|
||||
@param permission The permission to check.
|
||||
*/
|
||||
- (BOOL)hasGranted:(NSString *)permission;
|
||||
- (BOOL)hasGranted:(NSString *)permission
|
||||
NS_SWIFT_NAME(hasGranted(permission:));
|
||||
|
||||
/**
|
||||
Compares the receiver to another FBSDKAccessToken
|
||||
@@ -210,28 +215,6 @@ NS_DESIGNATED_INITIALIZER;
|
||||
*/
|
||||
- (BOOL)isEqualToAccessToken:(FBSDKAccessToken *)token;
|
||||
|
||||
/**
|
||||
Returns the "global" access token that represents the currently logged in user.
|
||||
|
||||
The `currentAccessToken` is a convenient representation of the token of the
|
||||
current user and is used by other SDK components (like `FBSDKLoginManager`).
|
||||
*/
|
||||
+ (FBSDKAccessToken *)currentAccessToken;
|
||||
|
||||
/**
|
||||
Returns YES if currentAccessToken is not nil AND currentAccessToken is not expired
|
||||
|
||||
*/
|
||||
+ (BOOL)currentAccessTokenIsActive;
|
||||
|
||||
/**
|
||||
Sets the "global" access token that represents the currently logged in user.
|
||||
@param token The access token to set.
|
||||
|
||||
This will broadcast a notification and save the token to the app keychain.
|
||||
*/
|
||||
+ (void)setCurrentAccessToken:(FBSDKAccessToken *)token;
|
||||
|
||||
/**
|
||||
Refresh the current access token's permission state and extend the token's expiration date,
|
||||
if possible.
|
||||
@@ -242,6 +225,8 @@ NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
If a token is already expired, it cannot be refreshed.
|
||||
*/
|
||||
+ (void)refreshCurrentAccessToken:(FBSDKGraphRequestHandler)completionHandler;
|
||||
+ (void)refreshCurrentAccessToken:(nullable FBSDKGraphRequestBlock)completionHandler;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -33,18 +33,17 @@ NSString *const FBSDKAccessTokenDidChangeNotification = @"com.facebook.sdk.FBSDK
|
||||
|
||||
#endif
|
||||
|
||||
NSString *const FBSDKAccessTokenDidChangeUserIDKey = @"FBSDKAccessTokenDidChangeUserID";
|
||||
NSString *const FBSDKAccessTokenDidChangeUserID = @"FBSDKAccessTokenDidChangeUserID";
|
||||
NSString *const FBSDKAccessTokenDidChangeUserIDKey = @"FBSDKAccessTokenDidChangeUserIDKey";
|
||||
NSString *const FBSDKAccessTokenChangeNewKey = @"FBSDKAccessToken";
|
||||
NSString *const FBSDKAccessTokenChangeOldKey = @"FBSDKAccessTokenOld";
|
||||
NSString *const FBSDKAccessTokenDidExpireKey = @"FBSDKAccessTokenDidExpire";
|
||||
NSString *const FBSDKAccessTokenDidExpire = @"FBSDKAccessTokenDidExpire";
|
||||
NSString *const FBSDKAccessTokenDidExpireKey = @"FBSDKAccessTokenDidExpireKey";
|
||||
|
||||
static FBSDKAccessToken *g_currentAccessToken;
|
||||
|
||||
#define FBSDK_ACCESSTOKEN_TOKENSTRING_KEY @"tokenString"
|
||||
#define FBSDK_ACCESSTOKEN_PERMISSIONS_KEY @"permissions"
|
||||
#define FBSDK_ACCESSTOKEN_DECLINEDPERMISSIONS_KEY @"declinedPermissions"
|
||||
#define FBSDK_ACCESSTOKEN_EXPIREDPERMISSIONS_KEY @"expiredPermissions"
|
||||
#define FBSDK_ACCESSTOKEN_APPID_KEY @"appID"
|
||||
#define FBSDK_ACCESSTOKEN_USERID_KEY @"userID"
|
||||
#define FBSDK_ACCESSTOKEN_REFRESHDATE_KEY @"refreshDate"
|
||||
@@ -57,41 +56,25 @@ static FBSDKAccessToken *g_currentAccessToken;
|
||||
- (instancetype)initWithTokenString:(NSString *)tokenString
|
||||
permissions:(NSArray *)permissions
|
||||
declinedPermissions:(NSArray *)declinedPermissions
|
||||
expiredPermissions:(NSArray *)expiredPermissions
|
||||
appID:(NSString *)appID
|
||||
userID:(NSString *)userID
|
||||
expirationDate:(NSDate *)expirationDate
|
||||
refreshDate:(NSDate *)refreshDate
|
||||
dataAccessExpirationDate:(NSDate *)dataAccessExpirationDate
|
||||
{
|
||||
return [self initWithTokenString:tokenString
|
||||
permissions:permissions
|
||||
declinedPermissions:declinedPermissions
|
||||
appID:appID
|
||||
userID:userID
|
||||
expirationDate:expirationDate
|
||||
refreshDate:refreshDate
|
||||
dataAccessExpirationDate:[NSDate distantFuture]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTokenString:(NSString *)tokenString
|
||||
permissions:(NSArray *)permissions
|
||||
declinedPermissions:(NSArray *)declinedPermissions
|
||||
appID:(NSString *)appID
|
||||
userID:(NSString *)userID
|
||||
expirationDate:(NSDate *)expirationDate
|
||||
refreshDate:(NSDate *)refreshDate
|
||||
dataAccessExpirationDate:(NSDate *)dataAccessExpirationDate
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_tokenString = [tokenString copy];
|
||||
_permissions = [NSSet setWithArray:permissions];
|
||||
_declinedPermissions = [NSSet setWithArray:declinedPermissions];
|
||||
_appID = [appID copy];
|
||||
_userID = [userID copy];
|
||||
_expirationDate = [expirationDate copy] ?: [NSDate distantFuture];
|
||||
_refreshDate = [refreshDate copy] ?: [NSDate date];
|
||||
_dataAccessExpirationDate = [dataAccessExpirationDate copy] ?: [NSDate distantFuture];
|
||||
}
|
||||
return self;
|
||||
if ((self = [super init])) {
|
||||
_tokenString = [tokenString copy];
|
||||
_permissions = [NSSet setWithArray:permissions];
|
||||
_declinedPermissions = [NSSet setWithArray:declinedPermissions];
|
||||
_expiredPermissions = [NSSet setWithArray:expiredPermissions];
|
||||
_appID = [appID copy];
|
||||
_userID = [userID copy];
|
||||
_expirationDate = [expirationDate copy] ?: [NSDate distantFuture];
|
||||
_refreshDate = [refreshDate copy] ?: [NSDate date];
|
||||
_dataAccessExpirationDate = [dataAccessExpirationDate copy] ?: [NSDate distantFuture];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)hasGranted:(NSString *)permission
|
||||
@@ -119,10 +102,10 @@ static FBSDKAccessToken *g_currentAccessToken;
|
||||
{
|
||||
if (token != g_currentAccessToken) {
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:token forKey:FBSDKAccessTokenChangeNewKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:g_currentAccessToken forKey:FBSDKAccessTokenChangeOldKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:token forKey:FBSDKAccessTokenChangeNewKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:g_currentAccessToken forKey:FBSDKAccessTokenChangeOldKey];
|
||||
// We set this flag also when the current Access Token was not valid, since there might be legacy code relying on it
|
||||
if (![g_currentAccessToken.userID isEqualToString:token.userID] || ![self currentAccessTokenIsActive]) {
|
||||
if (![g_currentAccessToken.userID isEqualToString:token.userID] || !self.isCurrentAccessTokenActive) {
|
||||
userInfo[FBSDKAccessTokenDidChangeUserIDKey] = @YES;
|
||||
}
|
||||
|
||||
@@ -141,22 +124,22 @@ static FBSDKAccessToken *g_currentAccessToken;
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)currentAccessTokenIsActive
|
||||
+ (BOOL)isCurrentAccessTokenActive
|
||||
{
|
||||
FBSDKAccessToken *currentAccessToken = [self currentAccessToken];
|
||||
return currentAccessToken != nil && !currentAccessToken.isExpired;
|
||||
}
|
||||
|
||||
+ (void)refreshCurrentAccessToken:(FBSDKGraphRequestHandler)completionHandler
|
||||
+ (void)refreshCurrentAccessToken:(FBSDKGraphRequestBlock)completionHandler
|
||||
{
|
||||
if ([FBSDKAccessToken currentAccessToken]) {
|
||||
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
|
||||
[FBSDKGraphRequestPiggybackManager addRefreshPiggyback:connection permissionHandler:completionHandler];
|
||||
[connection start];
|
||||
} else {
|
||||
if (completionHandler) {
|
||||
completionHandler(nil, nil, [NSError fbErrorWithCode:FBSDKErrorAccessTokenRequired message:@"No current access token to refresh"]);
|
||||
}
|
||||
} else if (completionHandler) {
|
||||
completionHandler(nil, nil, [FBSDKError
|
||||
errorWithCode:FBSDKErrorAccessTokenRequired
|
||||
message:@"No current access token to refresh"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +151,7 @@ static FBSDKAccessToken *g_currentAccessToken;
|
||||
self.tokenString.hash,
|
||||
self.permissions.hash,
|
||||
self.declinedPermissions.hash,
|
||||
self.expiredPermissions.hash,
|
||||
self.appID.hash,
|
||||
self.userID.hash,
|
||||
self.refreshDate.hash,
|
||||
@@ -194,6 +178,7 @@ static FBSDKAccessToken *g_currentAccessToken;
|
||||
[FBSDKInternalUtility object:self.tokenString isEqualToObject:token.tokenString] &&
|
||||
[FBSDKInternalUtility object:self.permissions isEqualToObject:token.permissions] &&
|
||||
[FBSDKInternalUtility object:self.declinedPermissions isEqualToObject:token.declinedPermissions] &&
|
||||
[FBSDKInternalUtility object:self.expiredPermissions isEqualToObject:token.expiredPermissions] &&
|
||||
[FBSDKInternalUtility object:self.appID isEqualToObject:token.appID] &&
|
||||
[FBSDKInternalUtility object:self.userID isEqualToObject:token.userID] &&
|
||||
[FBSDKInternalUtility object:self.refreshDate isEqualToObject:token.refreshDate] &&
|
||||
@@ -220,6 +205,7 @@ static FBSDKAccessToken *g_currentAccessToken;
|
||||
{
|
||||
NSString *appID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_ACCESSTOKEN_APPID_KEY];
|
||||
NSSet *declinedPermissions = [decoder decodeObjectOfClass:[NSSet class] forKey:FBSDK_ACCESSTOKEN_DECLINEDPERMISSIONS_KEY];
|
||||
NSSet *expiredPermissions = [decoder decodeObjectOfClass:[NSSet class] forKey:FBSDK_ACCESSTOKEN_EXPIREDPERMISSIONS_KEY];
|
||||
NSSet *permissions = [decoder decodeObjectOfClass:[NSSet class] forKey:FBSDK_ACCESSTOKEN_PERMISSIONS_KEY];
|
||||
NSString *tokenString = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_ACCESSTOKEN_TOKENSTRING_KEY];
|
||||
NSString *userID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_ACCESSTOKEN_USERID_KEY];
|
||||
@@ -230,6 +216,7 @@ static FBSDKAccessToken *g_currentAccessToken;
|
||||
return [self initWithTokenString:tokenString
|
||||
permissions:permissions.allObjects
|
||||
declinedPermissions:declinedPermissions.allObjects
|
||||
expiredPermissions:expiredPermissions.allObjects
|
||||
appID:appID
|
||||
userID:userID
|
||||
expirationDate:expirationDate
|
||||
@@ -241,6 +228,7 @@ static FBSDKAccessToken *g_currentAccessToken;
|
||||
{
|
||||
[encoder encodeObject:self.appID forKey:FBSDK_ACCESSTOKEN_APPID_KEY];
|
||||
[encoder encodeObject:self.declinedPermissions forKey:FBSDK_ACCESSTOKEN_DECLINEDPERMISSIONS_KEY];
|
||||
[encoder encodeObject:self.expiredPermissions forKey:FBSDK_ACCESSTOKEN_EXPIREDPERMISSIONS_KEY];
|
||||
[encoder encodeObject:self.permissions forKey:FBSDK_ACCESSTOKEN_PERMISSIONS_KEY];
|
||||
[encoder encodeObject:self.tokenString forKey:FBSDK_ACCESSTOKEN_TOKENSTRING_KEY];
|
||||
[encoder encodeObject:self.userID forKey:FBSDK_ACCESSTOKEN_USERID_KEY];
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
// 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 "FBSDKAppLinkResolving.h"
|
||||
|
||||
@class BFTask;
|
||||
|
||||
|
||||
// Check if Bolts.framework is available for import
|
||||
#if __has_include(<Bolts/BFAppLinkResolving.h>)
|
||||
// Import it if it's available
|
||||
#import <Bolts/BFAppLinkResolving.h>
|
||||
#else
|
||||
// Otherwise - redeclare BFAppLinkResolving protocol to resolve the problem of missing symbols
|
||||
// Please note: Bolts.framework is still required for AppLink resolving to work,
|
||||
// but this allows FBSDKCoreKit to weakly link Bolts.framework as well as this enables clang modulemaps to work.
|
||||
|
||||
/**
|
||||
Implement this protocol to provide an alternate strategy for resolving
|
||||
App Links that may include pre-fetching, caching, or querying for App Link
|
||||
data from an index provided by a service provider.
|
||||
*/
|
||||
DEPRECATED_MSG_ATTRIBUTE("Use `FBSDKAppLinkResolving`")
|
||||
@protocol BFAppLinkResolving <NSObject>
|
||||
|
||||
/**
|
||||
Asynchronously resolves App Link data for a given URL.
|
||||
|
||||
@param url The URL to resolve into an App Link.
|
||||
@return A BFTask that will return a BFAppLink for the given URL.
|
||||
*/
|
||||
- (BFTask *)appLinkFromURLInBackground:(NSURL *)url
|
||||
DEPRECATED_MSG_ATTRIBUTE("Use `appLinkFromURL:handler:`");
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
Provides an implementation of the BFAppLinkResolving protocol that uses the Facebook App Link
|
||||
Index API to resolve App Links given a URL. It also provides an additional helper method that can resolve
|
||||
multiple App Links in a single call.
|
||||
|
||||
|
||||
|
||||
Usage of this type requires a client token. See `[FBSDKSettings setClientToken:]` and linking
|
||||
Bolts.framework
|
||||
*/
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
@interface FBSDKAppLinkResolver : NSObject<FBSDKAppLinkResolving, BFAppLinkResolving>
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
/**
|
||||
Asynchronously resolves App Link data for multiple URLs.
|
||||
|
||||
@param urls An array of NSURLs to resolve into App Links.
|
||||
@return A BFTask that will return dictionary mapping input NSURLs to their
|
||||
corresponding BFAppLink.
|
||||
|
||||
You should set the client token before making this call. See `[FBSDKSettings setClientToken:]`
|
||||
*/
|
||||
- (BFTask *)appLinksFromURLsInBackground:(NSArray<NSURL *> *)urls
|
||||
DEPRECATED_MSG_ATTRIBUTE("Use `appLinkFromURLs:handler:`");
|
||||
|
||||
/**
|
||||
Asynchronously resolves App Link data for a given URL.
|
||||
|
||||
@param url The URL to resolve into an App Link.
|
||||
@return A BFTask that will return a BFAppLink for the given URL.
|
||||
*/
|
||||
- (BFTask *)appLinkFromURLInBackground:(NSURL *)url
|
||||
DEPRECATED_MSG_ATTRIBUTE("Use `appLinkFromURL:handler:`");
|
||||
|
||||
/**
|
||||
Asynchronously resolves App Link data for a given array of URLs.
|
||||
|
||||
@param urls The URLs to resolve into an App Link.
|
||||
@param handler The completion block that will return an App Link for the given URL.
|
||||
*/
|
||||
- (void)appLinksFromURLs:(NSArray<NSURL *> *)urls handler:(FBSDKAppLinksFromURLArrayHandler)handler
|
||||
NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension");
|
||||
|
||||
/**
|
||||
Allocates and initializes a new instance of FBSDKAppLinkResolver.
|
||||
*/
|
||||
+ (instancetype)resolver;
|
||||
|
||||
@end
|
||||
+26
-6
@@ -18,6 +18,8 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
|
||||
The FBSDKApplicationDelegate is designed to post process the results from Facebook Login
|
||||
@@ -29,12 +31,17 @@
|
||||
The methods in this class are designed to mirror those in UIApplicationDelegate, and you
|
||||
should call them in the respective methods in your AppDelegate implementation.
|
||||
*/
|
||||
NS_SWIFT_NAME(ApplicationDelegate)
|
||||
@interface FBSDKApplicationDelegate : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Gets the singleton instance.
|
||||
Gets the singleton instance.
|
||||
*/
|
||||
+ (instancetype)sharedInstance;
|
||||
@property (class, nonatomic, readonly, strong) FBSDKApplicationDelegate *sharedInstance
|
||||
NS_SWIFT_NAME(shared);
|
||||
|
||||
/**
|
||||
Call this method from the [UIApplicationDelegate application:openURL:sourceApplication:annotation:] method
|
||||
@@ -53,8 +60,8 @@
|
||||
*/
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation;
|
||||
sourceApplication:(nullable NSString *)sourceApplication
|
||||
annotation:(nullable id)annotation;
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_9_0
|
||||
/**
|
||||
@@ -72,7 +79,7 @@
|
||||
*/
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -87,6 +94,19 @@ controlled via 'FacebookAutoLogAppEventsEnabled' key in the project info plist f
|
||||
|
||||
@return YES if the url was intended for the Facebook SDK, NO if not.
|
||||
*/
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
didFinishLaunchingWithOptions:(nullable NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions;
|
||||
|
||||
/**
|
||||
Call this method to manually initialize SDK.
|
||||
As we initialize SDK automatically, this should only be called when auto initialization is disabled, this can be
|
||||
controlled via 'FacebookAutoInitEnabled' key in the project info plist file.
|
||||
|
||||
@param launchOptions The launchOptions as passed to [UIApplicationDelegate application:didFinishLaunchingWithOptions:].
|
||||
Could be nil if you don't call this function from [UIApplicationDelegate application:didFinishLaunchingWithOptions:].
|
||||
*/
|
||||
+ (void)initializeSDK:(nullable NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+224
-453
@@ -21,27 +21,22 @@
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#import <SafariServices/SafariServices.h>
|
||||
#endif
|
||||
|
||||
#import "FBSDKAppEvents+Internal.h"
|
||||
#import "FBSDKConstants.h"
|
||||
#import "FBSDKDynamicFrameworkLoader.h"
|
||||
#import "FBSDKError.h"
|
||||
#import "FBSDKFeatureManager.h"
|
||||
#import "FBSDKGateKeeperManager.h"
|
||||
#import "FBSDKInstrumentManager.h"
|
||||
#import "FBSDKInternalUtility.h"
|
||||
#import "FBSDKLogger.h"
|
||||
#import "FBSDKServerConfiguration.h"
|
||||
#import "FBSDKServerConfigurationManager.h"
|
||||
#import "FBSDKSettings+Internal.h"
|
||||
#import "FBSDKTimeSpentData.h"
|
||||
#import "FBSDKUtility.h"
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#import "FBSDKBoltsMeasurementEventListener.h"
|
||||
#import "FBSDKBridgeAPIRequest.h"
|
||||
#import "FBSDKBridgeAPIResponse.h"
|
||||
#import "FBSDKMeasurementEventListener.h"
|
||||
#import "FBSDKContainerViewController.h"
|
||||
#import "FBSDKProfile+Internal.h"
|
||||
#endif
|
||||
@@ -57,94 +52,102 @@ NSString *const FBSDKApplicationDidBecomeActiveNotification = @"com.facebook.sdk
|
||||
#endif
|
||||
|
||||
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
|
||||
static NSString *const FBSDKKitsBitmaskKey = @"com.facebook.sdk.kits.bitmask";
|
||||
static BOOL g_isSDKInitialized = NO;
|
||||
static UIApplicationState _applicationState;
|
||||
|
||||
@implementation FBSDKApplicationDelegate
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
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;
|
||||
NSHashTable<id<FBSDKApplicationObserving>> *_applicationObservers;
|
||||
BOOL _isAppLaunched;
|
||||
}
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
if ([FBSDKSettings isAutoInitEnabled]) {
|
||||
// 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;
|
||||
|
||||
[[self sharedInstance] application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:launchData];
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
// 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];
|
||||
|
||||
[FBSDKInternalUtility validateFacebookReservedURLSchemes];
|
||||
// Remove the observer
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[self initializeSDK:note.userInfo];
|
||||
// Remove the observer
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:UIApplicationDidFinishLaunchingNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
+ (void)initializeSDK:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions
|
||||
{
|
||||
static FBSDKApplicationDelegate *_sharedInstance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_sharedInstance = [[self alloc] _init];
|
||||
});
|
||||
return _sharedInstance;
|
||||
if (g_isSDKInitialized) {
|
||||
// Do nothing if initialized already
|
||||
return;
|
||||
}
|
||||
|
||||
g_isSDKInitialized = YES;
|
||||
|
||||
FBSDKApplicationDelegate *delegate = [self sharedInstance];
|
||||
|
||||
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
|
||||
[defaultCenter addObserver:delegate selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
|
||||
[defaultCenter addObserver:delegate selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
|
||||
[[FBSDKAppEvents singleton] registerNotifications];
|
||||
|
||||
[delegate application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
[FBSDKFeatureManager checkFeature:FBSDKFeatureInstrument completionBlock:^(BOOL enabled) {
|
||||
if (enabled) {
|
||||
[FBSDKInstrumentManager enable];
|
||||
}
|
||||
}];
|
||||
|
||||
[FBSDKFeatureManager checkFeature:FBSDKFeatureRestrictiveDataFiltering completionBlock:^(BOOL enabled) {
|
||||
if (enabled) {
|
||||
[FBSDKRestrictiveDataFilterManager enable];
|
||||
}
|
||||
}];
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
// Register Listener for App Link measurement events
|
||||
[FBSDKMeasurementEventListener 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:launchOptions[UIApplicationLaunchOptionsSourceApplicationKey]
|
||||
openURL:launchOptions[UIApplicationLaunchOptionsURLKey]];
|
||||
// Register on UIApplicationDidEnterBackgroundNotification events to reset source application data when app backgrounds.
|
||||
[FBSDKTimeSpentData registerAutoResetSourceApplication];
|
||||
|
||||
[FBSDKInternalUtility validateFacebookReservedURLSchemes];
|
||||
}
|
||||
|
||||
+ (FBSDKApplicationDelegate *)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];
|
||||
|
||||
[[FBSDKAppEvents singleton] registerNotifications];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
return nil;
|
||||
if ((self = [super init]) != nil) {
|
||||
_applicationObservers = [[NSHashTable alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
@@ -175,53 +178,33 @@ typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackUR
|
||||
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;
|
||||
|
||||
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();
|
||||
BOOL handled = NO;
|
||||
NSArray<id<FBSDKApplicationObserving>> *observers = [_applicationObservers allObjects];
|
||||
for (id<FBSDKApplicationObserving> observer in observers) {
|
||||
if ([observer respondsToSelector:@selector(application:openURL:sourceApplication:annotation:)]) {
|
||||
if ([observer application:application
|
||||
openURL:url
|
||||
sourceApplication:sourceApplication
|
||||
annotation:annotation]) {
|
||||
handled = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ([pendingURLOpen canOpenURL:url
|
||||
forApplication:application
|
||||
sourceApplication:sourceApplication
|
||||
annotation:annotation]) {
|
||||
return YES;
|
||||
}
|
||||
if ([self _handleBridgeAPIResponseURL:url sourceApplication:sourceApplication]) {
|
||||
return YES;
|
||||
}
|
||||
#endif
|
||||
[self _logIfAppLinkEvent:url];
|
||||
if (handled) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
[self _logIfAppLinkEvent:url];
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
@@ -235,348 +218,182 @@ typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackUR
|
||||
[FBSDKAccessToken setCurrentAccessToken:cachedToken];
|
||||
// fetch app settings
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
|
||||
// fetch gate keepers
|
||||
[FBSDKGateKeeperManager loadGateKeepers];
|
||||
|
||||
if ([FBSDKSettings autoLogAppEventsEnabled].boolValue) {
|
||||
if (FBSDKSettings.isAutoLogAppEventsEnabled) {
|
||||
[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;
|
||||
NSArray<id<FBSDKApplicationObserving>> *observers = [_applicationObservers allObjects];
|
||||
BOOL handled = NO;
|
||||
for (id<FBSDKApplicationObserving> observer in observers) {
|
||||
if ([observer respondsToSelector:@selector(application:didFinishLaunchingWithOptions:)]) {
|
||||
if ([observer application:application didFinishLaunchingWithOptions:launchOptions]) {
|
||||
handled = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(NSNotification *)notification
|
||||
{
|
||||
_isRequestingSFAuthenticationSession = NO;
|
||||
_active = NO;
|
||||
_expectingBackground = NO;
|
||||
_applicationState = UIApplicationStateBackground;
|
||||
NSArray<id<FBSDKApplicationObserving>> *observers = [_applicationObservers allObjects];
|
||||
for (id<FBSDKApplicationObserving> observer in observers) {
|
||||
if ([observer respondsToSelector:@selector(applicationDidEnterBackground:)]) {
|
||||
[observer applicationDidEnterBackground:notification.object];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (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 (notExpectingBackground) {
|
||||
_active = YES;
|
||||
#if !TARGET_OS_TV
|
||||
[_pendingURLOpen applicationDidBecomeActive:notification.object];
|
||||
[self _cancelBridgeRequest];
|
||||
#endif
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:FBSDKApplicationDidBecomeActiveNotification object:self];
|
||||
_applicationState = UIApplicationStateActive;
|
||||
// Auto log basic events in case autoLogAppEventsEnabled is set
|
||||
if (FBSDKSettings.isAutoLogAppEventsEnabled) {
|
||||
[FBSDKAppEvents activateApp];
|
||||
}
|
||||
|
||||
NSArray<id<FBSDKApplicationObserving>> *observers = [_applicationObservers copy];
|
||||
for (id<FBSDKApplicationObserving> observer in observers) {
|
||||
if ([observer respondsToSelector:@selector(applicationDidBecomeActive:)]) {
|
||||
[observer applicationDidBecomeActive:notification.object];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Internal Methods
|
||||
|
||||
#pragma mark -- (non-tvos)
|
||||
#pragma mark - FBSDKApplicationObserving
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
|
||||
- (void)openURL:(NSURL *)url sender:(id<FBSDKURLOpening>)sender handler:(void(^)(BOOL, NSError *))handler
|
||||
- (void)addObserver:(id<FBSDKApplicationObserving>)observer
|
||||
{
|
||||
_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 (handler) {
|
||||
handler(opened, nil);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (![_applicationObservers containsObject:observer]) {
|
||||
[_applicationObservers addObject:observer];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request
|
||||
useSafariViewController:(BOOL)useSafariViewController
|
||||
fromViewController:(UIViewController *)fromViewController
|
||||
completionBlock:(FBSDKBridgeAPICallbackBlock)completionBlock
|
||||
- (void)removeObserver:(id<FBSDKApplicationObserving>)observer
|
||||
{
|
||||
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 ([_applicationObservers containsObject:observer]) {
|
||||
[_applicationObservers removeObject:observer];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)openURLWithSafariViewController:(NSURL *)url
|
||||
sender:(id<FBSDKURLOpening>)sender
|
||||
fromViewController:(UIViewController *)fromViewController
|
||||
handler:(void(^)(BOOL, NSError *))handler
|
||||
+ (UIApplicationState)applicationState
|
||||
{
|
||||
if (![url.scheme hasPrefix:@"http"]) {
|
||||
[self openURL:url sender:sender handler:handler];
|
||||
return;
|
||||
}
|
||||
|
||||
_expectingBackground = NO;
|
||||
_pendingURLOpen = sender;
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
if ([sender isAuthenticationURL:url]) {
|
||||
[self _setSessionCompletionHandlerFromHandler:handler];
|
||||
[self _openURLWithAuthenticationSession:url];
|
||||
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];
|
||||
}
|
||||
return _applicationState;
|
||||
}
|
||||
|
||||
- (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];
|
||||
}
|
||||
}
|
||||
|
||||
- (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
|
||||
|
||||
// This means the user tapped "Done" which we should treat as a cancellation.
|
||||
- (void)safariViewControllerDidFinish:(UIViewController *)safariViewController
|
||||
{
|
||||
if (_pendingURLOpen) {
|
||||
id<FBSDKURLOpening> pendingURLOpen = _pendingURLOpen;
|
||||
|
||||
_pendingURLOpen = nil;
|
||||
|
||||
[pendingURLOpen application:nil
|
||||
openURL:nil
|
||||
sourceApplication:nil
|
||||
annotation: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];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (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<NSString *, NSString *> *params = [FBSDKBasicUtility dictionaryWithQueryString:url.query];
|
||||
NSString *applinkDataString = params[@"al_applink_data"];
|
||||
if (!applinkDataString) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSDictionary *applinkData = [FBSDKInternalUtility objectForJSONString:applinkDataString error:NULL];
|
||||
if (!applinkData) {
|
||||
return;
|
||||
}
|
||||
NSDictionary<id, id> *applinkData = [FBSDKBasicUtility 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];
|
||||
[FBSDKBasicUtility dictionary:logData setObject:targetURL.absoluteString forKey:@"targetURL"];
|
||||
[FBSDKBasicUtility 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) {
|
||||
[FBSDKBasicUtility dictionary:logData setObject:refererData[@"target_url"] forKey:@"referralTargetURL"];
|
||||
[FBSDKBasicUtility dictionary:logData setObject:refererData[@"url"] forKey:@"referralURL"];
|
||||
[FBSDKBasicUtility dictionary:logData setObject:refererData[@"app_name"] forKey:@"referralAppName"];
|
||||
}
|
||||
[FBSDKBasicUtility dictionary:logData setObject:url.absoluteString forKey:@"inputURL"];
|
||||
[FBSDKBasicUtility dictionary:logData setObject:url.scheme forKey:@"inputURLScheme"];
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppLinkInboundEvent
|
||||
valueToSum:nil
|
||||
parameters:logData
|
||||
accessToken:nil];
|
||||
[FBSDKAppEvents logInternalEvent:FBSDKAppLinkInboundEvent
|
||||
parameters:logData
|
||||
isImplicitlyLogged:YES];
|
||||
}
|
||||
|
||||
- (void)_logSDKInitialize
|
||||
{
|
||||
NSMutableDictionary *params = [NSMutableDictionary new];
|
||||
params[@"core_lib_included"] = @1;
|
||||
if (objc_lookUpClass("FBSDKShareDialog") != nil) {
|
||||
params[@"share_lib_included"] = @1;
|
||||
NSDictionary *metaInfo = [NSDictionary dictionaryWithObjects:@[@"login_lib_included",
|
||||
@"marketing_lib_included",
|
||||
@"messenger_lib_included",
|
||||
@"places_lib_included",
|
||||
@"share_lib_included",
|
||||
@"tv_lib_included"]
|
||||
forKeys:@[@"FBSDKLoginManager",
|
||||
@"FBSDKAutoLog",
|
||||
@"FBSDKMessengerButton",
|
||||
@"FBSDKPlacesManager",
|
||||
@"FBSDKShareDialog",
|
||||
@"FBSDKTVInterfaceFactory"]];
|
||||
|
||||
NSInteger bitmask = 0;
|
||||
NSInteger bit = 0;
|
||||
NSMutableDictionary<NSString *, NSNumber *> *params = NSMutableDictionary.new;
|
||||
params[@"core_lib_included"] = @1;
|
||||
for (NSString *className in metaInfo.allKeys) {
|
||||
NSString *keyName = [metaInfo objectForKey:className];
|
||||
if (objc_lookUpClass([className UTF8String])) {
|
||||
params[keyName] = @1;
|
||||
bitmask |= 1 << bit;
|
||||
}
|
||||
if (objc_lookUpClass("FBSDKLoginManager") != nil) {
|
||||
params[@"login_lib_included"] = @1;
|
||||
bit++;
|
||||
}
|
||||
|
||||
// Tracking if the consuming Application is using Swift
|
||||
id delegate = [UIApplication sharedApplication].delegate;
|
||||
NSString const *className = NSStringFromClass([delegate class]);
|
||||
if ([className componentsSeparatedByString:@"."].count > 1) {
|
||||
params[@"is_using_swift"] = @YES;
|
||||
}
|
||||
|
||||
void (^checkViewForSwift)(void) = ^void ()
|
||||
{
|
||||
// Additional check to see if the consuming application perhaps was
|
||||
// originally an objc project but is now using Swift
|
||||
UIViewController *topMostViewController = [FBSDKInternalUtility topMostViewController];
|
||||
NSString const *vcClassName = NSStringFromClass([topMostViewController class]);
|
||||
if ([vcClassName componentsSeparatedByString:@"."].count > 1) {
|
||||
params[@"is_using_swift"] = @YES;
|
||||
}
|
||||
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];
|
||||
};
|
||||
|
||||
if ([NSThread isMainThread]) {
|
||||
checkViewForSwift();
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
checkViewForSwift();
|
||||
});
|
||||
}
|
||||
|
||||
NSInteger existingBitmask = [[NSUserDefaults standardUserDefaults] integerForKey:FBSDKKitsBitmaskKey];
|
||||
if (existingBitmask != bitmask) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:bitmask forKey:FBSDKKitsBitmaskKey];
|
||||
[FBSDKAppEvents logInternalEvent:@"fb_sdk_initialize"
|
||||
parameters:params
|
||||
isImplicitlyLogged:NO];
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)isSDKInitialized
|
||||
{
|
||||
return [FBSDKSettings isAutoInitEnabled] || g_isSDKInitialized;
|
||||
}
|
||||
|
||||
// Wrapping this makes it mockable and enables testability
|
||||
@@ -584,50 +401,4 @@ typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackUR
|
||||
return _isAppLaunched;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_cancelBridgeRequest
|
||||
{
|
||||
if (_pendingRequest && _pendingRequestCompletionBlock) {
|
||||
_pendingRequestCompletionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseCancelledWithRequest:_pendingRequest]);
|
||||
}
|
||||
_pendingRequest = nil;
|
||||
_pendingRequestCompletionBlock = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
@@ -18,9 +18,14 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
A base class for common SDK buttons.
|
||||
*/
|
||||
NS_SWIFT_NAME(FBButton)
|
||||
@interface FBSDKButton : UIButton
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -24,7 +24,6 @@
|
||||
#import "FBSDKAppEvents.h"
|
||||
#import "FBSDKApplicationDelegate+Internal.h"
|
||||
#import "FBSDKLogo.h"
|
||||
#import "FBSDKMath.h"
|
||||
#import "FBSDKUIUtility.h"
|
||||
#import "FBSDKViewImpressionTracker.h"
|
||||
|
||||
@@ -166,10 +165,10 @@
|
||||
|
||||
- (void)logTapEventWithEventName:(NSString *)eventName parameters:(NSDictionary *)parameters
|
||||
{
|
||||
[FBSDKAppEvents logImplicitEvent:eventName
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
[FBSDKAppEvents logInternalEvent:eventName
|
||||
parameters:parameters
|
||||
isImplicitlyLogged:YES
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
}
|
||||
|
||||
- (void)checkImplicitlyDisabled
|
||||
@@ -227,7 +226,7 @@
|
||||
|
||||
- (UIColor *)defaultBackgroundColor
|
||||
{
|
||||
return [UIColor colorWithRed:65.0/255.0 green:93.0/255.0 blue:174.0/255.0 alpha:1.0];
|
||||
return [UIColor colorWithRed:24.0/255.0 green:119.0/255.0 blue:242.0/255.0 alpha:1.0];
|
||||
}
|
||||
|
||||
- (UIColor *)defaultDisabledColor
|
||||
@@ -242,7 +241,7 @@
|
||||
|
||||
- (UIColor *)defaultHighlightedColor
|
||||
{
|
||||
return [UIColor colorWithRed:47.0/255.0 green:71.0/255.0 blue:122.0/255.0 alpha:1.0];
|
||||
return [UIColor colorWithRed:21.0/255.0 green:105.0/255.0 blue:214.0/255.0 alpha:1.0];
|
||||
}
|
||||
|
||||
- (FBSDKIcon *)defaultIcon
|
||||
@@ -255,6 +254,11 @@
|
||||
return [UIColor colorWithRed:124.0/255.0 green:143.0/255.0 blue:200.0/255.0 alpha:1.0];
|
||||
}
|
||||
|
||||
- (UIColor *)highlightedContentColor
|
||||
{
|
||||
return [UIColor colorWithRed:218.0/255.0 green:221.0/255.0 blue:226.0/255.0 alpha:1.0];
|
||||
}
|
||||
|
||||
- (BOOL)isImplicitlyDisabled
|
||||
{
|
||||
return NO;
|
||||
@@ -327,6 +331,9 @@
|
||||
if (!icon) {
|
||||
icon = [self defaultIcon];
|
||||
}
|
||||
if (!selectedIcon) {
|
||||
selectedIcon = [self defaultIcon];
|
||||
}
|
||||
if (!backgroundColor) {
|
||||
backgroundColor = [self defaultBackgroundColor];
|
||||
}
|
||||
@@ -377,6 +384,7 @@
|
||||
}
|
||||
|
||||
[self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
[self setTitleColor:[self highlightedContentColor] forState: UIControlStateHighlighted | UIControlStateSelected];
|
||||
|
||||
[self setTitle:title forState:UIControlStateNormal];
|
||||
#if TARGET_OS_TV
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
/**
|
||||
@@ -25,7 +27,8 @@
|
||||
|
||||
Error codes from the SDK in the range 0-99 are reserved for this domain.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorDomain const FBSDKErrorDomain;
|
||||
FOUNDATION_EXPORT NSErrorDomain const FBSDKErrorDomain
|
||||
NS_SWIFT_NAME(ErrorDomain);
|
||||
|
||||
#else
|
||||
|
||||
@@ -34,7 +37,8 @@ FOUNDATION_EXPORT NSErrorDomain const FBSDKErrorDomain;
|
||||
|
||||
Error codes from the SDK in the range 0-99 are reserved for this domain.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorDomain;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorDomain
|
||||
NS_SWIFT_NAME(ErrorDomain);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,34 +54,40 @@ FOUNDATION_EXPORT NSString *const FBSDKErrorDomain;
|
||||
If the invalid argument is a collection, the collection can be found with this key and the individual
|
||||
invalid item can be found with FBSDKErrorArgumentValueKey.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorArgumentCollectionKey;
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorArgumentCollectionKey
|
||||
NS_SWIFT_NAME(ErrorArgumentCollectionKey);
|
||||
|
||||
/**
|
||||
The userInfo key for the invalid argument name for errors with FBSDKErrorInvalidArgument.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorArgumentNameKey;
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorArgumentNameKey
|
||||
NS_SWIFT_NAME(ErrorArgumentNameKey);
|
||||
|
||||
/**
|
||||
The userInfo key for the invalid argument value for errors with FBSDKErrorInvalidArgument.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorArgumentValueKey;
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorArgumentValueKey
|
||||
NS_SWIFT_NAME(ErrorArgumentValueKey);
|
||||
|
||||
/**
|
||||
The userInfo key for the message for developers in NSErrors that originate from the SDK.
|
||||
|
||||
The developer message will not be localized and is not intended to be presented within the app.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorDeveloperMessageKey;
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorDeveloperMessageKey
|
||||
NS_SWIFT_NAME(ErrorDeveloperMessageKey);
|
||||
|
||||
/**
|
||||
The userInfo key describing a localized description that can be presented to the user.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorLocalizedDescriptionKey;
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorLocalizedDescriptionKey
|
||||
NS_SWIFT_NAME(ErrorLocalizedDescriptionKey);
|
||||
|
||||
/**
|
||||
The userInfo key describing a localized title that can be presented to the user, used with `FBSDKLocalizedErrorDescriptionKey`.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorLocalizedTitleKey;
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorLocalizedTitleKey
|
||||
NS_SWIFT_NAME(ErrorLocalizedTitleKey);
|
||||
|
||||
/*
|
||||
@methodgroup FBSDKGraphRequest error userInfo keys
|
||||
@@ -88,36 +98,32 @@ FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKErrorLocalizedTitleKey;
|
||||
|
||||
See `FBSDKGraphErrorRecoveryProcessor` and `[FBSDKGraphRequest disableErrorRecovery]`.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorKey;
|
||||
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorCategoryKey
|
||||
DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorKey instead");
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorKey);
|
||||
|
||||
/*
|
||||
The userInfo key for the Graph API error code.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorCodeKey;
|
||||
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorCode
|
||||
DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorGraphErrorCodeKey instead");
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorCodeKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorGraphErrorCodeKey);
|
||||
|
||||
/*
|
||||
The userInfo key for the Graph API error subcode.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorSubcodeKey;
|
||||
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorSubcode
|
||||
DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorGraphErrorSubcodeKey instead");
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorSubcodeKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorGraphErrorSubcodeKey);
|
||||
|
||||
/*
|
||||
The userInfo key for the HTTP status code.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorHTTPStatusCodeKey;
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorHTTPStatusCodeKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorHTTPStatusCodeKey);
|
||||
|
||||
/*
|
||||
The userInfo key for the raw JSON response.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorParsedJSONResponseKey;
|
||||
FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorParsedJSONResponseKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorParsedJSONResponseKey);
|
||||
|
||||
#else
|
||||
|
||||
@@ -131,34 +137,40 @@ FOUNDATION_EXPORT NSErrorUserInfoKey const FBSDKGraphRequestErrorParsedJSONRespo
|
||||
If the invalid argument is a collection, the collection can be found with this key and the individual
|
||||
invalid item can be found with FBSDKErrorArgumentValueKey.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorArgumentCollectionKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorArgumentCollectionKey
|
||||
NS_SWIFT_NAME(ErrorArgumentCollectionKey);
|
||||
|
||||
/**
|
||||
The userInfo key for the invalid argument name for errors with FBSDKErrorInvalidArgument.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorArgumentNameKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorArgumentNameKey
|
||||
NS_SWIFT_NAME(ErrorArgumentNameKey);
|
||||
|
||||
/**
|
||||
The userInfo key for the invalid argument value for errors with FBSDKErrorInvalidArgument.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorArgumentValueKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorArgumentValueKey
|
||||
NS_SWIFT_NAME(ErrorArgumentValueKey);
|
||||
|
||||
/**
|
||||
The userInfo key for the message for developers in NSErrors that originate from the SDK.
|
||||
|
||||
The developer message will not be localized and is not intended to be presented within the app.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorDeveloperMessageKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorDeveloperMessageKey
|
||||
NS_SWIFT_NAME(ErrorDeveloperMessageKey);
|
||||
|
||||
/**
|
||||
The userInfo key describing a localized description that can be presented to the user.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorLocalizedDescriptionKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorLocalizedDescriptionKey
|
||||
NS_SWIFT_NAME(ErrorLocalizedDescriptionKey);
|
||||
|
||||
/**
|
||||
The userInfo key describing a localized title that can be presented to the user, used with `FBSDKLocalizedErrorDescriptionKey`.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorLocalizedTitleKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKErrorLocalizedTitleKey
|
||||
NS_SWIFT_NAME(ErrorLocalizedTitleKey);
|
||||
|
||||
/*
|
||||
@methodgroup FBSDKGraphRequest error userInfo keys
|
||||
@@ -169,39 +181,61 @@ FOUNDATION_EXPORT NSString *const FBSDKErrorLocalizedTitleKey;
|
||||
|
||||
See `FBSDKGraphErrorRecoveryProcessor` and `[FBSDKGraphRequest disableErrorRecovery]`.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorKey;
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorCategoryKey
|
||||
DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorKey instead");
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorKey);
|
||||
|
||||
/*
|
||||
The userInfo key for the Graph API error code.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorGraphErrorCodeKey;
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorGraphErrorCode
|
||||
DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorGraphErrorCodeKey instead");
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorGraphErrorCodeKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorGraphErrorCodeKey);
|
||||
|
||||
/*
|
||||
The userInfo key for the Graph API error subcode.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorGraphErrorSubcodeKey;
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorGraphErrorSubcode
|
||||
DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorGraphErrorSubcodeKey instead");
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorGraphErrorSubcodeKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorGraphErrorSubcodeKey);
|
||||
|
||||
/*
|
||||
The userInfo key for the HTTP status code.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorHTTPStatusCodeKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorHTTPStatusCodeKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorHTTPStatusCodeKey);
|
||||
|
||||
/*
|
||||
The userInfo key for the raw JSON response.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorParsedJSONResponseKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKGraphRequestErrorParsedJSONResponseKey
|
||||
NS_SWIFT_NAME(GraphRequestErrorParsedJSONResponseKey);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
@methodgroup Common Code Block typedefs
|
||||
*/
|
||||
|
||||
/**
|
||||
Success Block
|
||||
*/
|
||||
typedef void (^FBSDKCodeBlock)(void)
|
||||
NS_SWIFT_NAME(CodeBlock);
|
||||
|
||||
/**
|
||||
Error Block
|
||||
*/
|
||||
typedef void (^FBSDKErrorBlock)(NSError *_Nullable error)
|
||||
NS_SWIFT_NAME(ErrorBlock);
|
||||
|
||||
/**
|
||||
Success Block
|
||||
*/
|
||||
typedef void (^FBSDKSuccessBlock)(BOOL success, NSError *_Nullable error)
|
||||
NS_SWIFT_NAME(SuccessBlock);
|
||||
|
||||
/*
|
||||
@methodgroup Enums
|
||||
*/
|
||||
|
||||
#ifndef NS_ERROR_ENUM
|
||||
#define NS_ERROR_ENUM(_domain, _name) \
|
||||
enum _name: NSInteger _name; \
|
||||
@@ -209,10 +243,10 @@ enum __attribute__((ns_error_domain(_domain))) _name: NSInteger
|
||||
#endif
|
||||
|
||||
/**
|
||||
FBSDKError
|
||||
FBSDKCoreError
|
||||
Error codes for FBSDKErrorDomain.
|
||||
*/
|
||||
typedef NS_ERROR_ENUM(FBSDKErrorDomain, FBSDKError)
|
||||
typedef NS_ERROR_ENUM(FBSDKErrorDomain, FBSDKCoreError)
|
||||
{
|
||||
/**
|
||||
Reserved.
|
||||
@@ -289,7 +323,7 @@ typedef NS_ERROR_ENUM(FBSDKErrorDomain, FBSDKError)
|
||||
Indicates an app switch to the browser (typically for a dialog) failed.
|
||||
*/
|
||||
FBSDKErrorBrowserUnavailable,
|
||||
};
|
||||
} NS_SWIFT_NAME(CoreError);
|
||||
|
||||
/**
|
||||
FBSDKGraphRequestError
|
||||
@@ -303,11 +337,12 @@ typedef NS_ENUM(NSUInteger, FBSDKGraphRequestError)
|
||||
FBSDKGraphRequestErrorTransient = 1,
|
||||
/** Indicates the error can be recovered (such as requiring a login). A recoveryAttempter will be provided with the error instance that can take UI action. */
|
||||
FBSDKGraphRequestErrorRecoverable = 2
|
||||
};
|
||||
} NS_SWIFT_NAME(GraphRequestError);
|
||||
|
||||
/**
|
||||
a formal protocol very similar to the informal protocol NSErrorRecoveryAttempting
|
||||
*/
|
||||
NS_SWIFT_UNAVAILABLE("")
|
||||
@protocol FBSDKErrorRecoveryAttempting<NSObject>
|
||||
|
||||
/**
|
||||
@@ -325,37 +360,11 @@ typedef NS_ENUM(NSUInteger, FBSDKGraphRequestError)
|
||||
|
||||
The value passed for didRecover must be YES if error recovery was completely successful, NO otherwise.
|
||||
*/
|
||||
- (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo;
|
||||
|
||||
- (void)attemptRecoveryFromError:(NSError *)error
|
||||
optionIndex:(NSUInteger)recoveryOptionIndex
|
||||
delegate:(nullable id)delegate
|
||||
didRecoverSelector:(SEL)didRecoverSelector
|
||||
contextInfo:(nullable void *)contextInfo;
|
||||
@end
|
||||
|
||||
/**
|
||||
Deprecated
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, FBSDKErrorCode)
|
||||
{
|
||||
FBSDKReservedErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorReserved instead") = 0,
|
||||
FBSDKEncryptionErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorEncryption instead"),
|
||||
FBSDKInvalidArgumentErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorInvalidArgument instead"),
|
||||
FBSDKUnknownErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorUnknown instead"),
|
||||
FBSDKNetworkErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorNetwork instead"),
|
||||
FBSDKAppEventsFlushErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorAppEventsFlush instead"),
|
||||
FBSDKGraphRequestNonTextMimeTypeReturnedErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorGraphRequestNonTextMimeTypeReturned instead"),
|
||||
FBSDKGraphRequestProtocolMismatchErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorGraphRequestProtocolMismatch instead"),
|
||||
FBSDKGraphRequestGraphAPIErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorGraphRequestGraphAPI instead"),
|
||||
FBSDKDialogUnavailableErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorDialogUnavailable instead"),
|
||||
FBSDKAccessTokenRequiredErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorAccessTokenRequired instead"),
|
||||
FBSDKAppVersionUnsupportedErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorAppVersionUnsupported instead"),
|
||||
FBSDKBrowserUnavailableErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorBrowserUnavailable instead"),
|
||||
FBSDKBrowswerUnavailableErrorCode DEPRECATED_MSG_ATTRIBUTE("use FBSDKErrorBrowserUnavailable instead") = FBSDKBrowserUnavailableErrorCode,
|
||||
} DEPRECATED_MSG_ATTRIBUTE("use FBSDKError instead");
|
||||
|
||||
/**
|
||||
Deprecated
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKGraphRequestErrorCategory)
|
||||
{
|
||||
FBSDKGraphRequestErrorCategoryOther DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorOther instead") = 0,
|
||||
FBSDKGraphRequestErrorCategoryTransient DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorTransient instead") = 1,
|
||||
FBSDKGraphRequestErrorCategoryRecoverable DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestErrorRecoverable instead") = 2
|
||||
} DEPRECATED_MSG_ATTRIBUTE("use FBSDKGraphRequestError instead");
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -38,12 +38,10 @@ NSErrorUserInfoKey const FBSDKErrorDeveloperMessageKey = @"com.facebook.sdk:FBSD
|
||||
NSErrorUserInfoKey const FBSDKErrorLocalizedDescriptionKey = @"com.facebook.sdk:FBSDKErrorLocalizedDescriptionKey";
|
||||
NSErrorUserInfoKey const FBSDKErrorLocalizedTitleKey = @"com.facebook.sdk:FBSDKErrorLocalizedErrorTitleKey";
|
||||
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorKey = @"com.facebook.sdk:FBSDKGraphRequestErrorCategoryKey";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorKey = @"com.facebook.sdk:FBSDKGraphRequestErrorKey";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorCategoryKey = @"com.facebook.sdk:FBSDKGraphRequestErrorCategoryKey";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorCodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCode";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorCode = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCode";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorSubcodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorSubcode";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorSubcode = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorSubcode";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorCodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCodeKey";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorGraphErrorSubcodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorSubcodeKey";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorHTTPStatusCodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorHTTPStatusCodeKey";
|
||||
NSErrorUserInfoKey const FBSDKGraphRequestErrorParsedJSONResponseKey = @"com.facebook.sdk:FBSDKGraphRequestErrorParsedJSONResponseKey";
|
||||
|
||||
@@ -58,10 +56,8 @@ NSString *const FBSDKErrorLocalizedTitleKey = @"com.facebook.sdk:FBSDKErrorLocal
|
||||
|
||||
NSString *const FBSDKGraphRequestErrorKey = @"com.facebook.sdk:FBSDKGraphRequestErrorCategoryKey";
|
||||
NSString *const FBSDKGraphRequestErrorCategoryKey = @"com.facebook.sdk:FBSDKGraphRequestErrorCategoryKey";
|
||||
NSString *const FBSDKGraphRequestErrorGraphErrorCodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCode";
|
||||
NSString *const FBSDKGraphRequestErrorGraphErrorCode = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCode";
|
||||
NSString *const FBSDKGraphRequestErrorGraphErrorSubcodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorSubcode";
|
||||
NSString *const FBSDKGraphRequestErrorGraphErrorSubcode = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorSubcode";
|
||||
NSString *const FBSDKGraphRequestErrorGraphErrorCodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCodeKey";
|
||||
NSString *const FBSDKGraphRequestErrorGraphErrorSubcodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorSubcodeKey";
|
||||
NSString *const FBSDKGraphRequestErrorHTTPStatusCodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorHTTPStatusCodeKey";
|
||||
NSString *const FBSDKGraphRequestErrorParsedJSONResponseKey = @"com.facebook.sdk:FBSDKGraphRequestErrorParsedJSONResponseKey";
|
||||
|
||||
|
||||
@@ -18,11 +18,14 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Extension protocol for NSCopying that adds the copy method, which is implemented on NSObject.
|
||||
|
||||
NSObject<NSCopying> implicitly conforms to this protocol.
|
||||
*/
|
||||
NS_SWIFT_NAME(Copying)
|
||||
@protocol FBSDKCopying <NSCopying, NSObject>
|
||||
|
||||
/**
|
||||
@@ -32,3 +35,5 @@
|
||||
- (id)copy;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -27,7 +27,6 @@
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequest.h>
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequestConnection.h>
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequestDataAttachment.h>
|
||||
#import <FBSDKCoreKit/FBSDKMacros.h>
|
||||
#import <FBSDKCoreKit/FBSDKSettings.h>
|
||||
#import <FBSDKCoreKit/FBSDKTestUsersManager.h>
|
||||
#import <FBSDKCoreKit/FBSDKUtility.h>
|
||||
@@ -53,5 +52,5 @@
|
||||
#import <FBSDKCoreKit/FBSDKDeviceViewControllerBase.h>
|
||||
#endif
|
||||
|
||||
#define FBSDK_VERSION_STRING @"4.41.0"
|
||||
#define FBSDK_TARGET_PLATFORM_VERSION @"v3.2"
|
||||
#define FBSDK_VERSION_STRING @"5.8.0"
|
||||
#define FBSDK_TARGET_PLATFORM_VERSION @"v4.0"
|
||||
+21
-6
@@ -20,12 +20,15 @@
|
||||
|
||||
#import "FBSDKConstants.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class FBSDKGraphErrorRecoveryProcessor;
|
||||
@class FBSDKGraphRequest;
|
||||
|
||||
/**
|
||||
Defines a delegate for `FBSDKGraphErrorRecoveryProcessor`.
|
||||
*/
|
||||
NS_SWIFT_NAME(GraphErrorRecoveryProcessorDelegate)
|
||||
@protocol FBSDKGraphErrorRecoveryProcessorDelegate<NSObject>
|
||||
|
||||
/**
|
||||
@@ -34,7 +37,9 @@
|
||||
@param didRecover YES if the recovery was successful.
|
||||
@param error the error that that was attempted to be recovered from.
|
||||
*/
|
||||
- (void)processorDidAttemptRecovery:(FBSDKGraphErrorRecoveryProcessor *)processor didRecover:(BOOL)didRecover error:(NSError *)error;
|
||||
- (void)processorDidAttemptRecovery:(FBSDKGraphErrorRecoveryProcessor *)processor
|
||||
didRecover:(BOOL)didRecover
|
||||
error:(nullable NSError *)error;
|
||||
|
||||
@optional
|
||||
/**
|
||||
@@ -46,10 +51,15 @@
|
||||
if you want to prevent alerts of localized messages but otherwise perform retries and recoveries,
|
||||
you could return NO for errors where userInfo[FBSDKGraphRequestErrorKey] equal to FBSDKGraphRequestErrorOther
|
||||
*/
|
||||
- (BOOL)processorWillProcessError:(FBSDKGraphErrorRecoveryProcessor *)processor error:(NSError *)error;
|
||||
- (BOOL)processorWillProcessError:(FBSDKGraphErrorRecoveryProcessor *)processor
|
||||
error:(nullable NSError *)error;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Defines a type that can process Facebook NSErrors with best practices.
|
||||
|
||||
@@ -69,17 +79,18 @@
|
||||
Note that Facebook recovery attempters can present UI or even cause app switches (such as to login). Any such
|
||||
work is dispatched to the main thread (therefore your request handlers may then run on the main thread).
|
||||
|
||||
Login recovery requires FBSDKLoginKit. Login will use FBSDKLoginBehaviorNative and will prompt the user
|
||||
Login recovery requires FBSDKLoginKit. Login will prompt the user
|
||||
for all permissions last granted. If any are declined on the new request, the recovery is not successful but
|
||||
the `[FBSDKAccessToken currentAccessToken]` might still have been updated.
|
||||
.
|
||||
*/
|
||||
NS_SWIFT_UNAVAILABLE("")
|
||||
@interface FBSDKGraphErrorRecoveryProcessor : NSObject
|
||||
|
||||
/**
|
||||
Gets the delegate. Note this is a strong reference, and is nil'ed out after recovery is complete.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) id<FBSDKGraphErrorRecoveryProcessorDelegate>delegate;
|
||||
@property (nonatomic, strong, readonly, nullable) id<FBSDKGraphErrorRecoveryProcessorDelegate>delegate;
|
||||
|
||||
/**
|
||||
Attempts to process the error, return YES if the error can be processed.
|
||||
@@ -87,13 +98,17 @@
|
||||
@param request the related request that may be reissued.
|
||||
@param delegate the delegate that will be retained until recovery is complete.
|
||||
*/
|
||||
- (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request delegate:(id<FBSDKGraphErrorRecoveryProcessorDelegate>) delegate;
|
||||
- (BOOL)processError:(NSError *)error
|
||||
request:(FBSDKGraphRequest *)request
|
||||
delegate:(nullable id<FBSDKGraphErrorRecoveryProcessorDelegate>)delegate;
|
||||
|
||||
/**
|
||||
The callback for FBSDKErrorRecoveryAttempting
|
||||
@param didRecover if the recovery succeeded
|
||||
@param contextInfo unused
|
||||
*/
|
||||
- (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(void *)contextInfo;
|
||||
- (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(nullable void *)contextInfo;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+4
-29
@@ -17,7 +17,8 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#import "FBSDKGraphErrorRecoveryProcessor.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
#import "FBSDKErrorRecoveryAttempter.h"
|
||||
|
||||
@interface FBSDKGraphErrorRecoveryProcessor()
|
||||
@@ -26,18 +27,13 @@
|
||||
NSError *_error;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) id<FBSDKGraphErrorRecoveryProcessorDelegate>delegate;
|
||||
@property (nonatomic, strong, nullable) id<FBSDKGraphErrorRecoveryProcessorDelegate>delegate;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBSDKGraphErrorRecoveryProcessor
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request delegate:(id<FBSDKGraphErrorRecoveryProcessorDelegate>) delegate
|
||||
- (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request delegate:(id<FBSDKGraphErrorRecoveryProcessorDelegate>)delegate
|
||||
{
|
||||
self.delegate = delegate;
|
||||
if ([self.delegate respondsToSelector:@selector(processorWillProcessError:error:)]) {
|
||||
@@ -55,7 +51,6 @@
|
||||
case FBSDKGraphRequestErrorRecoverable :
|
||||
if ([request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) {
|
||||
_recoveryAttempter = error.recoveryAttempter;
|
||||
BOOL isLoginRecoveryAttempter = [_recoveryAttempter isKindOfClass:NSClassFromString(@"_FBSDKLoginRecoveryAttempter")];
|
||||
|
||||
// Set up a block to do the typical recovery work so that we can chain it for ios auth special cases.
|
||||
// the block returns YES if recovery UI is started (meaning we wait for the alertviewdelegate to resume control flow).
|
||||
@@ -72,26 +67,6 @@
|
||||
return NO;
|
||||
};
|
||||
|
||||
if ([request.tokenString isEqualToString:[FBSDKSystemAccountStoreAdapter sharedInstance].accessTokenString] &&
|
||||
isLoginRecoveryAttempter) {
|
||||
// special system auth case: if user has granted permissions we can simply renew. On a successful
|
||||
// renew, treat this as immediately recovered without the standard alert prompty.
|
||||
// (for example, this can repair expired tokens seamlessly)
|
||||
[[FBSDKSystemAccountStoreAdapter sharedInstance]
|
||||
renewSystemAuthorization:^(ACAccountCredentialRenewResult result, NSError *renewError) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (result == ACAccountCredentialRenewResultRenewed) {
|
||||
[self.delegate processorDidAttemptRecovery:self didRecover:YES error:nil];
|
||||
self.delegate = nil;
|
||||
} else if (!standardRecoveryWork()) {
|
||||
[self.delegate processorDidAttemptRecovery:self didRecover:NO error:self->_error];
|
||||
};
|
||||
});
|
||||
}];
|
||||
// short-circuit YES so that the renew callback resumes the control flow.
|
||||
return YES;
|
||||
}
|
||||
|
||||
return standardRecoveryWork();
|
||||
}
|
||||
return NO;
|
||||
|
||||
@@ -20,8 +20,22 @@
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequestConnection.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class FBSDKAccessToken;
|
||||
|
||||
/// typedef for FBSDKHTTPMethod
|
||||
typedef NSString *const FBSDKHTTPMethod NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAME(HTTPMethod);
|
||||
|
||||
/// GET Request
|
||||
FOUNDATION_EXPORT FBSDKHTTPMethod FBSDKHTTPMethodGET NS_SWIFT_NAME(get);
|
||||
|
||||
/// POST Request
|
||||
FOUNDATION_EXPORT FBSDKHTTPMethod FBSDKHTTPMethodPOST NS_SWIFT_NAME(post);
|
||||
|
||||
/// DELETE Request
|
||||
FOUNDATION_EXPORT FBSDKHTTPMethod FBSDKHTTPMethodDELETE NS_SWIFT_NAME(delete);
|
||||
|
||||
/**
|
||||
Represents a request to the Facebook Graph API.
|
||||
|
||||
@@ -41,28 +55,43 @@
|
||||
|
||||
@see FBSDKGraphErrorRecoveryProcessor
|
||||
*/
|
||||
NS_SWIFT_NAME(GraphRequest)
|
||||
@interface FBSDKGraphRequest : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`.
|
||||
Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`.
|
||||
@param graphPath the graph path (e.g., @"me").
|
||||
@param parameters the optional parameters dictionary.
|
||||
*/
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath;
|
||||
|
||||
/**
|
||||
Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`.
|
||||
@param graphPath the graph path (e.g., @"me").
|
||||
@param method the HTTP method. Empty String defaults to @"GET".
|
||||
*/
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
parameters:(NSDictionary *)parameters;
|
||||
HTTPMethod:(FBSDKHTTPMethod)method;
|
||||
|
||||
/**
|
||||
Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`.
|
||||
@param graphPath the graph path (e.g., @"me").
|
||||
@param parameters the optional parameters dictionary.
|
||||
@param HTTPMethod the optional HTTP method. nil defaults to @"GET".
|
||||
*/
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
parameters:(NSDictionary *)parameters
|
||||
HTTPMethod:(NSString *)HTTPMethod;
|
||||
parameters:(NSDictionary<NSString *, id> *)parameters;
|
||||
|
||||
/**
|
||||
Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`.
|
||||
@param graphPath the graph path (e.g., @"me").
|
||||
@param parameters the optional parameters dictionary.
|
||||
@param method the HTTP method. Empty String defaults to @"GET".
|
||||
*/
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
parameters:(NSDictionary<NSString *, id> *)parameters
|
||||
HTTPMethod:(FBSDKHTTPMethod)method;
|
||||
|
||||
/**
|
||||
Initializes a new instance.
|
||||
@@ -70,24 +99,24 @@
|
||||
@param parameters the optional parameters dictionary.
|
||||
@param tokenString the token string to use. Specifying nil will cause no token to be used.
|
||||
@param version the optional Graph API version (e.g., @"v2.0"). nil defaults to `[FBSDKSettings graphAPIVersion]`.
|
||||
@param HTTPMethod the optional HTTP method (e.g., @"POST"). nil defaults to @"GET".
|
||||
@param method the HTTP method. Empty String defaults to @"GET".
|
||||
*/
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
parameters:(NSDictionary *)parameters
|
||||
tokenString:(NSString *)tokenString
|
||||
version:(NSString *)version
|
||||
HTTPMethod:(NSString *)HTTPMethod
|
||||
parameters:(NSDictionary<NSString *, id> *)parameters
|
||||
tokenString:(nullable NSString *)tokenString
|
||||
version:(nullable NSString *)version
|
||||
HTTPMethod:(FBSDKHTTPMethod)method
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
The request parameters.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSMutableDictionary *parameters;
|
||||
@property (nonatomic, copy) NSDictionary<NSString *, id> *parameters;
|
||||
|
||||
/**
|
||||
The access token string used by the request.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *tokenString;
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *tokenString;
|
||||
|
||||
/**
|
||||
The Graph API endpoint to use for the request, for example "me".
|
||||
@@ -97,7 +126,7 @@ NS_DESIGNATED_INITIALIZER;
|
||||
/**
|
||||
The HTTPMethod to use for the request, for example "GET" or "POST".
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *HTTPMethod;
|
||||
@property (nonatomic, copy, readonly) FBSDKHTTPMethod HTTPMethod;
|
||||
|
||||
/**
|
||||
The Graph API version to use (e.g., "v2.0")
|
||||
@@ -115,12 +144,15 @@ NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
This will override [FBSDKSettings setGraphErrorRecoveryDisabled:].
|
||||
*/
|
||||
- (void)setGraphErrorRecoveryDisabled:(BOOL)disable;
|
||||
- (void)setGraphErrorRecoveryDisabled:(BOOL)disable
|
||||
NS_SWIFT_NAME(setGraphErrorRecovery(disabled:));
|
||||
|
||||
/**
|
||||
Starts a connection to the Graph API.
|
||||
@param handler The handler block to call when the request completes.
|
||||
*/
|
||||
- (FBSDKGraphRequestConnection *)startWithCompletionHandler:(FBSDKGraphRequestHandler)handler;
|
||||
- (FBSDKGraphRequestConnection *)startWithCompletionHandler:(nullable FBSDKGraphRequestBlock)handler;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -29,15 +29,28 @@
|
||||
#import "FBSDKSettings+Internal.h"
|
||||
|
||||
// constants
|
||||
static NSString *const kGetHTTPMethod = @"GET";
|
||||
static NSString *const kPostHTTPMethod = @"POST";
|
||||
FBSDKHTTPMethod FBSDKHTTPMethodGET = @"GET";
|
||||
FBSDKHTTPMethod FBSDKHTTPMethodPOST = @"POST";
|
||||
FBSDKHTTPMethod FBSDKHTTPMethodDELETE = @"DELETE";
|
||||
|
||||
@interface FBSDKGraphRequest()
|
||||
@property (nonatomic, assign) FBSDKGraphRequestFlags flags;
|
||||
@property (nonatomic, copy, readwrite) FBSDKHTTPMethod HTTPMethod;
|
||||
@end
|
||||
|
||||
@implementation FBSDKGraphRequest
|
||||
|
||||
@synthesize HTTPMethod;
|
||||
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath {
|
||||
return [self initWithGraphPath:graphPath parameters:@{}];
|
||||
}
|
||||
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
HTTPMethod:(FBSDKHTTPMethod)method {
|
||||
return [self initWithGraphPath:graphPath parameters:@{} HTTPMethod:method];
|
||||
}
|
||||
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
parameters:(NSDictionary *)parameters {
|
||||
return [self initWithGraphPath:graphPath
|
||||
@@ -47,12 +60,12 @@ static NSString *const kPostHTTPMethod = @"POST";
|
||||
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
parameters:(NSDictionary *)parameters
|
||||
HTTPMethod:(NSString *)HTTPMethod {
|
||||
HTTPMethod:(FBSDKHTTPMethod)method {
|
||||
return [self initWithGraphPath:graphPath
|
||||
parameters:parameters
|
||||
tokenString:[FBSDKAccessToken currentAccessToken].tokenString
|
||||
version:nil
|
||||
HTTPMethod:HTTPMethod];
|
||||
HTTPMethod:method];
|
||||
}
|
||||
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
@@ -61,20 +74,20 @@ static NSString *const kPostHTTPMethod = @"POST";
|
||||
return [self initWithGraphPath:graphPath
|
||||
parameters:parameters
|
||||
tokenString:[FBSDKAccessToken currentAccessToken].tokenString
|
||||
HTTPMethod:nil
|
||||
HTTPMethod:FBSDKHTTPMethodGET
|
||||
flags:flags];
|
||||
}
|
||||
|
||||
- (instancetype)initWithGraphPath:(NSString *)graphPath
|
||||
parameters:(NSDictionary *)parameters
|
||||
tokenString:(NSString *)tokenString
|
||||
HTTPMethod:(NSString *)HTTPMethod
|
||||
HTTPMethod:(FBSDKHTTPMethod)method
|
||||
flags:(FBSDKGraphRequestFlags)flags {
|
||||
if ((self = [self initWithGraphPath:graphPath
|
||||
parameters:parameters
|
||||
tokenString:tokenString
|
||||
version:[FBSDKSettings graphAPIVersion]
|
||||
HTTPMethod:HTTPMethod])) {
|
||||
HTTPMethod:method])) {
|
||||
self.flags |= flags;
|
||||
}
|
||||
return self;
|
||||
@@ -84,14 +97,14 @@ static NSString *const kPostHTTPMethod = @"POST";
|
||||
parameters:(NSDictionary *)parameters
|
||||
tokenString:(NSString *)tokenString
|
||||
version:(NSString *)version
|
||||
HTTPMethod:(NSString *)HTTPMethod {
|
||||
HTTPMethod:(FBSDKHTTPMethod)method {
|
||||
if ((self = [super init])) {
|
||||
_tokenString = [tokenString copy];
|
||||
_tokenString = tokenString ? [tokenString copy] : nil;
|
||||
_version = version ? [version copy] : [FBSDKSettings graphAPIVersion];
|
||||
_graphPath = [graphPath copy];
|
||||
_HTTPMethod = HTTPMethod ? [HTTPMethod copy] : kGetHTTPMethod;
|
||||
_parameters = [[NSMutableDictionary alloc] initWithDictionary:parameters];
|
||||
if ([FBSDKSettings isGraphErrorRecoveryDisabled]) {
|
||||
self.HTTPMethod = method.length > 0 ? [method copy] : FBSDKHTTPMethodGET;
|
||||
_parameters = parameters ?: @{};
|
||||
if (!FBSDKSettings.isGraphErrorRecoveryEnabled) {
|
||||
_flags = FBSDKGraphRequestFlagDisableErrorRecovery;
|
||||
}
|
||||
}
|
||||
@@ -134,7 +147,7 @@ static NSString *const kPostHTTPMethod = @"POST";
|
||||
|
||||
+ (NSString *)serializeURL:(NSString *)baseUrl
|
||||
params:(NSDictionary *)params {
|
||||
return [self serializeURL:baseUrl params:params httpMethod:kGetHTTPMethod];
|
||||
return [self serializeURL:baseUrl params:params httpMethod:FBSDKHTTPMethodGET];
|
||||
}
|
||||
|
||||
+ (NSString *)serializeURL:(NSString *)baseUrl
|
||||
@@ -154,15 +167,15 @@ static NSString *const kPostHTTPMethod = @"POST";
|
||||
NSURL *parsedURL = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
|
||||
#pragma clang pop
|
||||
|
||||
if ([httpMethod isEqualToString:kPostHTTPMethod] && !forBatch) {
|
||||
if ([httpMethod isEqualToString:FBSDKHTTPMethodPOST] && !forBatch) {
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
NSString *queryPrefix = parsedURL.query ? @"&" : @"?";
|
||||
|
||||
NSString *query = [FBSDKInternalUtility queryStringWithDictionary:params error:NULL invalidObjectHandler:^id(id object, BOOL *stop) {
|
||||
NSString *query = [FBSDKBasicUtility queryStringWithDictionary:params error:NULL invalidObjectHandler:^id(id object, BOOL *stop) {
|
||||
if ([self isAttachment:object]) {
|
||||
if ([httpMethod isEqualToString:kGetHTTPMethod]) {
|
||||
if ([httpMethod isEqualToString:FBSDKHTTPMethodGET]) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"can not use GET to upload a file"];
|
||||
}
|
||||
return nil;
|
||||
@@ -184,7 +197,7 @@ static NSString *const kPostHTTPMethod = @"POST";
|
||||
return params;
|
||||
}
|
||||
|
||||
- (FBSDKGraphRequestConnection *)startWithCompletionHandler:(FBSDKGraphRequestHandler)handler
|
||||
- (FBSDKGraphRequestConnection *)startWithCompletionHandler:(FBSDKGraphRequestBlock)handler
|
||||
{
|
||||
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
|
||||
[connection addRequest:self completionHandler:handler];
|
||||
|
||||
+49
-71
@@ -18,32 +18,45 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
The key in the result dictionary for requests to old versions of the Graph API
|
||||
whose response is not a JSON object.
|
||||
|
||||
|
||||
When a request returns a non-JSON response (such as a "true" literal), that response
|
||||
will be wrapped into a dictionary using this const as the key. This only applies for very few Graph API
|
||||
prior to v2.1.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKNonJSONResponseProperty
|
||||
NS_SWIFT_NAME(NonJSONResponseProperty);
|
||||
|
||||
@class FBSDKGraphRequest;
|
||||
@class FBSDKGraphRequestConnection;
|
||||
|
||||
/**
|
||||
FBSDKGraphRequestHandler
|
||||
FBSDKGraphRequestBlock
|
||||
|
||||
A block that is passed to addRequest to register for a callback with the results of that
|
||||
request once the connection completes.
|
||||
|
||||
|
||||
|
||||
Pass a block of this type when calling addRequest. This will be called once
|
||||
the request completes. The call occurs on the UI thread.
|
||||
|
||||
@param connection The `FBSDKGraphRequestConnection` that sent the request.
|
||||
@param connection The `FBSDKGraphRequestConnection` that sent the request.
|
||||
|
||||
@param result The result of the request. This is a translation of
|
||||
@param result The result of the request. This is a translation of
|
||||
JSON data to `NSDictionary` and `NSArray` objects. This
|
||||
is nil if there was an error.
|
||||
|
||||
@param error The `NSError` representing any error that occurred.
|
||||
@param error The `NSError` representing any error that occurred.
|
||||
|
||||
*/
|
||||
typedef void (^FBSDKGraphRequestHandler)(FBSDKGraphRequestConnection *connection,
|
||||
id result,
|
||||
NSError *error);
|
||||
typedef void (^FBSDKGraphRequestBlock)(FBSDKGraphRequestConnection *_Nullable connection,
|
||||
id _Nullable result,
|
||||
NSError *_Nullable error)
|
||||
NS_SWIFT_NAME(GraphRequestBlock);
|
||||
|
||||
/**
|
||||
@protocol
|
||||
@@ -51,6 +64,7 @@ typedef void (^FBSDKGraphRequestHandler)(FBSDKGraphRequestConnection *connection
|
||||
The `FBSDKGraphRequestConnectionDelegate` protocol defines the methods used to receive network
|
||||
activity progress information from a <FBSDKGraphRequestConnection>.
|
||||
*/
|
||||
NS_SWIFT_NAME(GraphRequestConnectionDelegate)
|
||||
@protocol FBSDKGraphRequestConnectionDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
@@ -79,7 +93,7 @@ typedef void (^FBSDKGraphRequestHandler)(FBSDKGraphRequestConnection *connection
|
||||
|
||||
If the request connection completes without a network error occurring then this method is called.
|
||||
Invocation of this method does not indicate success of every <FBSDKGraphRequest> made, only that the
|
||||
request connection has no further activity. Use the error argument passed to the FBSDKGraphRequestHandler
|
||||
request connection has no further activity. Use the error argument passed to the FBSDKGraphRequestBlock
|
||||
block to determine success or failure of each <FBSDKGraphRequest>.
|
||||
|
||||
This method is invoked after the completion handler for each <FBSDKGraphRequest>.
|
||||
@@ -97,7 +111,7 @@ typedef void (^FBSDKGraphRequestHandler)(FBSDKGraphRequestConnection *connection
|
||||
|
||||
If the request connection fails with a network error then this method is called. The `error`
|
||||
argument specifies why the network connection failed. The `NSError` object passed to the
|
||||
FBSDKGraphRequestHandler block may contain additional information.
|
||||
FBSDKGraphRequestBlock block may contain additional information.
|
||||
|
||||
@param connection The request connection that successfully completed a network request
|
||||
@param error The `NSError` representing the network error that occurred, if any. May be nil
|
||||
@@ -141,12 +155,18 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
|
||||
e.g. starting a connection, canceling a connection, or batching requests.
|
||||
|
||||
*/
|
||||
NS_SWIFT_NAME(GraphRequestConnection)
|
||||
@interface FBSDKGraphRequestConnection : NSObject
|
||||
|
||||
/**
|
||||
The default timeout on all FBSDKGraphRequestConnection instances. Defaults to 60 seconds.
|
||||
*/
|
||||
@property (class, nonatomic, assign) NSTimeInterval defaultConnectionTimeout;
|
||||
|
||||
/**
|
||||
The delegate object that receives updates.
|
||||
*/
|
||||
@property (nonatomic, weak) id<FBSDKGraphRequestConnectionDelegate> delegate;
|
||||
@property (nonatomic, weak, nullable) id<FBSDKGraphRequestConnectionDelegate> delegate;
|
||||
|
||||
/**
|
||||
Gets or sets the timeout interval to wait for a response before giving up.
|
||||
@@ -162,23 +182,22 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
|
||||
the server.
|
||||
|
||||
The property is nil until the request completes. If there was a response
|
||||
then this property will be non-nil during the FBSDKGraphRequestHandler callback.
|
||||
then this property will be non-nil during the FBSDKGraphRequestBlock callback.
|
||||
*/
|
||||
@property (nonatomic, retain, readonly) NSHTTPURLResponse *URLResponse;
|
||||
@property (nonatomic, retain, readonly, nullable) NSHTTPURLResponse *urlResponse;
|
||||
|
||||
/**
|
||||
Determines the operation queue that is used to call methods on the connection's delegate.
|
||||
|
||||
By default, a connection is scheduled on the current thread in the default mode when it is created.
|
||||
You cannot reschedule a connection after it has started.
|
||||
*/
|
||||
@property (nonatomic, retain) NSOperationQueue *delegateQueue;
|
||||
|
||||
/**
|
||||
@methodgroup Class methods
|
||||
*/
|
||||
|
||||
/**
|
||||
@method
|
||||
|
||||
This method sets the default timeout on all FBSDKGraphRequestConnection instances. Defaults to 60 seconds.
|
||||
|
||||
@param defaultConnectionTimeout The timeout interval.
|
||||
*/
|
||||
+ (void)setDefaultConnectionTimeout:(NSTimeInterval)defaultConnectionTimeout;
|
||||
|
||||
/**
|
||||
@methodgroup Adding requests
|
||||
*/
|
||||
@@ -191,13 +210,11 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
|
||||
@param request A request to be included in the round-trip when start is called.
|
||||
@param handler A handler to call back when the round-trip completes or times out.
|
||||
|
||||
|
||||
|
||||
The completion handler is retained until the block is called upon the
|
||||
completion or cancellation of the connection.
|
||||
*/
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler;
|
||||
completionHandler:(FBSDKGraphRequestBlock)handler;
|
||||
|
||||
/**
|
||||
@method
|
||||
@@ -209,25 +226,18 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
|
||||
@param handler A handler to call back when the round-trip completes or times out.
|
||||
The handler will be invoked on the main thread.
|
||||
|
||||
@param name An optional name for this request. This can be used to feed
|
||||
@param name A name for this request. This can be used to feed
|
||||
the results of one request to the input of another <FBSDKGraphRequest> in the same
|
||||
`FBSDKGraphRequestConnection` as described in
|
||||
[Graph API Batch Requests]( https://developers.facebook.com/docs/reference/api/batch/ ).
|
||||
|
||||
|
||||
|
||||
The completion handler is retained until the block is called upon the
|
||||
completion or cancellation of the connection. This request can be named
|
||||
to allow for using the request's response in a subsequent request.
|
||||
*/
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
batchEntryName:(NSString *)name
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler;
|
||||
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler
|
||||
batchEntryName:(NSString *)name
|
||||
DEPRECATED_MSG_ATTRIBUTE("Renamed `addRequest:batchEntryName:completionHandler:`");
|
||||
completionHandler:(FBSDKGraphRequestBlock)handler;
|
||||
|
||||
/**
|
||||
@method
|
||||
@@ -238,24 +248,17 @@ DEPRECATED_MSG_ATTRIBUTE("Renamed `addRequest:batchEntryName:completionHandler:`
|
||||
|
||||
@param handler A handler to call back when the round-trip completes or times out.
|
||||
|
||||
@param batchParameters The optional dictionary of parameters to include for this request
|
||||
@param batchParameters The dictionary of parameters to include for this request
|
||||
as described in [Graph API Batch Requests]( https://developers.facebook.com/docs/reference/api/batch/ ).
|
||||
Examples include "depends_on", "name", or "omit_response_on_success".
|
||||
|
||||
|
||||
|
||||
The completion handler is retained until the block is called upon the
|
||||
completion or cancellation of the connection. This request can be named
|
||||
to allow for using the request's response in a subsequent request.
|
||||
*/
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
batchParameters:(NSDictionary<NSString *, id> *)batchParameters
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler;
|
||||
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler
|
||||
batchParameters:(NSDictionary *)batchParameters
|
||||
DEPRECATED_MSG_ATTRIBUTE("Renamed `addRequest:batchParameters:completionHandler:`");
|
||||
batchParameters:(nullable NSDictionary<NSString *, id> *)batchParameters
|
||||
completionHandler:(FBSDKGraphRequestBlock)handler;
|
||||
|
||||
/**
|
||||
@methodgroup Instance methods
|
||||
@@ -267,8 +270,6 @@ DEPRECATED_MSG_ATTRIBUTE("Renamed `addRequest:batchParameters:completionHandler:
|
||||
Signals that a connection should be logically terminated as the
|
||||
application is no longer interested in a response.
|
||||
|
||||
|
||||
|
||||
Synchronously calls any handlers indicating the request was cancelled. Cancel
|
||||
does not guarantee that the request-related processing will cease. It
|
||||
does promise that all handlers will complete before the cancel returns. A call to
|
||||
@@ -291,22 +292,11 @@ DEPRECATED_MSG_ATTRIBUTE("Renamed `addRequest:batchParameters:completionHandler:
|
||||
*/
|
||||
- (void)start;
|
||||
|
||||
/**
|
||||
Determines the operation queue that is used to call methods on the connection's delegate.
|
||||
@param queue The operation queue to use when calling delegate methods.
|
||||
|
||||
By default, a connection is scheduled on the current thread in the default mode when it is created.
|
||||
You cannot reschedule a connection after it has started.
|
||||
*/
|
||||
- (void)setDelegateQueue:(NSOperationQueue *)queue;
|
||||
|
||||
/**
|
||||
@method
|
||||
|
||||
Overrides the default version for a batch request
|
||||
|
||||
|
||||
|
||||
The SDK automatically prepends a version part, such as "v2.0" to API paths in order to simplify API versioning
|
||||
for applications. If you want to override the version part while using batch requests on the connection, call
|
||||
this method to set the version for the batch request.
|
||||
@@ -315,18 +305,6 @@ DEPRECATED_MSG_ATTRIBUTE("Renamed `addRequest:batchParameters:completionHandler:
|
||||
*/
|
||||
- (void)overrideGraphAPIVersion:(NSString *)version;
|
||||
|
||||
- (void)overrideVersionPartWith:(NSString *)version
|
||||
DEPRECATED_MSG_ATTRIBUTE("Renamed `overrideGraphAPIVersion`");
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
The key in the result dictionary for requests to old versions of the Graph API
|
||||
whose response is not a JSON object.
|
||||
|
||||
|
||||
When a request returns a non-JSON response (such as a "true" literal), that response
|
||||
will be wrapped into a dictionary using this const as the key. This only applies for very few Graph API
|
||||
prior to v2.1.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKNonJSONResponseProperty;
|
||||
NS_ASSUME_NONNULL_END
|
||||
+214
-134
@@ -18,9 +18,10 @@
|
||||
|
||||
#import "FBSDKGraphRequestConnection+Internal.h"
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
#import "FBSDKAppEvents+Internal.h"
|
||||
#import "FBSDKConstants.h"
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKError.h"
|
||||
#import "FBSDKErrorConfiguration.h"
|
||||
#import "FBSDKGraphRequest+Internal.h"
|
||||
@@ -73,6 +74,7 @@ static FBSDKAccessToken *_CreateExpiredAccessToken(FBSDKAccessToken *accessToken
|
||||
return [[FBSDKAccessToken alloc] initWithTokenString:accessToken.tokenString
|
||||
permissions:accessToken.permissions.allObjects
|
||||
declinedPermissions:accessToken.declinedPermissions.allObjects
|
||||
expiredPermissions:accessToken.expiredPermissions.allObjects
|
||||
appID:accessToken.appID
|
||||
userID:accessToken.userID
|
||||
expirationDate:expirationDate
|
||||
@@ -103,8 +105,7 @@ NSURLSessionDataDelegate
|
||||
#endif
|
||||
>
|
||||
|
||||
@property (nonatomic, strong) NSURLSession *session;
|
||||
@property (nonatomic, strong) FBSDKURLSessionTask *task;
|
||||
@property (nonatomic, strong) FBSDKURLSession *session;
|
||||
@property (nonatomic, retain) NSMutableArray *requests;
|
||||
@property (nonatomic, assign) FBSDKGraphRequestConnectionState state;
|
||||
@property (nonatomic, strong) FBSDKLogger *logger;
|
||||
@@ -133,13 +134,14 @@ NSURLSessionDataDelegate
|
||||
_timeout = g_defaultTimeout;
|
||||
_state = kStateCreated;
|
||||
_logger = [[FBSDKLogger alloc] initWithLoggingBehavior:FBSDKLoggingBehaviorNetworkRequests];
|
||||
_session = [[FBSDKURLSession alloc] initWithDelegate:self delegateQueue:_delegateQueue];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_session invalidateAndCancel];
|
||||
[self.session invalidateAndCancel];
|
||||
}
|
||||
|
||||
#pragma mark - Public
|
||||
@@ -151,23 +153,27 @@ NSURLSessionDataDelegate
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSTimeInterval)defaultConnectionTimeout {
|
||||
return g_defaultTimeout;
|
||||
}
|
||||
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler
|
||||
completionHandler:(FBSDKGraphRequestBlock)handler
|
||||
{
|
||||
[self addRequest:request batchEntryName:nil completionHandler:handler];
|
||||
[self addRequest:request batchEntryName:@"" completionHandler:handler];
|
||||
}
|
||||
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
batchEntryName:(NSString *)name
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler
|
||||
completionHandler:(FBSDKGraphRequestBlock)handler
|
||||
{
|
||||
NSDictionary *batchParams = (name)? @{kBatchEntryName : name } : nil;
|
||||
NSDictionary<NSString *, id> *batchParams = name.length > 0 ? @{kBatchEntryName : name } : nil;
|
||||
[self addRequest:request batchParameters:batchParams completionHandler:handler];
|
||||
}
|
||||
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
batchParameters:(NSDictionary<NSString *, id> *)batchParameters
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler
|
||||
completionHandler:(FBSDKGraphRequestBlock)handler
|
||||
{
|
||||
if (self.state != kStateCreated) {
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||
@@ -181,25 +187,10 @@ NSURLSessionDataDelegate
|
||||
[self.requests addObject:metadata];
|
||||
}
|
||||
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler
|
||||
batchEntryName:(NSString *)name
|
||||
{
|
||||
[self addRequest:request batchEntryName:name completionHandler:handler];
|
||||
}
|
||||
|
||||
- (void)addRequest:(FBSDKGraphRequest *)request
|
||||
completionHandler:(FBSDKGraphRequestHandler)handler
|
||||
batchParameters:(NSDictionary *)batchParameters
|
||||
{
|
||||
[self addRequest:request batchParameters:batchParameters completionHandler:handler];
|
||||
}
|
||||
|
||||
- (void)cancel
|
||||
{
|
||||
self.state = kStateCancelled;
|
||||
[self.task cancel];
|
||||
[self cleanUpSession];
|
||||
[self.session invalidateAndCancel];
|
||||
}
|
||||
|
||||
- (void)overrideGraphAPIVersion:(NSString *)version
|
||||
@@ -209,17 +200,25 @@ NSURLSessionDataDelegate
|
||||
}
|
||||
}
|
||||
|
||||
- (void)overrideVersionPartWith:(NSString *)version
|
||||
{
|
||||
[self overrideGraphAPIVersion:version];
|
||||
}
|
||||
|
||||
- (void)start
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
g_errorConfiguration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil];
|
||||
});
|
||||
|
||||
if (![FBSDKApplicationDelegate isSDKInitialized]) {
|
||||
NSString *msg = @"FBSDKGraphRequestConnection cannot be started before Facebook SDK initialized.";
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
|
||||
formatString:@"%@", msg];
|
||||
self.state = kStateCancelled;
|
||||
[self completeFBSDKURLSessionWithResponse:nil
|
||||
data:nil
|
||||
networkError:[FBSDKError unknownErrorWithMessage:msg]];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//optimistically check for updated server configuration;
|
||||
g_errorConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration].errorConfiguration ?: g_errorConfiguration;
|
||||
|
||||
@@ -236,22 +235,22 @@ NSURLSessionDataDelegate
|
||||
[self logRequest:request bodyLength:0 bodyLogger:nil attachmentLogger:nil];
|
||||
_requestStartTime = [FBSDKInternalUtility currentTimeInMilliseconds];
|
||||
|
||||
FBSDKURLSessionTaskHandler handler = ^(NSError *error,
|
||||
NSURLResponse *response,
|
||||
NSData *responseData) {
|
||||
[self completeFBSDKURLSessionWithResponse:response
|
||||
data:responseData
|
||||
networkError:error];
|
||||
FBSDKURLSessionTaskBlock completionHanlder = ^(NSData *responseDataV1, NSURLResponse *responseV1, NSError *errorV1) {
|
||||
FBSDKURLSessionTaskBlock handler = ^(NSData *responseDataV2,
|
||||
NSURLResponse *responseV2,
|
||||
NSError *errorV2) {
|
||||
[self completeFBSDKURLSessionWithResponse:responseV2
|
||||
data:responseDataV2
|
||||
networkError:errorV2];
|
||||
};
|
||||
|
||||
if(errorV1) {
|
||||
[self taskDidCompleteWithError:errorV1 handler:handler];
|
||||
} else {
|
||||
[self taskDidCompleteWithResponse:responseV1 data:responseDataV1 requestStartTime:self.requestStartTime handler:handler];
|
||||
}
|
||||
};
|
||||
|
||||
if (!self.session) {
|
||||
self.session = [self defaultSession];
|
||||
}
|
||||
|
||||
self.task = [[FBSDKURLSessionTask alloc] initWithRequest:request
|
||||
fromSession:self.session
|
||||
completionHandler:handler];
|
||||
[self.task start];
|
||||
[self.session executeURLRequest:request completionHandler:completionHanlder];
|
||||
|
||||
id<FBSDKGraphRequestConnectionDelegate> delegate = self.delegate;
|
||||
if ([delegate respondsToSelector:@selector(requestConnectionWillBeginLoading:)]) {
|
||||
@@ -265,8 +264,14 @@ NSURLSessionDataDelegate
|
||||
}
|
||||
}
|
||||
|
||||
- (NSOperationQueue *)delegateQueue
|
||||
{
|
||||
return _delegateQueue;
|
||||
}
|
||||
|
||||
- (void)setDelegateQueue:(NSOperationQueue *)queue
|
||||
{
|
||||
_session.delegateQueue = queue;
|
||||
_delegateQueue = queue;
|
||||
}
|
||||
|
||||
@@ -289,7 +294,10 @@ NSURLSessionDataDelegate
|
||||
}
|
||||
|
||||
if (batchToken) {
|
||||
metadata.request.parameters[kAccessTokenKey] = batchToken;
|
||||
NSMutableDictionary<NSString *, id> *params = [NSMutableDictionary
|
||||
dictionaryWithDictionary:metadata.request.parameters];
|
||||
params[kAccessTokenKey] = batchToken;
|
||||
metadata.request.parameters = params;
|
||||
[self registerTokenToOmitFromLog:batchToken];
|
||||
}
|
||||
|
||||
@@ -322,7 +330,7 @@ NSURLSessionDataDelegate
|
||||
logger:(FBSDKLogger *)logger
|
||||
{
|
||||
[attachments enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
|
||||
value = [FBSDKInternalUtility convertRequestValue:value];
|
||||
value = [FBSDKBasicUtility convertRequestValue:value];
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
if (addFormData) {
|
||||
[body appendWithKey:key formValue:(NSString *)value logger:logger];
|
||||
@@ -367,7 +375,7 @@ NSURLSessionDataDelegate
|
||||
batchToken:[batchToken isEqualToString:individualToken] ? nil : individualToken];
|
||||
}
|
||||
|
||||
NSString *jsonBatch = [FBSDKInternalUtility JSONStringForObject:batch error:NULL invalidObjectHandler:NULL];
|
||||
NSString *jsonBatch = [FBSDKBasicUtility JSONStringForObject:batch error:NULL invalidObjectHandler:NULL];
|
||||
|
||||
[body appendWithKey:kBatchKey formValue:jsonBatch logger:logger];
|
||||
if (batchToken) {
|
||||
@@ -472,21 +480,31 @@ NSURLSessionDataDelegate
|
||||
addFormData:NO
|
||||
logger:attachmentLogger];
|
||||
|
||||
NSURL *url = [FBSDKInternalUtility facebookURLWithHostPrefix:kGraphURLPrefix path:nil queryParameters:nil defaultVersion:_overrideVersionPart error:NULL];
|
||||
NSURL *url = [FBSDKInternalUtility
|
||||
facebookURLWithHostPrefix:kGraphURLPrefix
|
||||
path:@""
|
||||
queryParameters:@{}
|
||||
defaultVersion:_overrideVersionPart
|
||||
error:NULL];
|
||||
|
||||
request = [NSMutableURLRequest requestWithURL:url
|
||||
cachePolicy:NSURLRequestUseProtocolCachePolicy
|
||||
timeoutInterval:timeout];
|
||||
request.HTTPMethod = @"POST";
|
||||
}
|
||||
|
||||
request.HTTPBody = body.data;
|
||||
NSUInteger bodyLength = body.data.length / 1024;
|
||||
|
||||
NSData *compressedData;
|
||||
if ([request.HTTPMethod isEqualToString:@"POST"] && (compressedData = [body compressedData])) {
|
||||
request.HTTPBody = compressedData;
|
||||
[request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
|
||||
} else {
|
||||
request.HTTPBody = body.data;
|
||||
}
|
||||
[request setValue:[FBSDKGraphRequestConnection userAgent] forHTTPHeaderField:@"User-Agent"];
|
||||
[request setValue:[body mimeContentType] forHTTPHeaderField:@"Content-Type"];
|
||||
[request setHTTPShouldHandleCookies:NO];
|
||||
|
||||
[self logRequest:request bodyLength:bodyLength bodyLogger:bodyLogger attachmentLogger:attachmentLogger];
|
||||
[self logRequest:request bodyLength:(request.HTTPBody.length / 1024) bodyLogger:bodyLogger attachmentLogger:attachmentLogger];
|
||||
|
||||
return request;
|
||||
}
|
||||
@@ -503,9 +521,12 @@ NSURLSessionDataDelegate
|
||||
//
|
||||
- (NSString *)urlStringForSingleRequest:(FBSDKGraphRequest *)request forBatch:(BOOL)forBatch
|
||||
{
|
||||
request.parameters[@"format"] = @"json";
|
||||
request.parameters[@"sdk"] = kSDK;
|
||||
request.parameters[@"include_headers"] = @"false";
|
||||
NSMutableDictionary<NSString *, id> *params = [NSMutableDictionary dictionaryWithDictionary:request.parameters];
|
||||
params[@"format"] = @"json";
|
||||
params[@"sdk"] = kSDK;
|
||||
params[@"include_headers"] = @"false";
|
||||
|
||||
request.parameters = params;
|
||||
|
||||
NSString *baseURL;
|
||||
if (forBatch) {
|
||||
@@ -513,7 +534,8 @@ NSURLSessionDataDelegate
|
||||
} else {
|
||||
NSString *token = [self accessTokenWithRequest:request];
|
||||
if (token) {
|
||||
[request.parameters setValue:token forKey:kAccessTokenKey];
|
||||
[params setValue:token forKey:kAccessTokenKey];
|
||||
request.parameters = params;
|
||||
[self registerTokenToOmitFromLog:token];
|
||||
}
|
||||
|
||||
@@ -530,7 +552,12 @@ NSURLSessionDataDelegate
|
||||
}
|
||||
}
|
||||
|
||||
baseURL = [FBSDKInternalUtility facebookURLWithHostPrefix:prefix path:request.graphPath queryParameters:nil defaultVersion:request.version error:NULL].absoluteString;
|
||||
baseURL = [FBSDKInternalUtility
|
||||
facebookURLWithHostPrefix:prefix
|
||||
path:request.graphPath
|
||||
queryParameters:@{}
|
||||
defaultVersion:request.version
|
||||
error:NULL].absoluteString;
|
||||
}
|
||||
|
||||
NSString *url = [FBSDKGraphRequest serializeURL:baseURL
|
||||
@@ -554,16 +581,16 @@ NSURLSessionDataDelegate
|
||||
}
|
||||
|
||||
NSArray *results = nil;
|
||||
_URLResponse = (NSHTTPURLResponse *)response;
|
||||
_urlResponse = (NSHTTPURLResponse *)response;
|
||||
if (response) {
|
||||
NSAssert([response isKindOfClass:[NSHTTPURLResponse class]],
|
||||
@"Expected NSHTTPURLResponse, got %@",
|
||||
response);
|
||||
|
||||
NSInteger statusCode = _URLResponse.statusCode;
|
||||
NSInteger statusCode = _urlResponse.statusCode;
|
||||
|
||||
if (!error && [response.MIMEType hasPrefix:@"image"]) {
|
||||
error = [NSError fbErrorWithCode:FBSDKErrorGraphRequestNonTextMimeTypeReturned
|
||||
error = [FBSDKError errorWithCode:FBSDKErrorGraphRequestNonTextMimeTypeReturned
|
||||
message:@"Response is a non-text MIME type; endpoints that return images and other "
|
||||
@"binary data should be fetched using NSURLRequest and NSURLSession"];
|
||||
} else {
|
||||
@@ -572,13 +599,13 @@ NSURLSessionDataDelegate
|
||||
statusCode:statusCode];
|
||||
}
|
||||
} else if (!error) {
|
||||
error = [NSError fbErrorWithCode:FBSDKErrorUnknown
|
||||
error = [FBSDKError errorWithCode:FBSDKErrorUnknown
|
||||
message:@"Missing NSURLResponse"];
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
if (self.requests.count != results.count) {
|
||||
error = [NSError fbErrorWithCode:FBSDKErrorGraphRequestProtocolMismatch
|
||||
error = [FBSDKError errorWithCode:FBSDKErrorGraphRequestProtocolMismatch
|
||||
message:@"Unexpected number of results returned from server."];
|
||||
} else {
|
||||
[_logger appendFormat:@"Response <#%lu>\nDuration: %llu msec\nSize: %lu kB\nResponse Body:\n%@\n\n",
|
||||
@@ -599,7 +626,7 @@ NSURLSessionDataDelegate
|
||||
|
||||
[self completeWithResults:results networkError:error];
|
||||
|
||||
[self cleanUpSession];
|
||||
[self.session invalidateAndCancel];
|
||||
}
|
||||
|
||||
//
|
||||
@@ -617,7 +644,7 @@ NSURLSessionDataDelegate
|
||||
//
|
||||
- (NSArray *)parseJSONResponse:(NSData *)data
|
||||
error:(NSError **)error
|
||||
statusCode:(NSInteger)statusCode;
|
||||
statusCode:(NSInteger)statusCode
|
||||
{
|
||||
// Graph API can return "true" or "false", which is not valid JSON.
|
||||
// Translate that before asking JSON parser to look at it.
|
||||
@@ -628,10 +655,8 @@ NSURLSessionDataDelegate
|
||||
if (responseUTF8 == nil) {
|
||||
NSString *base64Data = data.length != 0 ? [data base64EncodedStringWithOptions:0] : @"";
|
||||
if (base64Data != nil) {
|
||||
[FBSDKAppEvents logImplicitEvent:@"fb_response_invalid_utf8"
|
||||
valueToSum:nil
|
||||
parameters:nil
|
||||
accessToken:nil];
|
||||
[FBSDKAppEvents logInternalEvent:@"fb_response_invalid_utf8"
|
||||
isImplicitlyLogged:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,7 +725,7 @@ NSURLSessionDataDelegate
|
||||
{
|
||||
id parsed = nil;
|
||||
if (!(*error) && [utf8 isKindOfClass:[NSString class]]) {
|
||||
parsed = [FBSDKInternalUtility objectForJSONString:utf8 error:error];
|
||||
parsed = [FBSDKBasicUtility objectForJSONString:utf8 error:error];
|
||||
// if we fail parse we attempt a re-parse of a modified input to support results in the form "foo=bar", "true", etc.
|
||||
// which is shouldn't be necessary since Graph API v2.1.
|
||||
if (*error) {
|
||||
@@ -708,9 +733,9 @@ NSURLSessionDataDelegate
|
||||
// consistent with the rest of the output of this function (note, if perf turns out
|
||||
// to be a problem -- unlikely -- we can return the following dictionary outright)
|
||||
NSDictionary *original = @{ FBSDKNonJSONResponseProperty : utf8 };
|
||||
NSString *jsonrep = [FBSDKInternalUtility JSONStringForObject:original error:NULL invalidObjectHandler:NULL];
|
||||
NSString *jsonrep = [FBSDKBasicUtility JSONStringForObject:original error:NULL invalidObjectHandler:NULL];
|
||||
NSError *reparseError = nil;
|
||||
parsed = [FBSDKInternalUtility objectForJSONString:jsonrep error:&reparseError];
|
||||
parsed = [FBSDKBasicUtility objectForJSONString:jsonrep error:&reparseError];
|
||||
if (!reparseError) {
|
||||
*error = nil;
|
||||
}
|
||||
@@ -793,43 +818,14 @@ NSURLSessionDataDelegate
|
||||
|
||||
};
|
||||
|
||||
FBSDKSystemAccountStoreAdapter *adapter = [FBSDKSystemAccountStoreAdapter sharedInstance];
|
||||
NSString *metadataTokenString = metadata.request.tokenString;
|
||||
NSString *currentTokenString = [FBSDKAccessToken currentAccessToken].tokenString;
|
||||
NSString *accountStoreTokenString = adapter.accessTokenString;
|
||||
BOOL isAccountStoreLogin = [metadataTokenString isEqualToString:accountStoreTokenString];
|
||||
|
||||
if ([metadataTokenString isEqualToString:currentTokenString] || isAccountStoreLogin) {
|
||||
if ([metadataTokenString isEqualToString:currentTokenString]) {
|
||||
NSInteger errorCode = [error.userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] integerValue];
|
||||
NSInteger errorSubcode = [error.userInfo[FBSDKGraphRequestErrorGraphErrorSubcodeKey] integerValue];
|
||||
if (errorCode == 190 || errorCode == 102) {
|
||||
if (isAccountStoreLogin) {
|
||||
if (errorSubcode == 460) {
|
||||
// For iOS6, when the password is changed on the server, the system account store
|
||||
// will continue to issue the old token until the user has changed the
|
||||
// password AND _THEN_ a renew call is made. To prevent opening
|
||||
// with an old token which would immediately be closed, we tell our adapter
|
||||
// that we want to force a blocking renew until success.
|
||||
adapter.forceBlockingRenew = YES;
|
||||
} else {
|
||||
[adapter renewSystemAuthorization:^(ACAccountCredentialRenewResult result, NSError *renewError) {
|
||||
NSOperationQueue *queue = self->_delegateQueue ?: [NSOperationQueue mainQueue];
|
||||
[queue addOperationWithBlock:^{
|
||||
clearToken(errorSubcode);
|
||||
finishAndInvokeCompletionHandler();
|
||||
}];
|
||||
}];
|
||||
return;
|
||||
}
|
||||
}
|
||||
clearToken(errorSubcode);
|
||||
} else if (errorCode >= 200 && errorCode < 300) {
|
||||
// permission error
|
||||
[adapter renewSystemAuthorization:^(ACAccountCredentialRenewResult result, NSError *renewError) {
|
||||
NSOperationQueue *queue = self->_delegateQueue ?: [NSOperationQueue mainQueue];
|
||||
[queue addOperationWithBlock:finishAndInvokeCompletionHandler];
|
||||
}];
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -873,17 +869,17 @@ NSURLSessionDataDelegate
|
||||
|
||||
if ([errorDictionary isKindOfClass:[NSDictionary class]]) {
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"code"] forKey:FBSDKGraphRequestErrorGraphErrorCodeKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_subcode"] forKey:FBSDKGraphRequestErrorGraphErrorSubcodeKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:errorDictionary[@"code"] forKey:FBSDKGraphRequestErrorGraphErrorCodeKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:errorDictionary[@"error_subcode"] forKey:FBSDKGraphRequestErrorGraphErrorSubcodeKey];
|
||||
//"message" is preferred over error_msg or error_reason.
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_msg"] forKey:FBSDKErrorDeveloperMessageKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_reason"] forKey:FBSDKErrorDeveloperMessageKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"message"] forKey:FBSDKErrorDeveloperMessageKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_user_title"] forKey:FBSDKErrorLocalizedTitleKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:FBSDKErrorLocalizedDescriptionKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:NSLocalizedDescriptionKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:result[@"code"] forKey:FBSDKGraphRequestErrorHTTPStatusCodeKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:result forKey:FBSDKGraphRequestErrorParsedJSONResponseKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:errorDictionary[@"error_msg"] forKey:FBSDKErrorDeveloperMessageKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:errorDictionary[@"error_reason"] forKey:FBSDKErrorDeveloperMessageKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:errorDictionary[@"message"] forKey:FBSDKErrorDeveloperMessageKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:errorDictionary[@"error_user_title"] forKey:FBSDKErrorLocalizedTitleKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:FBSDKErrorLocalizedDescriptionKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:NSLocalizedDescriptionKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:result[@"code"] forKey:FBSDKGraphRequestErrorHTTPStatusCodeKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:result forKey:FBSDKGraphRequestErrorParsedJSONResponseKey];
|
||||
|
||||
FBSDKErrorRecoveryConfiguration *recoveryConfiguration = [g_errorConfiguration
|
||||
recoveryConfigurationForCode:[userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] stringValue]
|
||||
@@ -892,14 +888,14 @@ NSURLSessionDataDelegate
|
||||
if ([errorDictionary[@"is_transient"] boolValue]) {
|
||||
userInfo[FBSDKGraphRequestErrorKey] = @(FBSDKGraphRequestErrorTransient);
|
||||
} else {
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:@(recoveryConfiguration.errorCategory) forKey:FBSDKGraphRequestErrorKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:@(recoveryConfiguration.errorCategory) forKey:FBSDKGraphRequestErrorKey];
|
||||
}
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryDescription forKey:NSLocalizedRecoverySuggestionErrorKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryOptionDescriptions forKey:NSLocalizedRecoveryOptionsErrorKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryDescription forKey:NSLocalizedRecoverySuggestionErrorKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryOptionDescriptions forKey:NSLocalizedRecoveryOptionsErrorKey];
|
||||
FBSDKErrorRecoveryAttempter *attempter = [FBSDKErrorRecoveryAttempter recoveryAttempterFromConfiguration:recoveryConfiguration];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:attempter forKey:NSRecoveryAttempterErrorKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:attempter forKey:NSRecoveryAttempterErrorKey];
|
||||
|
||||
return [NSError fbErrorWithCode:FBSDKErrorGraphRequestGraphAPI
|
||||
return [FBSDKError errorWithCode:FBSDKErrorGraphRequestGraphAPI
|
||||
userInfo:userInfo
|
||||
message:nil
|
||||
underlyingError:nil];
|
||||
@@ -909,7 +905,7 @@ NSURLSessionDataDelegate
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSError *)errorWithCode:(FBSDKError)code
|
||||
- (NSError *)errorWithCode:(FBSDKCoreError)code
|
||||
statusCode:(NSInteger)statusCode
|
||||
parsedJSONResponse:(id)response
|
||||
innerError:(NSError *)innerError
|
||||
@@ -937,6 +933,93 @@ NSURLSessionDataDelegate
|
||||
return error;
|
||||
}
|
||||
|
||||
#pragma mark - Private methods (logging and completion)
|
||||
|
||||
- (void)logAndInvokeHandler:(FBSDKURLSessionTaskBlock)handler
|
||||
error:(NSError *)error
|
||||
{
|
||||
if (error) {
|
||||
NSString *logEntry = [NSString
|
||||
stringWithFormat:@"FBSDKURLSessionTask <#%lu>:\n Error: '%@'\n%@\n",
|
||||
(unsigned long)[FBSDKLogger generateSerialNumber],
|
||||
error.localizedDescription,
|
||||
error.userInfo];
|
||||
|
||||
[self logMessage:logEntry];
|
||||
}
|
||||
|
||||
[self invokeHandler:handler error:error response:nil responseData:nil];
|
||||
}
|
||||
|
||||
- (void)logAndInvokeHandler:(FBSDKURLSessionTaskBlock)handler
|
||||
response:(NSURLResponse *)response
|
||||
responseData:(NSData *)responseData
|
||||
requestStartTime:(uint64_t)requestStartTime
|
||||
{
|
||||
// Basic logging just prints out the URL. FBSDKGraphRequest logging provides more details.
|
||||
NSString *mimeType = response.MIMEType;
|
||||
NSMutableString *mutableLogEntry = [NSMutableString stringWithFormat:@"FBSDKGraphRequestConnection <#%lu>:\n Duration: %llu msec\nResponse Size: %lu kB\n MIME type: %@\n",
|
||||
(unsigned long)[FBSDKLogger generateSerialNumber],
|
||||
[FBSDKInternalUtility currentTimeInMilliseconds] - requestStartTime,
|
||||
(unsigned long)responseData.length / 1024,
|
||||
mimeType];
|
||||
|
||||
if ([mimeType isEqualToString:@"text/javascript"]) {
|
||||
NSString *responseUTF8 = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
|
||||
[mutableLogEntry appendFormat:@" Response:\n%@\n\n", responseUTF8];
|
||||
}
|
||||
|
||||
[self logMessage:mutableLogEntry];
|
||||
|
||||
[self invokeHandler:handler error:nil response:response responseData:responseData];
|
||||
}
|
||||
|
||||
- (void)invokeHandler:(FBSDKURLSessionTaskBlock)handler
|
||||
error:(NSError *)error
|
||||
response:(NSURLResponse *)response
|
||||
responseData:(NSData *)responseData
|
||||
{
|
||||
if (handler != nil) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
handler(responseData, response, error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)logMessage:(NSString *)message
|
||||
{
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorNetworkRequests formatString:@"%@", message];
|
||||
}
|
||||
|
||||
- (void)taskDidCompleteWithResponse:(NSURLResponse *)response
|
||||
data:(NSData *)data
|
||||
requestStartTime:(uint64_t)requestStartTime
|
||||
handler:(FBSDKURLSessionTaskBlock)handler
|
||||
{
|
||||
@try {
|
||||
[self logAndInvokeHandler:handler
|
||||
response:response
|
||||
responseData:data
|
||||
requestStartTime:requestStartTime];
|
||||
} @finally {}
|
||||
}
|
||||
|
||||
- (void)taskDidCompleteWithError:(NSError *)error
|
||||
handler:(FBSDKURLSessionTaskBlock)handler
|
||||
{
|
||||
@try {
|
||||
if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == kCFURLErrorSecureConnectionFailed) {
|
||||
NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 };
|
||||
if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS9Version]) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
|
||||
logEntry:@"WARNING: FBSDK secure network request failed. Please verify you have configured your "
|
||||
"app for Application Transport Security compatibility described at https://developers.facebook.com/docs/ios/ios9"];
|
||||
}
|
||||
}
|
||||
[self logAndInvokeHandler:handler error:error];
|
||||
} @finally {}
|
||||
}
|
||||
|
||||
#pragma mark - Private methods (miscellaneous)
|
||||
|
||||
- (void)logRequest:(NSMutableURLRequest *)request
|
||||
@@ -985,6 +1068,8 @@ NSURLSessionDataDelegate
|
||||
}
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||
+ (NSString *)userAgent
|
||||
{
|
||||
static NSString *agent = nil;
|
||||
@@ -992,26 +1077,21 @@ NSURLSessionDataDelegate
|
||||
dispatch_once(&onceToken, ^{
|
||||
agent = [NSString stringWithFormat:@"%@.%@", kUserAgentBase, FBSDK_VERSION_STRING];
|
||||
});
|
||||
|
||||
NSString *agentWithSuffix = nil;
|
||||
if ([FBSDKSettings userAgentSuffix]) {
|
||||
return [NSString stringWithFormat:@"%@/%@", agent, [FBSDKSettings userAgentSuffix]];
|
||||
agentWithSuffix = [NSString stringWithFormat:@"%@/%@", agent, [FBSDKSettings userAgentSuffix]];
|
||||
}
|
||||
if (@available(iOS 13.0, *)) {
|
||||
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
|
||||
SEL selector = NSSelectorFromString(@"isMacCatalystApp");
|
||||
if (selector && [processInfo respondsToSelector:selector] && [processInfo performSelector:selector]) {
|
||||
return [NSString stringWithFormat:@"%@/%@", agentWithSuffix ?: agent, @"macOS"];
|
||||
}
|
||||
}
|
||||
return agent;
|
||||
}
|
||||
|
||||
- (NSURLSession *)defaultSession
|
||||
{
|
||||
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
return [NSURLSession sessionWithConfiguration:config
|
||||
delegate:self
|
||||
delegateQueue:_delegateQueue];
|
||||
}
|
||||
|
||||
- (void)cleanUpSession
|
||||
{
|
||||
[self.session invalidateAndCancel];
|
||||
self.session = nil;
|
||||
return agentWithSuffix ?: agent;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#pragma mark - NSURLSessionDataDelegate
|
||||
|
||||
|
||||
+5
@@ -18,9 +18,12 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
A container class for data attachments so that additional metadata can be provided about the attachment.
|
||||
*/
|
||||
NS_SWIFT_NAME(GraphRequestDataAttachment)
|
||||
@interface FBSDKGraphRequestDataAttachment : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
@@ -53,3 +56,5 @@ NS_DESIGNATED_INITIALIZER;
|
||||
@property (nonatomic, copy, readonly) NSString *filename;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,19 +0,0 @@
|
||||
// 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>
|
||||
+27
-21
@@ -22,46 +22,52 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
/*! The name of the notification posted by FBSDKMeasurementEvent */
|
||||
FOUNDATION_EXPORT NSNotificationName const FBSDKMeasurementEventNotification;
|
||||
/** The name of the notification posted by FBSDKMeasurementEvent */
|
||||
FOUNDATION_EXPORT NSNotificationName const FBSDKMeasurementEventNotification
|
||||
NS_SWIFT_NAME(MeasurementEvent);
|
||||
|
||||
#else
|
||||
|
||||
/*! The name of the notification posted by FBSDKMeasurementEvent */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKMeasurementEventNotification;
|
||||
/** The name of the notification posted by FBSDKMeasurementEvent */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKMeasurementEventNotification
|
||||
NS_SWIFT_NAME(MeasurementEventNotification);
|
||||
|
||||
#endif
|
||||
|
||||
FOUNDATION_EXPORT NSString *const FBSDKMeasurementEventNotificationName
|
||||
DEPRECATED_MSG_ATTRIBUTE("Use `FBSDKMeasurementEventNotification` instead");
|
||||
/** Defines keys in the userInfo object for the notification named FBSDKMeasurementEventNotificationName */
|
||||
/** The string field for the name of the event */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKMeasurementEventNameKey
|
||||
NS_SWIFT_NAME(MeasurementEventNameKey);
|
||||
/** The dictionary field for the arguments of the event */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKMeasurementEventArgsKey
|
||||
NS_SWIFT_NAME(MeasurementEventArgsKey);
|
||||
|
||||
/*! Defines keys in the userInfo object for the notification named FBSDKMeasurementEventNotificationName */
|
||||
/*! The string field for the name of the event */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKMeasurementEventNameKey;
|
||||
/*! The dictionary field for the arguments of the event */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKMeasurementEventArgsKey;
|
||||
|
||||
/*! Events raised by FBSDKMeasurementEvent for Applink */
|
||||
/*!
|
||||
/** Events raised by FBSDKMeasurementEvent for Applink */
|
||||
/**
|
||||
The name of the event posted when [FBSDKURL URLWithURL:] is called successfully. This represents the successful parsing of an app link URL.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkParseEventName;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkParseEventName
|
||||
NS_SWIFT_NAME(AppLinkParseEventName);
|
||||
|
||||
/*!
|
||||
/**
|
||||
The name of the event posted when [FBSDKURL URLWithInboundURL:] is called successfully.
|
||||
This represents parsing an inbound app link URL from a different application
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkNavigateInEventName;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkNavigateInEventName
|
||||
NS_SWIFT_NAME(AppLinkNavigateInEventName);
|
||||
|
||||
/*! The event raised when the user navigates from your app to other apps */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkNavigateOutEventName;
|
||||
/** The event raised when the user navigates from your app to other apps */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkNavigateOutEventName
|
||||
NS_SWIFT_NAME(AppLinkNavigateOutEventName);
|
||||
|
||||
/*!
|
||||
/**
|
||||
The event raised when the user navigates out from your app and back to the referrer app.
|
||||
e.g when the user leaves your app after tapping the back-to-referrer navigation bar
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkNavigateBackToReferrerEventName;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKAppLinkNavigateBackToReferrerEventName
|
||||
NS_SWIFT_NAME(AppLinkNavigateBackToReferrerEventName);
|
||||
|
||||
NS_SWIFT_NAME(MeasurementEvent)
|
||||
@interface FBSDKMeasurementEvent : NSObject
|
||||
|
||||
@end
|
||||
|
||||
+8
-4
@@ -18,6 +18,9 @@
|
||||
|
||||
#import "FBSDKMeasurementEvent_Internal.h"
|
||||
|
||||
#import "FBSDKLogger.h"
|
||||
#import "FBSDKSettings.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
NSNotificationName const FBSDKMeasurementEventNotification = @"com.facebook.facebook-objc-sdk.measurement_event";
|
||||
@@ -33,11 +36,11 @@ NSString *const FBSDKMeasurementEventNotificationName = @"com.facebook.facebook-
|
||||
NSString *const FBSDKMeasurementEventNameKey = @"event_name";
|
||||
NSString *const FBSDKMeasurementEventArgsKey = @"event_args";
|
||||
|
||||
/* app Link Event raised by this FBSDKURL */
|
||||
/** app Link Event raised by this FBSDKURL */
|
||||
NSString *const FBSDKAppLinkParseEventName = @"al_link_parse";
|
||||
NSString *const FBSDKAppLinkNavigateInEventName = @"al_nav_in";
|
||||
|
||||
/*! AppLink events raised in this class */
|
||||
/** AppLink events raised in this class */
|
||||
NSString *const FBSDKAppLinkNavigateOutEventName = @"al_nav_out";
|
||||
NSString *const FBSDKAppLinkNavigateBackToReferrerEventName = @"al_ref_back_out";
|
||||
|
||||
@@ -48,8 +51,9 @@ NSString *const FBSDKAppLinkNavigateBackToReferrerEventName = @"al_ref_back_out"
|
||||
|
||||
- (void)postNotification {
|
||||
if (!_name) {
|
||||
NSLog(@"Warning: Missing event name when logging FBSDK measurement event. \n"
|
||||
" Ignoring this event in logging.");
|
||||
[FBSDKLogger
|
||||
singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
|
||||
logEntry:@"Warning: Missing event name when logging FBSDK measurement event.\nIgnoring this event in logging."];
|
||||
return;
|
||||
}
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
@@ -20,11 +20,14 @@
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Extension protocol for NSMutableCopying that adds the mutableCopy method, which is implemented on NSObject.
|
||||
|
||||
NSObject<NSCopying, NSMutableCopying> implicitly conforms to this protocol.
|
||||
*/
|
||||
NS_SWIFT_NAME(MutableCopying)
|
||||
@protocol FBSDKMutableCopying <FBSDKCopying, NSMutableCopying>
|
||||
|
||||
/**
|
||||
@@ -34,3 +37,5 @@
|
||||
- (id)mutableCopy;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+54
-46
@@ -18,6 +18,10 @@
|
||||
|
||||
#import "FBSDKProfilePictureView.h"
|
||||
|
||||
@class FBSDKProfile;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
/**
|
||||
@@ -27,18 +31,20 @@
|
||||
`FBSDKProfileChangeOldKey` and
|
||||
`FBSDKProfileChangeNewKey`.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSNotificationName const FBSDKProfileDidChangeNotification;
|
||||
FOUNDATION_EXPORT NSNotificationName const FBSDKProfileDidChangeNotification
|
||||
NS_SWIFT_NAME(ProfileDidChange);
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
Notification indicating that the `currentProfile` has changed.
|
||||
Notification indicating that the `currentProfile` has changed.
|
||||
|
||||
the userInfo dictionary of the notification will contain keys
|
||||
`FBSDKProfileChangeOldKey` and
|
||||
`FBSDKProfileChangeNewKey`.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKProfileDidChangeNotification;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKProfileDidChangeNotification
|
||||
NS_SWIFT_NAME(ProfileDidChangeNotification);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,13 +52,24 @@ FOUNDATION_EXPORT NSString *const FBSDKProfileDidChangeNotification;
|
||||
|
||||
If there was no old profile, the key will not be present.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKProfileChangeOldKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKProfileChangeOldKey
|
||||
NS_SWIFT_NAME(ProfileChangeOldKey);
|
||||
|
||||
/* key in notification's userInfo object for getting the new profile.
|
||||
|
||||
If there is no new profile, the key will not be present.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKProfileChangeNewKey;
|
||||
FOUNDATION_EXPORT NSString *const FBSDKProfileChangeNewKey
|
||||
NS_SWIFT_NAME(ProfileChangeNewKey);
|
||||
|
||||
/**
|
||||
Describes the callback for loadCurrentProfileWithCompletion.
|
||||
@param profile the FBSDKProfile
|
||||
@param error the error during the request, if any
|
||||
|
||||
*/
|
||||
typedef void (^FBSDKProfileBlock)(FBSDKProfile *_Nullable profile, NSError *_Nullable error)
|
||||
NS_SWIFT_NAME(ProfileBlock);
|
||||
|
||||
/**
|
||||
Represents an immutable Facebook profile
|
||||
@@ -66,6 +83,7 @@ FOUNDATION_EXPORT NSString *const FBSDKProfileChangeNewKey;
|
||||
|
||||
You can use this class to build your own `FBSDKProfilePictureView` or in place of typical requests to "/me".
|
||||
*/
|
||||
NS_SWIFT_NAME(Profile)
|
||||
@interface FBSDKProfile : NSObject<NSCopying, NSSecureCoding>
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
@@ -82,12 +100,24 @@ FOUNDATION_EXPORT NSString *const FBSDKProfileChangeNewKey;
|
||||
@param refreshDate the optional date this profile was fetched. Defaults to [NSDate date].
|
||||
*/
|
||||
- (instancetype)initWithUserID:(NSString *)userID
|
||||
firstName:(NSString *)firstName
|
||||
middleName:(NSString *)middleName
|
||||
lastName:(NSString *)lastName
|
||||
name:(NSString *)name
|
||||
linkURL:(NSURL *)linkURL
|
||||
refreshDate:(NSDate *)refreshDate NS_DESIGNATED_INITIALIZER;
|
||||
firstName:(nullable NSString *)firstName
|
||||
middleName:(nullable NSString *)middleName
|
||||
lastName:(nullable NSString *)lastName
|
||||
name:(nullable NSString *)name
|
||||
linkURL:(nullable NSURL *)linkURL
|
||||
refreshDate:(nullable NSDate *)refreshDate NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
The current profile instance and posts the appropriate notification
|
||||
if the profile parameter is different than the receiver.
|
||||
|
||||
This persists the profile to NSUserDefaults.
|
||||
*/
|
||||
|
||||
/// The current profile
|
||||
@property (class, nonatomic, strong, nullable) FBSDKProfile *currentProfile
|
||||
NS_SWIFT_NAME(current);
|
||||
|
||||
/**
|
||||
The user id
|
||||
*/
|
||||
@@ -95,46 +125,32 @@ FOUNDATION_EXPORT NSString *const FBSDKProfileChangeNewKey;
|
||||
/**
|
||||
The user's first name
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *firstName;
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *firstName;
|
||||
/**
|
||||
The user's middle name
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *middleName;
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *middleName;
|
||||
/**
|
||||
The user's last name
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *lastName;
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *lastName;
|
||||
/**
|
||||
The user's complete name
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *name;
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *name;
|
||||
/**
|
||||
A URL to the user's profile.
|
||||
|
||||
Consider using Bolts and `FBSDKAppLinkResolver` to resolve this
|
||||
Consider using `FBSDKAppLinkResolver` to resolve this
|
||||
to an app link to link directly to the user's profile in the Facebook app.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSURL *linkURL;
|
||||
@property (nonatomic, readonly, nullable) NSURL *linkURL;
|
||||
|
||||
/**
|
||||
The last time the profile data was fetched.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSDate *refreshDate;
|
||||
|
||||
/**
|
||||
Gets the current FBSDKProfile instance.
|
||||
*/
|
||||
+ (FBSDKProfile *)currentProfile;
|
||||
|
||||
/**
|
||||
Sets the current instance and posts the appropriate notification if the profile parameter is different
|
||||
than the receiver.
|
||||
@param profile the profile to set
|
||||
|
||||
This persists the profile to NSUserDefaults.
|
||||
*/
|
||||
+ (void)setCurrentProfile:(FBSDKProfile *)profile;
|
||||
|
||||
/**
|
||||
Indicates if `currentProfile` will automatically observe `FBSDKAccessTokenDidChangeNotification` notifications
|
||||
@param enable YES is observing
|
||||
@@ -145,7 +161,8 @@ FOUNDATION_EXPORT NSString *const FBSDKProfileChangeNewKey;
|
||||
Note that if `[FBSDKAccessToken currentAccessToken]` is unset, the `currentProfile` instance remains. It's also possible
|
||||
for `currentProfile` to return nil until the data is fetched.
|
||||
*/
|
||||
+ (void)enableUpdatesOnAccessTokenChange:(BOOL)enable;
|
||||
+ (void)enableUpdatesOnAccessTokenChange:(BOOL)enable
|
||||
NS_SWIFT_NAME(enableUpdatesOnAccessTokenChange(_:));
|
||||
|
||||
/**
|
||||
Loads the current profile and passes it to the completion block.
|
||||
@@ -154,26 +171,15 @@ FOUNDATION_EXPORT NSString *const FBSDKProfileChangeNewKey;
|
||||
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;
|
||||
+ (void)loadCurrentProfileWithCompletion:(nullable FBSDKProfileBlock)completion;
|
||||
|
||||
/**
|
||||
A convenience method for returning a complete `NSURL` for retrieving the user's profile image.
|
||||
@param mode The picture mode
|
||||
@param size The height and width. This will be rounded to integer precision.
|
||||
*/
|
||||
- (NSURL *)imageURLForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size;
|
||||
|
||||
/**
|
||||
A convenience method for returning a Graph API path for retrieving the user's profile image.
|
||||
|
||||
@warning use `imageURLForPictureMode:size:` instead
|
||||
|
||||
You can pass this to a `FBSDKGraphRequest` instance to download the image.
|
||||
@param mode The picture mode
|
||||
@param size The height and width. This will be rounded to integer precision.
|
||||
*/
|
||||
- (NSString *)imagePathForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size
|
||||
DEPRECATED_MSG_ATTRIBUTE("use imageURLForPictureMode:size: instead");
|
||||
- (nullable NSURL *)imageURLForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size
|
||||
NS_SWIFT_NAME(imageURL(forMode:size:));
|
||||
|
||||
/**
|
||||
Returns YES if the profile is equivalent to the receiver.
|
||||
@@ -181,3 +187,5 @@ DEPRECATED_MSG_ATTRIBUTE("use imageURLForPictureMode:size: instead");
|
||||
*/
|
||||
- (BOOL)isEqualToProfile:(FBSDKProfile *)profile;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+13
-19
@@ -18,7 +18,7 @@
|
||||
|
||||
#import "FBSDKProfile+Internal.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
|
||||
@@ -79,8 +79,8 @@ static FBSDKProfile *g_currentProfile;
|
||||
[[self class] cacheProfile:profile];
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:profile forKey:FBSDKProfileChangeNewKey];
|
||||
[FBSDKInternalUtility dictionary:userInfo setObject:g_currentProfile forKey:FBSDKProfileChangeOldKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:profile forKey:FBSDKProfileChangeNewKey];
|
||||
[FBSDKBasicUtility dictionary:userInfo setObject:g_currentProfile forKey:FBSDKProfileChangeOldKey];
|
||||
g_currentProfile = profile;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:FBSDKProfileDidChangeNotification
|
||||
object:[self class]
|
||||
@@ -89,29 +89,23 @@ static FBSDKProfile *g_currentProfile;
|
||||
}
|
||||
|
||||
- (NSURL *)imageURLForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
NSString *path = [self imagePathForPictureMode:mode size:size];
|
||||
#pragma clang diagnostic pop
|
||||
return [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph"
|
||||
path:path
|
||||
queryParameters:nil
|
||||
error:NULL];
|
||||
}
|
||||
|
||||
- (NSString *)imagePathForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size
|
||||
{
|
||||
NSString *type;
|
||||
switch (mode) {
|
||||
case FBSDKProfilePictureModeNormal: type = @"normal"; break;
|
||||
case FBSDKProfilePictureModeSquare: type = @"square"; break;
|
||||
}
|
||||
return [NSString stringWithFormat:@"%@/picture?type=%@&width=%d&height=%d",
|
||||
|
||||
NSString *path = [NSString stringWithFormat:@"%@/picture?type=%@&width=%d&height=%d",
|
||||
_userID,
|
||||
type,
|
||||
(int) roundf(size.width),
|
||||
(int) roundf(size.height)];
|
||||
|
||||
return [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph"
|
||||
path:path
|
||||
queryParameters:@{}
|
||||
error:NULL];
|
||||
}
|
||||
|
||||
+ (void)enableUpdatesOnAccessTokenChange:(BOOL)enable
|
||||
@@ -126,7 +120,7 @@ static FBSDKProfile *g_currentProfile;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)loadCurrentProfileWithCompletion:(void (^)(FBSDKProfile *, NSError *))completion
|
||||
+ (void)loadCurrentProfileWithCompletion:(FBSDKProfileBlock)completion
|
||||
{
|
||||
[self loadProfileWithToken:[FBSDKAccessToken currentAccessToken] completion:completion];
|
||||
}
|
||||
@@ -214,7 +208,7 @@ static FBSDKProfile *g_currentProfile;
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
+ (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(void (^)(FBSDKProfile *, NSError *))completion
|
||||
+ (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion
|
||||
{
|
||||
static FBSDKGraphRequestConnection *executingRequestConnection = nil;
|
||||
|
||||
@@ -266,7 +260,7 @@ static FBSDKProfile *g_currentProfile;
|
||||
|
||||
@implementation FBSDKProfile(Internal)
|
||||
|
||||
+ (void)cacheProfile:(FBSDKProfile *) profile
|
||||
+ (void)cacheProfile:(FBSDKProfile *)profile
|
||||
{
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
if (profile) {
|
||||
|
||||
+6
-1
@@ -18,6 +18,8 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
FBSDKProfilePictureMode enum
|
||||
Defines the aspect ratio mode for the source image of the profile picture.
|
||||
@@ -32,11 +34,12 @@ typedef NS_ENUM(NSUInteger, FBSDKProfilePictureMode)
|
||||
The original picture's aspect ratio will be used for the source image in the view.
|
||||
*/
|
||||
FBSDKProfilePictureModeNormal,
|
||||
};
|
||||
} NS_SWIFT_NAME(Profile.PictureMode);
|
||||
|
||||
/**
|
||||
A view to display a profile picture.
|
||||
*/
|
||||
NS_SWIFT_NAME(FBProfilePictureView)
|
||||
@interface FBSDKProfilePictureView : UIView
|
||||
|
||||
/**
|
||||
@@ -58,3 +61,5 @@ typedef NS_ENUM(NSUInteger, FBSDKProfilePictureMode)
|
||||
- (void)setNeedsImageUpdate;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+23
-37
@@ -205,40 +205,6 @@
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
+ (void)_downloadImageWithState:(FBSDKProfilePictureViewState *)state
|
||||
completionBlock:(void(^)(NSData *data))completionBlock;
|
||||
{
|
||||
NSURL *imageURL = [self _imageURLWithState:state];
|
||||
if (!imageURL) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imageURL];
|
||||
NSURLSession *session = [NSURLSession sharedSession];
|
||||
[[session
|
||||
dataTaskWithRequest:request
|
||||
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||
if (!error && data.length) {
|
||||
completionBlock(data);
|
||||
}
|
||||
}] resume];
|
||||
}
|
||||
|
||||
+ (NSURL *)_imageURLWithState:(FBSDKProfilePictureViewState *)state
|
||||
{
|
||||
FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken];
|
||||
if ([state.profileID isEqualToString:@"me"] && !accessToken) {
|
||||
return nil;
|
||||
}
|
||||
NSString *path = [[NSString alloc] initWithFormat:@"/%@/picture", [FBSDKUtility URLEncode:state.profileID]];
|
||||
CGSize size = state.size;
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
parameters[@"width"] = @(size.width);
|
||||
parameters[@"height"] = @(size.height);
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:accessToken.tokenString forKey:@"access_token"];
|
||||
return [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph" path:path queryParameters:parameters error:NULL];
|
||||
}
|
||||
|
||||
- (void)_accessTokenDidChangeNotification:(NSNotification *)notification
|
||||
{
|
||||
if (![_profileID isEqualToString:@"me"] || !notification.userInfo[FBSDKAccessTokenDidChangeUserIDKey]) {
|
||||
@@ -340,10 +306,30 @@
|
||||
}
|
||||
_lastState = state;
|
||||
|
||||
FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken];
|
||||
if ([state.profileID isEqualToString:@"me"] && !accessToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *path = [[NSString alloc] initWithFormat:@"/%@/picture", [FBSDKUtility URLEncode:state.profileID]];
|
||||
CGSize size = state.size;
|
||||
NSMutableDictionary<NSString *, id> *parameters = [[NSMutableDictionary alloc] init];
|
||||
parameters[@"width"] = @(size.width);
|
||||
parameters[@"height"] = @(size.height);
|
||||
[FBSDKBasicUtility dictionary:parameters setObject:accessToken.tokenString forKey:@"access_token"];
|
||||
NSURL *imageURL = [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph" path:path queryParameters:parameters error:NULL];
|
||||
|
||||
__weak FBSDKProfilePictureView *weakSelf = self;
|
||||
[[self class] _downloadImageWithState:state completionBlock:^(NSData *data) {
|
||||
[weakSelf _updateImageWithData:data state:state];
|
||||
}];
|
||||
|
||||
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imageURL];
|
||||
NSURLSession *session = [NSURLSession sharedSession];
|
||||
[[session
|
||||
dataTaskWithRequest:request
|
||||
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||
if (!error && data.length) {
|
||||
[weakSelf _updateImageWithData:data state:state];
|
||||
}
|
||||
}] resume];
|
||||
}
|
||||
|
||||
- (void)_setPlaceholderImage
|
||||
|
||||
+103
-162
@@ -18,255 +18,196 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*
|
||||
* Constants defining logging behavior. Use with <[FBSDKSettings setLoggingBehavior]>.
|
||||
*/
|
||||
|
||||
/// typedef for FBSDKAppEventName
|
||||
typedef NSString *const FBSDKLoggingBehavior NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAME(LoggingBehavior);
|
||||
|
||||
/** Include access token in logging. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorAccessTokens;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorAccessTokens;
|
||||
|
||||
/** Log performance characteristics */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorPerformanceCharacteristics;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorPerformanceCharacteristics;
|
||||
|
||||
/** Log FBSDKAppEvents interactions */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorAppEvents;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorAppEvents;
|
||||
|
||||
/** Log Informational occurrences */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorInformational;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorInformational;
|
||||
|
||||
/** Log cache errors. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorCacheErrors;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorCacheErrors;
|
||||
|
||||
/** Log errors from SDK UI controls */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorUIControlErrors;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorUIControlErrors;
|
||||
|
||||
/** Log debug warnings from API response, i.e. when friends fields requested, but user_friends permission isn't granted. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorGraphAPIDebugWarning;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorGraphAPIDebugWarning;
|
||||
|
||||
/** Log warnings from API response, i.e. when requested feature will be deprecated in next version of API.
|
||||
Info is the lowest level of severity, using it will result in logging all previously mentioned levels.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorGraphAPIDebugInfo;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorGraphAPIDebugInfo;
|
||||
|
||||
/** Log errors from SDK network requests */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorNetworkRequests;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorNetworkRequests;
|
||||
|
||||
/** Log errors likely to be preventable by the developer. This is in the default set of enabled logging behaviors. */
|
||||
FOUNDATION_EXPORT NSString *const FBSDKLoggingBehaviorDeveloperErrors;
|
||||
FOUNDATION_EXPORT FBSDKLoggingBehavior FBSDKLoggingBehaviorDeveloperErrors;
|
||||
|
||||
NS_SWIFT_NAME(Settings)
|
||||
@interface FBSDKSettings : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Get the Facebook App ID used by the SDK.
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookAppID).
|
||||
Retrieve the current iOS SDK version.
|
||||
*/
|
||||
+ (NSString *)appID;
|
||||
@property (class, nonatomic, copy, readonly) NSString *sdkVersion;
|
||||
|
||||
/**
|
||||
Set the Facebook App ID to be used by the SDK.
|
||||
@param appID The Facebook App ID to be used by the SDK.
|
||||
Retrieve the current default Graph API version.
|
||||
*/
|
||||
+ (void)setAppID:(NSString *)appID;
|
||||
@property (class, nonatomic, copy, readonly) NSString *defaultGraphAPIVersion;
|
||||
|
||||
/**
|
||||
Get the default url scheme suffix used for sessions.
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookUrlSchemeSuffix).
|
||||
*/
|
||||
+ (NSString *)appURLSchemeSuffix;
|
||||
|
||||
/**
|
||||
Set the app url scheme suffix used by the SDK.
|
||||
@param appURLSchemeSuffix The url scheme suffix to be used by the SDK.
|
||||
*/
|
||||
+ (void)setAppURLSchemeSuffix:(NSString *)appURLSchemeSuffix;
|
||||
|
||||
/**
|
||||
Retrieve the Client Token that has been set via [FBSDKSettings setClientToken].
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookClientToken).
|
||||
*/
|
||||
+ (NSString *)clientToken;
|
||||
|
||||
/**
|
||||
Sets the Client Token for the Facebook App.
|
||||
|
||||
This is needed for certain API calls when made anonymously, without a user-based access token.
|
||||
@param clientToken The Facebook App's "client token", which, for a given appid can be found in the Security
|
||||
section of the Advanced tab of the Facebook App settings found at <https://developers.facebook.com/apps/[your-app-id]>
|
||||
*/
|
||||
+ (void)setClientToken:(NSString *)clientToken;
|
||||
|
||||
/**
|
||||
A convenient way to toggle error recovery for all FBSDKGraphRequest instances created after this is set.
|
||||
@param disableGraphErrorRecovery YES or NO.
|
||||
*/
|
||||
+ (void)setGraphErrorRecoveryDisabled:(BOOL)disableGraphErrorRecovery;
|
||||
|
||||
/**
|
||||
Get the Facebook Display Name used by the SDK.
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookDisplayName).
|
||||
*/
|
||||
+ (NSString *)displayName;
|
||||
|
||||
/**
|
||||
Set the default Facebook Display Name to be used by the SDK.
|
||||
|
||||
This should match the Display Name that has been set for the app with the corresponding Facebook App ID,
|
||||
in the Facebook App Dashboard.
|
||||
@param displayName The Facebook Display Name to be used by the SDK.
|
||||
*/
|
||||
+ (void)setDisplayName:(NSString *)displayName;
|
||||
|
||||
/**
|
||||
Get the Facebook domain part.
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookDomainPart).
|
||||
*/
|
||||
+ (NSString *)facebookDomainPart;
|
||||
|
||||
/**
|
||||
Set the subpart of the Facebook domain.
|
||||
|
||||
This can be used to change the Facebook domain (e.g. @"beta") so that requests will be sent to
|
||||
graph.beta.facebook.com
|
||||
@param facebookDomainPart The domain part to be inserted into facebook.com.
|
||||
*/
|
||||
+ (void)setFacebookDomainPart:(NSString *)facebookDomainPart;
|
||||
|
||||
/**
|
||||
The quality of JPEG images sent to Facebook from the SDK.
|
||||
The quality of JPEG images sent to Facebook from the SDK,
|
||||
expressed as a value from 0.0 to 1.0.
|
||||
|
||||
If not explicitly set, the default is 0.9.
|
||||
|
||||
@see [UIImageJPEGRepresentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIImageJPEGRepresentation) */
|
||||
+ (CGFloat)JPEGCompressionQuality;
|
||||
@property (class, nonatomic, assign) CGFloat JPEGCompressionQuality
|
||||
NS_SWIFT_NAME(jpegCompressionQuality);
|
||||
|
||||
/**
|
||||
Set the quality of JPEG images sent to Facebook from the SDK.
|
||||
@param JPEGCompressionQuality The quality for JPEG images, expressed as a value from 0.0 to 1.0.
|
||||
|
||||
@see [UIImageJPEGRepresentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIImageJPEGRepresentation) */
|
||||
+ (void)setJPEGCompressionQuality:(CGFloat)JPEGCompressionQuality;
|
||||
|
||||
/**
|
||||
Flag which controls the auto logging of basic app events, such as activateApp and deactivateApp.
|
||||
If not explicitly set, the default is 1 - true
|
||||
Controls sdk auto initailization.
|
||||
If not explicitly set, the default is true
|
||||
*/
|
||||
+ (NSNumber *)autoLogAppEventsEnabled;
|
||||
@property (class, nonatomic, assign, getter=isAutoInitEnabled) BOOL autoInitEnabled;
|
||||
|
||||
/**
|
||||
Set the flag which controls the auto logging of basic app events, such as activateApp and deactivateApp.
|
||||
@param AutoLogAppEventsEnabled Flag value, expressed as a value from 0 - false or 1 - true.
|
||||
Controls sdk crash report
|
||||
If not explicitly set, the default is true
|
||||
*/
|
||||
+ (void)setAutoLogAppEventsEnabled:(NSNumber *)AutoLogAppEventsEnabled;
|
||||
@property (class, nonatomic, assign, getter=isInstrumentEnabled) BOOL instrumentEnabled
|
||||
__attribute((deprecated("This attribute is no longer used, use autoLogAppEventsEnabled instead.")));
|
||||
|
||||
/**
|
||||
Flag which controls the fb_codeless_debug logging event
|
||||
If not explicitly set, the default is 1 - true
|
||||
Controls the auto logging of basic app events, such as activateApp and deactivateApp.
|
||||
If not explicitly set, the default is true
|
||||
*/
|
||||
+ (NSNumber *)codelessDebugLogEnabled;
|
||||
@property (class, nonatomic, assign, getter=isAutoLogAppEventsEnabled) BOOL autoLogAppEventsEnabled;
|
||||
|
||||
/**
|
||||
Set the flag which controls the fb_codeless_debug logging event
|
||||
@param CodelessDebugLogEnabled Flag value, expressed as a value from 0 - false or 1 - true.
|
||||
Controls the fb_codeless_debug logging event
|
||||
If not explicitly set, the default is true
|
||||
*/
|
||||
+ (void)setCodelessDebugLogEnabled:(NSNumber *)CodelessDebugLogEnabled;
|
||||
@property (class, nonatomic, assign, getter=isCodelessDebugLogEnabled) BOOL codelessDebugLogEnabled;
|
||||
|
||||
/**
|
||||
Flag which controls whether advertiserID could be collected.
|
||||
If not explicitly set, the default is 1 - true
|
||||
Controls the fb_codeless_debug logging event
|
||||
If not explicitly set, the default is true
|
||||
*/
|
||||
+ (NSNumber *)advertiserIDCollectionEnabled;
|
||||
@property (class, nonatomic, assign, getter=isAdvertiserIDCollectionEnabled) BOOL advertiserIDCollectionEnabled;
|
||||
|
||||
/**
|
||||
Set the flag which controls ontrols whether advertiserID could be collected.
|
||||
@param AdvertiserIDCollectionEnabled Flag value, expressed as a value from 0 - false or 1 - true.
|
||||
Whether data such as that generated through FBSDKAppEvents and sent to Facebook
|
||||
should be restricted from being used for other than analytics and conversions.
|
||||
Defaults to NO. This value is stored on the device and persists across app launches.
|
||||
*/
|
||||
+ (void)setAdvertiserIDCollectionEnabled:(NSNumber *)AdvertiserIDCollectionEnabled;
|
||||
@property (class, nonatomic, assign, getter=shouldLimitEventAndDataUsage) BOOL limitEventAndDataUsage;
|
||||
|
||||
/**
|
||||
Gets whether data such as that generated through FBSDKAppEvents and sent to Facebook should be restricted from being used for other than analytics and conversions. Defaults to NO. This value is stored on the device and persists across app launches.
|
||||
A convenient way to toggle error recovery for all FBSDKGraphRequest instances created after this is set.
|
||||
*/
|
||||
+ (BOOL)limitEventAndDataUsage;
|
||||
@property (class, nonatomic, assign, getter=isGraphErrorRecoveryEnabled) BOOL graphErrorRecoveryEnabled;
|
||||
|
||||
/**
|
||||
Sets whether data such as that generated through FBSDKAppEvents and sent to Facebook should be restricted from being used for other than analytics and conversions. Defaults to NO. This value is stored on the device and persists across app launches.
|
||||
The Facebook App ID used by the SDK.
|
||||
|
||||
@param limitEventAndDataUsage The desired value.
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookAppID).
|
||||
*/
|
||||
+ (void)setLimitEventAndDataUsage:(BOOL)limitEventAndDataUsage;
|
||||
@property (class, nonatomic, copy, nullable) NSString *appID;
|
||||
|
||||
/**
|
||||
Retrieve the current iOS SDK version.
|
||||
The default url scheme suffix used for sessions.
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookUrlSchemeSuffix).
|
||||
*/
|
||||
+ (NSString *)sdkVersion;
|
||||
@property (class, nonatomic, copy, nullable) NSString *appURLSchemeSuffix;
|
||||
|
||||
/**
|
||||
The current Facebook SDK logging behavior.
|
||||
The Client Token that has been set via [FBSDKSettings setClientToken].
|
||||
This is needed for certain API calls when made anonymously, without a user-based access token.
|
||||
|
||||
The Facebook App's "client token", which, for a given appid can be found in the Security
|
||||
section of the Advanced tab of the Facebook App settings found at <https://developers.facebook.com/apps/[your-app-id]>
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookClientToken).
|
||||
*/
|
||||
@property (class, nonatomic, copy) NSSet<NSString *> *loggingBehaviors;
|
||||
|
||||
+ (NSSet *)loggingBehavior
|
||||
DEPRECATED_MSG_ATTRIBUTE("Renamed `loggingBehaviors`");
|
||||
@property (class, nonatomic, copy, nullable) NSString *clientToken;
|
||||
|
||||
/**
|
||||
Set the current Facebook SDK logging behavior. This should consist of strings defined as
|
||||
constants with FBSDKLoggingBehavior*.
|
||||
The Facebook Display Name used by the SDK.
|
||||
|
||||
@param loggingBehavior A set of strings indicating what information should be logged. If nil is provided, the logging
|
||||
behavior is reset to the default set of enabled behaviors. Set to an empty set in order to disable all logging.
|
||||
This should match the Display Name that has been set for the app with the corresponding Facebook App ID,
|
||||
in the Facebook App Dashboard.
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookDisplayName).
|
||||
*/
|
||||
@property (class, nonatomic, copy, nullable) NSString *displayName;
|
||||
|
||||
/**
|
||||
The Facebook domain part. This can be used to change the Facebook domain
|
||||
(e.g. @"beta") so that requests will be sent to `graph.beta.facebook.com`
|
||||
|
||||
If not explicitly set, the default will be read from the application's plist (FacebookDomainPart).
|
||||
*/
|
||||
@property (class, nonatomic, copy, nullable) NSString *facebookDomainPart;
|
||||
|
||||
/**
|
||||
The current Facebook SDK logging behavior. This should consist of strings
|
||||
defined as constants with FBSDKLoggingBehavior*.
|
||||
|
||||
This should consist a set of strings indicating what information should be logged
|
||||
defined as constants with FBSDKLoggingBehavior*. Set to an empty set in order to disable all logging.
|
||||
|
||||
You can also define this via an array in your app plist with key "FacebookLoggingBehavior" or add and remove individual values via enableLoggingBehavior: or disableLogginBehavior:
|
||||
|
||||
The default is a set consisting of FBSDKLoggingBehaviorDeveloperErrors
|
||||
*/
|
||||
+ (void)setLoggingBehavior:(NSSet *)loggingBehavior;
|
||||
|
||||
/**
|
||||
Enable a particular Facebook SDK logging behavior.
|
||||
|
||||
@param loggingBehavior The LoggingBehavior to enable. This should be a string defined as a constant with FBSDKLoggingBehavior*.
|
||||
*/
|
||||
+ (void)enableLoggingBehavior:(NSString *)loggingBehavior;
|
||||
|
||||
/**
|
||||
Disable a particular Facebook SDK logging behavior.
|
||||
|
||||
@param loggingBehavior The LoggingBehavior to disable. This should be a string defined as a constant with FBSDKLoggingBehavior*.
|
||||
*/
|
||||
+ (void)disableLoggingBehavior:(NSString *)loggingBehavior;
|
||||
|
||||
/**
|
||||
Set the user defaults key used by legacy token caches.
|
||||
|
||||
@param tokenInformationKeyName the key used by legacy token caches.
|
||||
|
||||
|
||||
Use this only if you customized FBSessionTokenCachingStrategy in v3.x of
|
||||
the Facebook SDK for iOS.
|
||||
*/
|
||||
+ (void)setLegacyUserDefaultTokenInformationKeyName:(NSString *)tokenInformationKeyName;
|
||||
|
||||
/**
|
||||
Get the user defaults key used by legacy token caches.
|
||||
*/
|
||||
+ (NSString *)legacyUserDefaultTokenInformationKeyName;
|
||||
@property (class, nonatomic, copy) NSSet<FBSDKLoggingBehavior> *loggingBehaviors
|
||||
NS_REFINED_FOR_SWIFT;
|
||||
|
||||
/**
|
||||
Overrides the default Graph API version to use with `FBSDKGraphRequests`. This overrides `FBSDK_TARGET_PLATFORM_VERSION`.
|
||||
|
||||
The string should be of the form `@"v2.7"`.
|
||||
|
||||
Defaults to `FBSDK_TARGET_PLATFORM_VERSION`.
|
||||
*/
|
||||
+ (void)setGraphAPIVersion:(NSString *)version;
|
||||
@property (class, nonatomic, copy, null_resettable) NSString *graphAPIVersion;
|
||||
|
||||
/**
|
||||
Returns the default Graph API version. Defaults to `FBSDK_TARGET_PLATFORM_VERSION`
|
||||
*/
|
||||
+ (NSString *)graphAPIVersion;
|
||||
Enable a particular Facebook SDK logging behavior.
|
||||
|
||||
@param loggingBehavior The LoggingBehavior to enable. This should be a string defined as a constant with FBSDKLoggingBehavior*.
|
||||
*/
|
||||
+ (void)enableLoggingBehavior:(FBSDKLoggingBehavior)loggingBehavior;
|
||||
|
||||
/**
|
||||
Disable a particular Facebook SDK logging behavior.
|
||||
|
||||
@param loggingBehavior The LoggingBehavior to disable. This should be a string defined as a constant with FBSDKLoggingBehavior*.
|
||||
*/
|
||||
+ (void)disableLoggingBehavior:(FBSDKLoggingBehavior)loggingBehavior;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+171
-93
@@ -20,12 +20,16 @@
|
||||
|
||||
#import "FBSDKAccessTokenCache.h"
|
||||
#import "FBSDKAccessTokenExpirer.h"
|
||||
#import "FBSDKAppEvents+Internal.h"
|
||||
#import "FBSDKCoreKit.h"
|
||||
|
||||
#define FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(TYPE, PLIST_KEY, GETTER, SETTER, DEFAULT_VALUE) \
|
||||
#define FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(TYPE, PLIST_KEY, GETTER, SETTER, DEFAULT_VALUE, ENABLE_CACHE) \
|
||||
static TYPE *g_##PLIST_KEY = nil; \
|
||||
+ (TYPE *)GETTER \
|
||||
{ \
|
||||
if (!g_##PLIST_KEY && ENABLE_CACHE) { \
|
||||
g_##PLIST_KEY = [[[NSUserDefaults standardUserDefaults] objectForKey:@#PLIST_KEY] copy]; \
|
||||
} \
|
||||
if (!g_##PLIST_KEY) { \
|
||||
g_##PLIST_KEY = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@#PLIST_KEY] copy] ?: DEFAULT_VALUE; \
|
||||
} \
|
||||
@@ -33,70 +37,90 @@ static TYPE *g_##PLIST_KEY = nil; \
|
||||
} \
|
||||
+ (void)SETTER:(TYPE *)value { \
|
||||
g_##PLIST_KEY = [value copy]; \
|
||||
if (ENABLE_CACHE) { \
|
||||
if (value) { \
|
||||
[[NSUserDefaults standardUserDefaults] setObject:value forKey:@#PLIST_KEY]; \
|
||||
} else { \
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@#PLIST_KEY]; \
|
||||
} \
|
||||
} \
|
||||
[FBSDKSettings _logIfSDKSettingsChanged]; \
|
||||
}
|
||||
|
||||
#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";
|
||||
NSString *const FBSDKLoggingBehaviorInformational = @"informational";
|
||||
NSString *const FBSDKLoggingBehaviorCacheErrors = @"cache_errors";
|
||||
NSString *const FBSDKLoggingBehaviorUIControlErrors = @"ui_control_errors";
|
||||
NSString *const FBSDKLoggingBehaviorDeveloperErrors = @"developer_errors";
|
||||
NSString *const FBSDKLoggingBehaviorGraphAPIDebugWarning = @"graph_api_debug_warning";
|
||||
NSString *const FBSDKLoggingBehaviorGraphAPIDebugInfo = @"graph_api_debug_info";
|
||||
NSString *const FBSDKLoggingBehaviorNetworkRequests = @"network_requests";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorAccessTokens = @"include_access_tokens";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorPerformanceCharacteristics = @"perf_characteristics";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorAppEvents = @"app_events";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorInformational = @"informational";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorCacheErrors = @"cache_errors";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorUIControlErrors = @"ui_control_errors";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorDeveloperErrors = @"developer_errors";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorGraphAPIDebugWarning = @"graph_api_debug_warning";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorGraphAPIDebugInfo = @"graph_api_debug_info";
|
||||
FBSDKLoggingBehavior FBSDKLoggingBehaviorNetworkRequests = @"network_requests";
|
||||
|
||||
static NSObject<FBSDKAccessTokenCaching> *g_tokenCache;
|
||||
static NSMutableSet *g_loggingBehaviors;
|
||||
static NSString *g_legacyUserDefaultTokenInformationKeyName = @"FBAccessTokenInformationKey";
|
||||
static NSMutableSet<FBSDKLoggingBehavior> *g_loggingBehaviors;
|
||||
static NSString *const FBSDKSettingsLimitEventAndDataUsage = @"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage";
|
||||
static NSString *const FBSDKSettingsBitmask = @"com.facebook.sdk:FBSDKSettingsBitmask";
|
||||
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;
|
||||
|
||||
//
|
||||
// Warning messages for App Event Flags
|
||||
//
|
||||
|
||||
static NSString *const autoLogAppEventsEnabledNotSetWarning =
|
||||
@"<Warning>: Please set a value for FacebookAutoLogAppEventsEnabled. Set the flag to TRUE if you want "
|
||||
"to collect app install, app launch and in-app purchase events automatically. To request user consent "
|
||||
"before collecting data, set the flag value to FALSE, then change to TRUE once user consent is received. "
|
||||
"Learn more: https://developers.facebook.com/docs/app-events/getting-started-app-events-ios#disable-auto-events.";
|
||||
static NSString *const advertiserIDCollectionEnabledNotSetWarning =
|
||||
@"<Warning>: You haven't set a value for FacebookAdvertiserIDCollectionEnabled. Set the flag to TRUE if "
|
||||
"you want to collect Advertiser ID for better advertising and analytics results. To request user consent "
|
||||
"before collecting data, set the flag value to FALSE, then change to TRUE once user consent is received. "
|
||||
"Learn more: https://developers.facebook.com/docs/app-events/getting-started-app-events-ios#disable-auto-events.";
|
||||
static NSString *const advertiserIDCollectionEnabledFalseWarning =
|
||||
@"<Warning>: The value for FacebookAdvertiserIDCollectionEnabled is currently set to FALSE so you're sending app "
|
||||
"events without collecting Advertiser ID. This can affect the quality of your advertising and analytics results.";
|
||||
|
||||
@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]];
|
||||
|
||||
[FBSDKSettings logWarnings];
|
||||
[FBSDKSettings _logIfSDKSettingsChanged];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Plist Configuration Settings
|
||||
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookAppID, appID, setAppID, nil);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookUrlSchemeSuffix, appURLSchemeSuffix, setAppURLSchemeSuffix, nil);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookClientToken, clientToken, setClientToken, nil);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDisplayName, displayName, setDisplayName, nil);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDomainPart, facebookDomainPart, setFacebookDomainPart, nil);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookJpegCompressionQuality, _JPEGCompressionQualityNumber, _setJPEGCompressionQualityNumber, @0.9);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLogEnabled, codelessDebugLogEnabled,
|
||||
setCodelessDebugLogEnabled, @0);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookAppID, appID, setAppID, nil, NO);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookUrlSchemeSuffix, appURLSchemeSuffix, setAppURLSchemeSuffix, nil, NO);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookClientToken, clientToken, setClientToken, nil, NO);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDisplayName, displayName, setDisplayName, nil, NO);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDomainPart, facebookDomainPart, setFacebookDomainPart, nil, NO);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookJpegCompressionQuality, _JPEGCompressionQualityNumber, _setJPEGCompressionQualityNumber, @0.9, NO);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAutoInitEnabled, _autoInitEnabled, _setAutoInitEnabled, @1, YES);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookInstrumentEnabled, _instrumentEnabled, _setInstrumentEnabled, @1, YES);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAutoLogAppEventsEnabled, _autoLogAppEventsEnabled, _setAutoLogAppEventsEnabled, @1, YES);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCollectionEnabled, _advertiserIDCollectionEnabled, _setAdvertiserIDCollectionEnabled, @1, YES);
|
||||
FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLogEnabled, _codelessDebugLogEnabled,
|
||||
_setCodelessDebugLogEnabled, @0, YES);
|
||||
|
||||
+ (void)setGraphErrorRecoveryDisabled:(BOOL)disableGraphErrorRecovery {
|
||||
g_disableErrorRecovery = disableGraphErrorRecovery;
|
||||
+ (BOOL)isGraphErrorRecoveryEnabled
|
||||
{
|
||||
return !g_disableErrorRecovery;
|
||||
}
|
||||
|
||||
+ (BOOL)isGraphErrorRecoveryDisabled {
|
||||
return g_disableErrorRecovery;
|
||||
+ (void)setGraphErrorRecoveryEnabled:(BOOL)graphErrorRecoveryEnabled
|
||||
{
|
||||
g_disableErrorRecovery = !graphErrorRecoveryEnabled;
|
||||
}
|
||||
|
||||
+ (CGFloat)JPEGCompressionQuality
|
||||
@@ -109,7 +133,60 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLo
|
||||
[self _setJPEGCompressionQualityNumber:@(JPEGCompressionQuality)];
|
||||
}
|
||||
|
||||
+ (BOOL)limitEventAndDataUsage
|
||||
+ (BOOL)isAutoInitEnabled
|
||||
{
|
||||
return [self _autoInitEnabled].boolValue;
|
||||
}
|
||||
|
||||
+ (void)setAutoInitEnabled:(BOOL)autoInitEnabled
|
||||
{
|
||||
[self _setAutoInitEnabled:@(autoInitEnabled)];
|
||||
if (autoInitEnabled) {
|
||||
[FBSDKApplicationDelegate initializeSDK:nil];
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)isInstrumentEnabled
|
||||
{
|
||||
return [self _instrumentEnabled].boolValue;
|
||||
}
|
||||
|
||||
+ (void)setInstrumentEnabled:(BOOL)instrumentEnabled
|
||||
{
|
||||
[self _setInstrumentEnabled:@(instrumentEnabled)];
|
||||
}
|
||||
|
||||
+ (BOOL)isCodelessDebugLogEnabled
|
||||
{
|
||||
return [self _codelessDebugLogEnabled].boolValue;
|
||||
}
|
||||
|
||||
+ (void)setCodelessDebugLogEnabled:(BOOL)codelessDebugLogEnabled
|
||||
{
|
||||
[self _setCodelessDebugLogEnabled:@(codelessDebugLogEnabled)];
|
||||
}
|
||||
|
||||
+ (BOOL)isAutoLogAppEventsEnabled
|
||||
{
|
||||
return [self _autoLogAppEventsEnabled].boolValue;
|
||||
}
|
||||
|
||||
+ (void)setAutoLogAppEventsEnabled:(BOOL)autoLogAppEventsEnabled
|
||||
{
|
||||
[self _setAutoLogAppEventsEnabled:@(autoLogAppEventsEnabled)];
|
||||
}
|
||||
|
||||
+ (BOOL)isAdvertiserIDCollectionEnabled
|
||||
{
|
||||
return [self _advertiserIDCollectionEnabled].boolValue;
|
||||
}
|
||||
|
||||
+ (void)setAdvertiserIDCollectionEnabled:(BOOL)advertiserIDCollectionEnabled
|
||||
{
|
||||
[self _setAdvertiserIDCollectionEnabled:@(advertiserIDCollectionEnabled)];
|
||||
}
|
||||
|
||||
+ (BOOL)shouldLimitEventAndDataUsage
|
||||
{
|
||||
NSNumber *storedValue = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsLimitEventAndDataUsage];
|
||||
if (storedValue == nil) {
|
||||
@@ -125,10 +202,10 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLo
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
||||
+ (NSSet<NSString *> *)loggingBehaviors
|
||||
+ (NSSet<FBSDKLoggingBehavior> *)loggingBehaviors
|
||||
{
|
||||
if (!g_loggingBehaviors) {
|
||||
NSArray *bundleLoggingBehaviors = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FacebookLoggingBehavior"];
|
||||
NSArray<FBSDKLoggingBehavior> *bundleLoggingBehaviors = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FacebookLoggingBehavior"];
|
||||
if (bundleLoggingBehaviors) {
|
||||
g_loggingBehaviors = [[NSMutableSet alloc] initWithArray:bundleLoggingBehaviors];
|
||||
} else {
|
||||
@@ -140,7 +217,7 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLo
|
||||
return [g_loggingBehaviors copy];
|
||||
}
|
||||
|
||||
+ (void)setLoggingBehaviors:(NSSet<NSString *> *)loggingBehaviors
|
||||
+ (void)setLoggingBehaviors:(NSSet<FBSDKLoggingBehavior> *)loggingBehaviors
|
||||
{
|
||||
if (![g_loggingBehaviors isEqualToSet:loggingBehaviors]) {
|
||||
g_loggingBehaviors = [loggingBehaviors mutableCopy];
|
||||
@@ -149,17 +226,7 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLo
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSSet *)loggingBehavior
|
||||
{
|
||||
return [self loggingBehaviors];
|
||||
}
|
||||
|
||||
+ (void)setLoggingBehavior:(NSSet *)loggingBehavior
|
||||
{
|
||||
[self setLoggingBehaviors:loggingBehavior];
|
||||
}
|
||||
|
||||
+ (void)enableLoggingBehavior:(NSString *)loggingBehavior
|
||||
+ (void)enableLoggingBehavior:(FBSDKLoggingBehavior)loggingBehavior
|
||||
{
|
||||
if (!g_loggingBehaviors) {
|
||||
[self loggingBehaviors];
|
||||
@@ -168,7 +235,7 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLo
|
||||
[self updateGraphAPIDebugBehavior];
|
||||
}
|
||||
|
||||
+ (void)disableLoggingBehavior:(NSString *)loggingBehavior
|
||||
+ (void)disableLoggingBehavior:(FBSDKLoggingBehavior)loggingBehavior
|
||||
{
|
||||
if (!g_loggingBehaviors) {
|
||||
[self loggingBehaviors];
|
||||
@@ -177,18 +244,6 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLo
|
||||
[self updateGraphAPIDebugBehavior];
|
||||
}
|
||||
|
||||
+ (void)setLegacyUserDefaultTokenInformationKeyName:(NSString *)tokenInformationKeyName
|
||||
{
|
||||
if (![g_legacyUserDefaultTokenInformationKeyName isEqualToString:tokenInformationKeyName]) {
|
||||
g_legacyUserDefaultTokenInformationKeyName = tokenInformationKeyName;
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)legacyUserDefaultTokenInformationKeyName
|
||||
{
|
||||
return g_legacyUserDefaultTokenInformationKeyName;
|
||||
}
|
||||
|
||||
#pragma mark - Readonly Configuration Settings
|
||||
|
||||
+ (NSString *)sdkVersion
|
||||
@@ -230,9 +285,14 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLo
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)defaultGraphAPIVersion
|
||||
{
|
||||
return FBSDK_TARGET_PLATFORM_VERSION;
|
||||
}
|
||||
|
||||
+ (NSString *)graphAPIVersion
|
||||
{
|
||||
return g_defaultGraphAPIVersion ?: FBSDK_TARGET_PLATFORM_VERSION;
|
||||
return g_defaultGraphAPIVersion ?: self.defaultGraphAPIVersion;
|
||||
}
|
||||
|
||||
+ (NSNumber *)appEventSettingsForPlistKey:(NSString *)plistKey
|
||||
@@ -251,34 +311,52 @@ FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLo
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
+ (NSNumber *)autoLogAppEventsEnabled
|
||||
+ (void)logWarnings
|
||||
{
|
||||
return g_autoLogAppEventsEnabled;
|
||||
}
|
||||
|
||||
+ (void)setAutoLogAppEventsEnabled:(NSNumber *)autoLogAppEventsEnabled
|
||||
{
|
||||
if (autoLogAppEventsEnabled == nil || [g_autoLogAppEventsEnabled isEqual:autoLogAppEventsEnabled]) {
|
||||
return;
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
// Log warnings for App Event Flags
|
||||
if (![mainBundle objectForInfoDictionaryKey:@"FacebookAutoLogAppEventsEnabled"]) {
|
||||
NSLog(autoLogAppEventsEnabledNotSetWarning);
|
||||
}
|
||||
|
||||
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;
|
||||
if (![mainBundle objectForInfoDictionaryKey:@"FacebookAdvertiserIDCollectionEnabled"]) {
|
||||
NSLog(advertiserIDCollectionEnabledNotSetWarning);
|
||||
}
|
||||
if (![FBSDKSettings isAdvertiserIDCollectionEnabled]) {
|
||||
NSLog(advertiserIDCollectionEnabledFalseWarning);
|
||||
}
|
||||
}
|
||||
|
||||
g_advertiserIDCollectionEnabled = [advertiserIDCollectionEnabled copy];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:g_advertiserIDCollectionEnabled forKey:[NSString stringWithFormat:FBSDKSETTINGS_ADVERTISERID_COLLECTION_ENABLED_USER_DEFAULTS_KEY, [self appID]]];
|
||||
+ (void)_logIfSDKSettingsChanged
|
||||
{
|
||||
NSInteger bitmask = 0;
|
||||
NSInteger bit = 0;
|
||||
bitmask |= ([FBSDKSettings isAutoInitEnabled] ? 1 : 0) << bit++;
|
||||
bitmask |= ([FBSDKSettings isAutoLogAppEventsEnabled] ? 1 : 0) << bit++;
|
||||
bitmask |= ([FBSDKSettings isAdvertiserIDCollectionEnabled] ? 1 : 0) << bit++;
|
||||
|
||||
NSInteger previousBitmask = [[NSUserDefaults standardUserDefaults] integerForKey:FBSDKSettingsBitmask];
|
||||
if (previousBitmask != bitmask) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:bitmask forKey:FBSDKSettingsBitmask];
|
||||
|
||||
NSArray<NSString *> *keys = @[@"FacebookAutoInitEnabled",
|
||||
@"FacebookAutoLogAppEventsEnabled",
|
||||
@"FacebookAdvertiserIDCollectionEnabled"];
|
||||
NSArray<NSNumber *> *defaultValues = @[@YES, @YES, @YES];
|
||||
NSInteger initialBitmask = 0;
|
||||
NSInteger usageBitmask = 0;
|
||||
for (int i = 0; i < keys.count; i++) {
|
||||
NSNumber *plistValue = [[NSBundle mainBundle] objectForInfoDictionaryKey:keys[i]];
|
||||
BOOL initialValue = [(plistValue ?: defaultValues[i]) boolValue];
|
||||
initialBitmask |= (initialValue ? 1 : 0) << i;
|
||||
usageBitmask |= (plistValue != nil ? 1 : 0) << i;
|
||||
}
|
||||
[FBSDKAppEvents logInternalEvent:@"fb_sdk_settings_changed"
|
||||
parameters:@{@"usage": @(usageBitmask),
|
||||
@"initial": @(initialBitmask),
|
||||
@"previous":@(previousBitmask),
|
||||
@"current": @(bitmask)}
|
||||
isImplicitlyLogged:YES];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Internal - Graph API Debug
|
||||
|
||||
+24
-18
@@ -18,19 +18,17 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FBSDKConstants.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class FBSDKAccessToken;
|
||||
|
||||
/**
|
||||
|
||||
Callback block for returning an array of FBSDKAccessToken instances (and possibly `NSNull` instances); or an error.
|
||||
Callback block for returning an array of FBSDKAccessToken instances (and possibly `NSNull` instances); or an error.
|
||||
*/
|
||||
typedef void (^FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)(NSArray *tokens, NSError *error) ;
|
||||
|
||||
/**
|
||||
|
||||
Callback block for removing a test user.
|
||||
*/
|
||||
typedef void (^FBSDKTestUsersManagerRemoveTestAccountHandler)(NSError *error) ;
|
||||
typedef void (^FBSDKAccessTokensBlock)(NSArray<FBSDKAccessToken *> *tokens, NSError *_Nullable error)
|
||||
NS_SWIFT_NAME(AccessTokensBlock);
|
||||
|
||||
|
||||
/**
|
||||
@@ -46,6 +44,7 @@ typedef void (^FBSDKTestUsersManagerRemoveTestAccountHandler)(NSError *error) ;
|
||||
an app id and app secret. You will typically use this class to write unit or integration tests.
|
||||
Make sure you NEVER include your app secret in your production app.
|
||||
*/
|
||||
NS_SWIFT_NAME(TestUsersManager)
|
||||
@interface FBSDKTestUsersManager : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
@@ -56,14 +55,14 @@ typedef void (^FBSDKTestUsersManagerRemoveTestAccountHandler)(NSError *error) ;
|
||||
@param appID the Facebook app id
|
||||
@param appSecret the Facebook app secret
|
||||
*/
|
||||
+ (instancetype)sharedInstanceForAppID:(NSString *)appID appSecret:(NSString *)appSecret;
|
||||
+ (instancetype)sharedInstanceForAppID:(NSString *)appID appSecret:(NSString *)appSecret
|
||||
NS_SWIFT_NAME(shared(forAppID:appSecret:));
|
||||
|
||||
/**
|
||||
retrieve FBSDKAccessToken instances for test accounts with the specific permissions.
|
||||
@param arraysOfPermissions an array of permissions sets, such as @[ [NSSet setWithObject:@"email"], [NSSet setWithObject:@"user_birthday"]]
|
||||
if you needed two test accounts with email and birthday permissions, respectively. You can pass in empty nested sets
|
||||
if you need two arbitrary test accounts. For convenience, passing nil is treated as @[ [NSSet set] ]
|
||||
for fetching a single test user.
|
||||
if you need two arbitrary test accounts.
|
||||
@param createIfNotFound if YES, new test accounts are created if no test accounts existed that fit the permissions
|
||||
requirement
|
||||
@param handler the callback to invoke which will return an array of `FBAccessTokenData` instances or an `NSError`.
|
||||
@@ -74,24 +73,26 @@ typedef void (^FBSDKTestUsersManagerRemoveTestAccountHandler)(NSError *error) ;
|
||||
`arrayOfPermissionsArrays` so that the most number of permissions come first to minimize creation of new
|
||||
test accounts.
|
||||
*/
|
||||
- (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray *)arraysOfPermissions
|
||||
- (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray<NSSet<NSString *> *> *)arraysOfPermissions
|
||||
createIfNotFound:(BOOL)createIfNotFound
|
||||
completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler;
|
||||
completionHandler:(nullable FBSDKAccessTokensBlock)handler
|
||||
NS_SWIFT_NAME(requestTestAccountTokens(withPermissions:createIfNotFound:completionHandler:));
|
||||
|
||||
/**
|
||||
add a test account with the specified permissions
|
||||
@param permissions the set of permissions, e.g., [NSSet setWithObjects:@"email", @"user_friends"]
|
||||
@param handler the callback handler
|
||||
*/
|
||||
- (void)addTestAccountWithPermissions:(NSSet *)permissions
|
||||
completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler;
|
||||
- (void)addTestAccountWithPermissions:(NSSet<NSString *> *)permissions
|
||||
completionHandler:(nullable FBSDKAccessTokensBlock)handler;
|
||||
|
||||
/**
|
||||
remove a test account for the given user id
|
||||
@param userId the user id
|
||||
@param handler the callback handler
|
||||
*/
|
||||
- (void)removeTestAccount:(NSString *)userId completionHandler:(FBSDKTestUsersManagerRemoveTestAccountHandler)handler;
|
||||
- (void)removeTestAccount:(NSString *)userId
|
||||
completionHandler:(nullable FBSDKErrorBlock)handler;
|
||||
|
||||
/**
|
||||
Make two test users friends with each other.
|
||||
@@ -99,6 +100,11 @@ typedef void (^FBSDKTestUsersManagerRemoveTestAccountHandler)(NSError *error) ;
|
||||
@param second the token of the second user
|
||||
@param callback the callback handler
|
||||
*/
|
||||
- (void)makeFriendsWithFirst:(FBSDKAccessToken *)first second:(FBSDKAccessToken *)second callback:(void (^)(NSError *))callback;
|
||||
- (void)makeFriendsWithFirst:(FBSDKAccessToken *)first
|
||||
second:(FBSDKAccessToken *)second
|
||||
callback:(nullable FBSDKErrorBlock)callback
|
||||
NS_SWIFT_NAME(makeFriends(first:second:callback:));
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+22
-21
@@ -18,12 +18,12 @@
|
||||
|
||||
#import "FBSDKTestUsersManager.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
static NSString *const kFBGraphAPITestUsersPathFormat = @"%@/accounts/test-users";
|
||||
static NSString *const kAccountsDictionaryTokenKey = @"access_token";
|
||||
static NSString *const kAccountsDictionaryPermissionsKey = @"permissions";
|
||||
static NSMutableDictionary *gInstancesDictionary;
|
||||
static NSMutableDictionary<NSString *, FBSDKTestUsersManager *> *gInstancesDictionary;
|
||||
|
||||
@interface FBSDKTestUsersManager()
|
||||
- (instancetype)initWithAppID:(NSString *)appID appSecret:(NSString *)appSecret NS_DESIGNATED_INITIALIZER;
|
||||
@@ -61,16 +61,16 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
return gInstancesDictionary[instanceKey];
|
||||
}
|
||||
|
||||
- (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray *)arraysOfPermissions
|
||||
- (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray<NSSet<NSString *> *> *)arraysOfPermissions
|
||||
createIfNotFound:(BOOL)createIfNotFound
|
||||
completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler {
|
||||
completionHandler:(FBSDKAccessTokensBlock)handler {
|
||||
arraysOfPermissions = arraysOfPermissions ?: @[[NSSet set]];
|
||||
|
||||
// wrap work in a block so that we can chain it to after a fetch of existing accounts if we need to.
|
||||
void (^helper)(NSError *) = ^(NSError *error){
|
||||
if (error) {
|
||||
if (handler) {
|
||||
handler(nil, error);
|
||||
handler(@[], error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
completionHandler:^(NSArray *tokens, NSError *addError) {
|
||||
if (addError) {
|
||||
if (handler) {
|
||||
handler(nil, addError);
|
||||
handler(@[], addError);
|
||||
}
|
||||
} else {
|
||||
[weakSelf requestTestAccountTokensWithArraysOfPermissions:arraysOfPermissions
|
||||
@@ -123,7 +123,7 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
}
|
||||
|
||||
- (void)addTestAccountWithPermissions:(NSSet *)permissions
|
||||
completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler {
|
||||
completionHandler:(FBSDKAccessTokensBlock)handler {
|
||||
NSDictionary *params = @{
|
||||
@"installed" : @"true",
|
||||
@"permissions" : [permissions.allObjects componentsJoinedByString:@","],
|
||||
@@ -133,11 +133,11 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
parameters:params
|
||||
tokenString:[self appAccessToken]
|
||||
version:nil
|
||||
HTTPMethod:@"POST"];
|
||||
HTTPMethod:FBSDKHTTPMethodPOST];
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
if (error) {
|
||||
if (handler) {
|
||||
handler(nil, error);
|
||||
handler(@[], error);
|
||||
}
|
||||
} else {
|
||||
NSMutableDictionary *accountData = [NSMutableDictionary dictionaryWithCapacity:2];
|
||||
@@ -155,7 +155,7 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)makeFriendsWithFirst:(FBSDKAccessToken *)first second:(FBSDKAccessToken *)second callback:(void (^)(NSError *))callback
|
||||
- (void)makeFriendsWithFirst:(FBSDKAccessToken *)first second:(FBSDKAccessToken *)second callback:(FBSDKErrorBlock)callback
|
||||
{
|
||||
__block int expectedCount = 2;
|
||||
void (^complete)(NSError *) = ^(NSError *error) {
|
||||
@@ -169,15 +169,15 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
}
|
||||
};
|
||||
FBSDKGraphRequest *one = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/friends/%@", first.userID, second.userID]
|
||||
parameters:nil
|
||||
parameters:@{}
|
||||
tokenString:first.tokenString
|
||||
version:nil
|
||||
HTTPMethod:@"POST"];
|
||||
HTTPMethod:FBSDKHTTPMethodPOST];
|
||||
FBSDKGraphRequest *two = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/friends/%@", second.userID, first.userID]
|
||||
parameters:nil
|
||||
parameters:@{}
|
||||
tokenString:second.tokenString
|
||||
version:nil
|
||||
HTTPMethod:@"POST"];
|
||||
HTTPMethod:FBSDKHTTPMethodPOST];
|
||||
FBSDKGraphRequestConnection *conn = [[FBSDKGraphRequestConnection alloc] init];
|
||||
[conn addRequest:one
|
||||
batchEntryName:@"first"
|
||||
@@ -192,9 +192,9 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
[conn start];
|
||||
}
|
||||
|
||||
- (void)removeTestAccount:(NSString *)userId completionHandler:(FBSDKTestUsersManagerRemoveTestAccountHandler)handler {
|
||||
- (void)removeTestAccount:(NSString *)userId completionHandler:(FBSDKErrorBlock)handler {
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:userId
|
||||
parameters:nil
|
||||
parameters:@{}
|
||||
tokenString:self.appAccessToken
|
||||
version:nil
|
||||
HTTPMethod:@"DELETE"];
|
||||
@@ -210,7 +210,8 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
- (FBSDKAccessToken *)tokenDataForTokenString:(NSString *)tokenString permissions:(NSSet *)permissions userId:(NSString *)userId{
|
||||
return [[FBSDKAccessToken alloc] initWithTokenString:tokenString
|
||||
permissions:permissions.allObjects
|
||||
declinedPermissions:nil
|
||||
declinedPermissions:@[]
|
||||
expiredPermissions:@[]
|
||||
appID:_appID
|
||||
userID:userId
|
||||
expirationDate:nil
|
||||
@@ -244,7 +245,7 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
return [NSString stringWithFormat:@"%@|%@", _appID, _appSecret];
|
||||
}
|
||||
|
||||
- (void)fetchExistingTestAccountsWithAfterCursor:(NSString *)after handler:(void(^)(NSError *error))handler {
|
||||
- (void)fetchExistingTestAccountsWithAfterCursor:(NSString *)after handler:(FBSDKErrorBlock)handler {
|
||||
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
|
||||
FBSDKGraphRequest *requestForAccountIds = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:kFBGraphAPITestUsersPathFormat, _appID]
|
||||
parameters:@{@"limit" : @"50",
|
||||
@@ -253,7 +254,7 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
}
|
||||
tokenString:self.appAccessToken
|
||||
version:nil
|
||||
HTTPMethod:nil];
|
||||
HTTPMethod:FBSDKHTTPMethodGET];
|
||||
__block NSString *afterCursor = nil;
|
||||
__block NSInteger expectedTestAccounts = 0;
|
||||
FBSDKGraphRequestConnection *permissionConnection = [[FBSDKGraphRequestConnection alloc] init];
|
||||
@@ -274,10 +275,10 @@ static NSMutableDictionary *gInstancesDictionary;
|
||||
self->_accounts[userId][kAccountsDictionaryTokenKey] = token;
|
||||
expectedTestAccounts++;
|
||||
[permissionConnection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@?fields=permissions", userId]
|
||||
parameters:nil
|
||||
parameters:@{}
|
||||
tokenString:self.appAccessToken
|
||||
version:nil
|
||||
HTTPMethod:nil]
|
||||
HTTPMethod:FBSDKHTTPMethodGET]
|
||||
completionHandler:^(FBSDKGraphRequestConnection *innerConnection2, id innerResult, NSError *innerError) {
|
||||
if (self->_accounts.count == 0) {
|
||||
// indicates an earlier error that was already passed to handler, so just short circuit.
|
||||
|
||||
+21
-15
@@ -22,62 +22,68 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class FBSDKAppLink;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Provides a set of utilities for working with NSURLs, such as parsing of query parameters
|
||||
and handling for App Link requests.
|
||||
*/
|
||||
NS_SWIFT_NAME(AppLinkURL)
|
||||
@interface FBSDKURL : NSObject
|
||||
|
||||
/*!
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Creates a link target from a raw URL.
|
||||
On success, this posts the FBSDKAppLinkParseEventName measurement event. If you are constructing the FBSDKURL within your application delegate's
|
||||
application:openURL:sourceApplication:annotation:, you should instead use URLWithInboundURL:sourceApplication:
|
||||
to support better FBSDKMeasurementEvent notifications
|
||||
@param url The instance of `NSURL` to create FBSDKURL from.
|
||||
*/
|
||||
+ (FBSDKURL *)URLWithURL:(NSURL *)url;
|
||||
+ (instancetype)URLWithURL:(NSURL *)url
|
||||
NS_SWIFT_NAME(init(url:));
|
||||
|
||||
/*!
|
||||
/**
|
||||
Creates a link target from a raw URL received from an external application. This is typically called from the app delegate's
|
||||
application:openURL:sourceApplication:annotation: and will post the FBSDKAppLinkNavigateInEventName measurement event.
|
||||
@param url The instance of `NSURL` to create FBSDKURL from.
|
||||
@param sourceApplication the bundle ID of the app that is requesting your app to open the URL. The same sourceApplication in application:openURL:sourceApplication:annotation:
|
||||
*/
|
||||
+ (FBSDKURL *)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication;
|
||||
+ (instancetype)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
|
||||
NS_SWIFT_NAME(init(inboundURL:sourceApplication:));
|
||||
|
||||
/*!
|
||||
/**
|
||||
Gets the target URL. If the link is an App Link, this is the target of the App Link.
|
||||
Otherwise, it is the url that created the target.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSURL *targetURL;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Gets the query parameters for the target, parsed into an NSDictionary.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSDictionary<NSString *, id> *targetQueryParameters;
|
||||
|
||||
/*!
|
||||
/**
|
||||
If this link target is an App Link, this is the data found in al_applink_data.
|
||||
Otherwise, it is nil.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSDictionary<NSString *, id> *appLinkData;
|
||||
@property (nonatomic, strong, readonly, nullable) NSDictionary<NSString *, id> *appLinkData;
|
||||
|
||||
/*!
|
||||
/**
|
||||
If this link target is an App Link, this is the data found in extras.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSDictionary<NSString *, id> *appLinkExtras;
|
||||
@property (nonatomic, strong, readonly, nullable) NSDictionary<NSString *, id> *appLinkExtras;
|
||||
|
||||
/*!
|
||||
/**
|
||||
The App Link indicating how to navigate back to the referer app, if any.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) FBSDKAppLink *appLinkReferer;
|
||||
@property (nonatomic, strong, readonly, nullable) FBSDKAppLink *appLinkReferer;
|
||||
|
||||
/*!
|
||||
/**
|
||||
The URL that was used to create this FBSDKURL.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSURL *inputURL;
|
||||
|
||||
/*!
|
||||
/**
|
||||
The query parameters of the inputURL, parsed into an NSDictionary.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSDictionary<NSString *, id> *inputQueryParameters;
|
||||
|
||||
@@ -110,15 +110,15 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (FBSDKURL *)URLWithURL:(NSURL *)url {
|
||||
+ (instancetype)URLWithURL:(NSURL *)url {
|
||||
return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:NO];
|
||||
}
|
||||
|
||||
+ (FBSDKURL *)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication {
|
||||
+ (instancetype)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication {
|
||||
return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:YES sourceApplication:sourceApplication forRenderBackToReferrerBar:NO];
|
||||
}
|
||||
|
||||
+ (FBSDKURL *)URLForRenderBackToReferrerBarURL:(NSURL *)url {
|
||||
+ (instancetype)URLForRenderBackToReferrerBarURL:(NSURL *)url {
|
||||
return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:YES];
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 535 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user