SDK v17.0.0 may not get valid AccessToken immediately after call ApplicationDelegate didFinishLaunchingWithOptions
tzuyangliu opened this issue · comments
Checklist before submitting a bug report
- I've updated to the latest released version of the SDK
- I've searched for existing GitHub issues
- I've looked for existing answers on Stack Overflow, the Facebook Developer Community Forum and the Facebook Developers Group
- I've read the Code of Conduct
- This issue is not security related and can safely be disclosed publicly on GitHub
Xcode version
15.2
Facebook iOS SDK version
17.0.0
Dependency Manager
CocoaPods
SDK Framework
Login
Goals
In response to Apple's privacy manifests requirements, upgrade Facebook SDK. Encounter this problem after upgrading.
Firstly, initializes the SDK when my app launch:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions{
[[FBSDKApplicationDelegate sharedInstance] application:app didFinishLaunchingWithOptions:opitons];
return YES;
}
Right after this, app will check for an existing token:
id token = [FBSDKAccessToken currentAccessToken];
Expected results
The [FBSDKAccessToken currentAccessToken] not be nil
Actual results
The [FBSDKAccessToken currentAccessToken] may be nil
I checked some previous stackoverflow question records(https://stackoverflow.com/questions/32950937/fbsdkaccesstoken-currentaccesstoken-nil-after-quitting-app) and found that it was not the same problem.
Steps to reproduce
I tried to compare the source code and found the reason for this difference.
Here's 17.0.0's FBSDKApplicationDelegate code:
@discardableResult
public func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
guard
!isAppLaunched,
!hasInitializeBeenCalled
else { return false }
initializeSDK(launchOptions: launchOptions) {
self.isAppLaunched = true
self.initializeTokenCache()
self.fetchServerConfiguration()
if self.components.settings.isAutoLogAppEventsEnabled {
self.logSDKInitialize()
}
self.initializeProfile()
self.checkAuthentication()
_ = self.notifyLaunchObservers(application: application, launchOptions: launchOptions)
}
return true
}
Here's 16.3.1's FBSDKApplicationDelegate code:
@discardableResult
public func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
guard
!isAppLaunched,
!hasInitializeBeenCalled
else { return false }
initializeSDK(launchOptions: launchOptions)
isAppLaunched = true
initializeTokenCache()
fetchServerConfiguration()
if components.settings.isAutoLogAppEventsEnabled {
logSDKInitialize()
}
initializeProfile()
checkAuthentication()
return notifyLaunchObservers(application: application, launchOptions: launchOptions)
}
Obviously, in the initialization logic of version 17.0.0, there is an additional asynchronous call, resulting in a scenario where the asynchronous logic is not completed after the initialization logic is completed. At this point, it becomes uncertain when the App can obtain the AccessToken. It seems that this asynchronous logic is to obtain a configuration called DomainConfiguration. This configuration may come from UserDefaults or may require a network request.
I also found a solution based on the source code, which is to wait for the FBSDKAccessTokenDidChangeNotification notification after startup, and then try to obtain the AccessToken. On the one hand, this will have an impact on the original business logic process, which is not reflected in the update document description; on the other hand, in the test scenario, I found that on some devices this time may exceed 10 seconds, which is unacceptable.
Code samples & details
No response