Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor AppDelegate #1793

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## Unreleased

### Added

- Reintroduces `initializeSDK` method to `FBSDKApplicationDelegate`

### Changed

- Introduced [Xcodegen](https://github.com/yonaskolb/XcodeGen) for generating project files. Moving forward, We will now use Xcodegen to generate the project files that are used to build the SDK releases. There should be no impact to SDK users. However, some build settings were restored to Xcode defaults as a result of this change, and output binaries may be affected in unpredictable ways. Contributors to the SDK should run the new, top-level script `generate-projects.sh` to ensure that the project files they are using are the same as those being used in CI and for releases. The next major version will remove the project files from version control. If you experience any of these issues, please open an [issue](https://github.com/facebook/facebook-ios-sdk/issues/new/choose) and we will look into it.
Expand All @@ -21,6 +25,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- `uploadVideoWithConfiguration:andResultCompletionHandler` is replaced by `uploadVideoWithConfiguration:andResultCompletion`
- `FBSDKGamingPayloadObserver`'s `shared` instance. Going forward a user should create and retain their own instance of a payload observer for as long as they'd like to receive callbacks from its delegate.

### Fixed

- Initializing the SDK in when UIApplication is unavailable [#1748](https://github.com/facebook/facebook-ios-sdk/issues/1748)
- Issue caused by `initializeSDK` deprecation [#1731](https://github.com/facebook/facebook-ios-sdk/issues/1731)

[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v11.0.1...HEAD)

## 11.0.1
Expand Down
3 changes: 2 additions & 1 deletion FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m
Original file line number Diff line number Diff line change
Expand Up @@ -1703,7 +1703,8 @@ - (void)validateConfiguration
if (!self.isConfigured) {
static NSString *const reason = @"As of v9.0, you must initialize the SDK prior to calling any methods or setting any properties. "
"You can do this by calling `FBSDKApplicationDelegate`'s `application:didFinishLaunchingWithOptions:` method. "
"Learn more: https://developers.facebook.com/docs/ios/getting-started";
"Learn more: https://developers.facebook.com/docs/ios/getting-started"
"If no `UIApplication` is available you can use `FBSDKApplicationDelegate`'s `initializeSDK` method.";
@throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil];
}
#endif
Expand Down
3 changes: 2 additions & 1 deletion FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkUtility.m
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ + (void)validateConfiguration
if (!_isConfigured) {
static NSString *const reason = @"As of v9.0, you must initialize the SDK prior to calling any methods or setting any properties. "
"You can do this by calling `FBSDKApplicationDelegate`'s `application:didFinishLaunchingWithOptions:` method."
"Learn more: https://developers.facebook.com/docs/ios/getting-started";
"Learn more: https://developers.facebook.com/docs/ios/getting-started"
"If no `UIApplication` is available you can use `FBSDKApplicationDelegate`'s `initializeSDK` method.";
@throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil];
}
#endif
Expand Down
11 changes: 11 additions & 0 deletions FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ controlled via 'FacebookAutoLogAppEventsEnabled' key in the project info plist f
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(nullable NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions;

/**
Initializes the SDK.

If you are using the SDK within the context of the UIApplication lifecycle, do not use this method.
Instead use `application: didFinishLaunchingWithOptions:`.

As part of SDK initialization basic auto logging of app events will occur, this can be
controlled via 'FacebookAutoLogAppEventsEnabled' key in the project info plist file.
*/
- (void)initializeSDK;

/**
Adds an observer that will be informed about application lifecycle events.

Expand Down
134 changes: 103 additions & 31 deletions FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,14 @@ - (instancetype)initWithNotificationCenter:(id<FBSDKNotificationObserving, FBSDK

#endif

- (void)initializeSDK
{
[self initializeSDKWithLaunchOptions:@{}];
}

- (void)initializeSDKWithLaunchOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions
{
if (hasInitializeBeenCalled) {
// Do nothing if initialized already
return;
} else {
hasInitializeBeenCalled = YES;
Expand All @@ -244,45 +248,79 @@ - (void)initializeSDKWithLaunchOptions:(NSDictionary<UIApplicationLaunchOptionsK
//
[self configureDependencies];

id<FBSDKSettingsLogging> const settingsLogger = self.settings;
[settingsLogger logWarnings];
[settingsLogger logIfSDKSettingsChanged];
[settingsLogger recordInstall];

[self logInitialization];
[self addObservers];

[self.appEvents startObservingApplicationLifecycleNotifications];

[self application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:launchOptions];
[self handleDeferredActivationIfNeeded];
[self enableInstrumentation];

// In case of sdk autoInit enabled sdk expects one appDidBecomeActive notification after app launch and has some logic to ignore it.
// if sdk autoInit disabled app won't receive appDidBecomeActive on app launch and will ignore the first one it gets instead of handling it.
// Send first applicationDidBecomeActive notification manually
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
[self applicationDidBecomeActive:nil];
}
#if !TARGET_OS_TV
[self logBackgroundRefreshStatus];
[self initializeAppLink];
#endif

[self.featureChecker checkFeature:FBSDKFeatureInstrument completionBlock:^(BOOL enabled) {
if (enabled) {
[FBSDKInstrumentManager.shared enable];
}
}];
[self configureSourceApplicationWithLaunchOptions:launchOptions];
}

#if !TARGET_OS_TV
[self.backgroundEventLogger logBackgroundRefresStatus:[UIApplication.sharedApplication backgroundRefreshStatus]];
// Register Listener for App Link measurement events
[FBSDKMeasurementEventListener defaultListener];
- (void)initializeAppLink
{
[self initializeMeasurementListener];
[self _logIfAutoAppLinkEnabled];
}
#endif

- (void)handleDeferredActivationIfNeeded
{
// If sdk initialization is deferred until after the applicationDidBecomeActive notification is received, then we need to manually perform this work in case it hasn't happened at all.
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
[self applicationDidBecomeActive:nil];
}
}

- (void)configureSourceApplicationWithLaunchOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions
{
// Set the SourceApplication for time spent data. This is not going to update the value if the app has already launched.
[self.appEvents setSourceApplication:launchOptions[UIApplicationLaunchOptionsSourceApplicationKey]
openURL:launchOptions[UIApplicationLaunchOptionsURLKey]];
// Register on UIApplicationDidEnterBackgroundNotification events to reset source application data when app backgrounds.
[self.appEvents registerAutoResetSourceApplication];

[FBSDKInternalUtility.sharedUtility validateFacebookReservedURLSchemes];
}

#if !TARGET_OS_TV
- (void)initializeMeasurementListener
{
// Register Listener for App Link measurement events
[FBSDKMeasurementEventListener defaultListener];
}
#endif

#if !TARGET_OS_TV
- (void)logBackgroundRefreshStatus
{
[self.backgroundEventLogger logBackgroundRefresStatus:[UIApplication.sharedApplication backgroundRefreshStatus]];
}
#endif

- (void)logInitialization
{
id<FBSDKSettingsLogging> const settingsLogger = self.settings;
[settingsLogger logWarnings];
[settingsLogger logIfSDKSettingsChanged];
[settingsLogger recordInstall];
}

- (void)enableInstrumentation
{
[self.featureChecker checkFeature:FBSDKFeatureInstrument completionBlock:^(BOOL enabled) {
if (enabled) {
[FBSDKInstrumentManager.shared enable];
}
}];
}

- (void)addObservers
{
id<FBSDKNotificationObserving> const observer = self.notificationObserver;
Expand Down Expand Up @@ -368,6 +406,8 @@ - (BOOL)application:(UIApplication *)application
return NO;
}

// MARK: Finish Launching

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (self.isAppLaunched) {
Expand All @@ -380,37 +420,69 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

self.isAppLaunched = YES;

// Retrieve cached tokens
[self initializeTokenCache];
[self fetchServerConfiguration];

if (self.settings.isAutoLogAppEventsEnabled) {
[self _logSDKInitialize];
}

#if !TARGET_OS_TV
[self initializeProfile];
[self checkAuthentication];
#endif

return [self notifyLaunchObserversWithApplication:application
launchOptions:launchOptions];
}

- (void)initializeTokenCache
{
FBSDKAccessToken *cachedToken = [[self.tokenWallet tokenCache] accessToken];
[self.tokenWallet setCurrentAccessToken:cachedToken];
}

// fetch app settings
- (void)fetchServerConfiguration
{
[self.serverConfigurationProvider loadServerConfigurationWithCompletionBlock:NULL];
}

if (self.settings.isAutoLogAppEventsEnabled) {
[self _logSDKInitialize];
}
#if !TARGET_OS_TV
- (void)initializeProfile
{
FBSDKProfile *cachedProfile = [self.profileProvider fetchCachedProfile];
[self.profileProvider setCurrentProfile:cachedProfile];
}
#endif

#if !TARGET_OS_TV
- (void)checkAuthentication
{
FBSDKAuthenticationToken *cachedAuthToken = [[self.authenticationTokenWallet tokenCache] authenticationToken];
[self.authenticationTokenWallet setCurrentAuthenticationToken:cachedAuthToken];

[FBSDKAuthenticationStatusUtility checkAuthenticationStatus];
}
#endif

- (BOOL)notifyLaunchObserversWithApplication:(UIApplication *)application
launchOptions:(NSDictionary *)launchOptions
{
NSArray<id<FBSDKApplicationObserving>> *observers = [self.applicationObservers allObjects];
BOOL handled = NO;
BOOL someObserverHandledLaunch = NO;
for (id<FBSDKApplicationObserving> observer in observers) {
if ([observer respondsToSelector:@selector(application:didFinishLaunchingWithOptions:)]) {
if ([observer application:application didFinishLaunchingWithOptions:launchOptions]) {
handled = YES;
someObserverHandledLaunch = YES;
}
}
}

return handled;
return someObserverHandledLaunch;
}

// MARK: Entering Background

- (void)applicationDidEnterBackground:(NSNotification *)notification
{
[self setApplicationState:UIApplicationStateBackground];
Expand Down
3 changes: 2 additions & 1 deletion FBSDKCoreKit/FBSDKCoreKit/FBSDKInternalUtility.m
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,8 @@ - (void)validateConfiguration
if (!self.isConfigured) {
static NSString *const reason = @"As of v9.0, you must initialize the SDK prior to calling any methods or setting any properties. "
"You can do this by calling `FBSDKApplicationDelegate`'s `application:didFinishLaunchingWithOptions:` method. "
"Learn more: https://developers.facebook.com/docs/ios/getting-started";
"Learn more: https://developers.facebook.com/docs/ios/getting-started"
"If no `UIApplication` is available you can use `FBSDKApplicationDelegate`'s `initializeSDK` method.";
@throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil];
}
#endif
Expand Down
3 changes: 2 additions & 1 deletion FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,8 @@ - (void)validateConfiguration
if (!self.isConfigured) {
static NSString *const reason = @"As of v9.0, you must initialize the SDK prior to calling any methods or setting any properties. "
"You can do this by calling `FBSDKApplicationDelegate`'s `application:didFinishLaunchingWithOptions:` method."
"Learn more: https://developers.facebook.com/docs/ios/getting-started";
"Learn more: https://developers.facebook.com/docs/ios/getting-started"
"If no `UIApplication` is available you can use `FBSDKApplicationDelegate`'s `initializeSDK` method.";
@throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil];
}
#endif
Expand Down