首次下载后经动态链接更新App时openURL方法未触发的问题
我之前也碰到过类似的场景,结合你的代码和问题描述,咱们来拆解下可能的原因和对应的修复方案:
首先明确你的核心问题:
当直接覆盖安装更新App版本时,
openURL:方法可以正常调用;但如果先点击过Firebase动态链接打开App,之后再覆盖更新版本,openURL:就完全不再触发了。
你的openURL:处理代码如下:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options { // Sends the URL to the current authorization flow (if any) which will // process it if it relates to an authorization response. if ([_currentAuthorizationFlow resumeAuthorizationFlowWithURL:url]) { _currentAuthorizationFlow = nil; return YES; } FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; NSString *userID = [[NSUserDefaults standardUserDefaults] stringForKey:@"xx"]; NSString *firstTimeAppOpened = [[NSUserDefaults standardUserDefaults] stringForKey:@"xxx"]; if (dynamicLink != nil) { if ([dynamicLink.url.absoluteString length] != 0) { NSLog(@"App opened with link: %@", dynamicLink); NSString *snippet = [NSString stringWithFormat:@"URLScheme: Received dynamic firebase link: %@", dynamicLink.url.absoluteString]; NSString *category = @"DYNAMIC_LINK"; NSString *pathFromURL = [dynamicLink.url.absoluteString lastPathComponent]; [SiteConnector sendAuditWithSnippet:snippet inCategory:category]; NSString *firstTimeAppOpened = [[NSUserDefaults standardUserDefaults] stringForKey:@"FirstTimeAppOpened"]; if ([dynamicLink.url.absoluteString rangeOfString:@"murat"].location == NSNotFound) { [self dynamicLinkBehaviour:pathFromURL second:dynamicLink.url absolutePath:nil]; } else { if (firstTimeAppOpened == nil) { [self onboardingDynamicLink:dynamicLink.url.absoluteString]; } } } else { if (userID == nil && firstTimeAppOpened == nil) { [self openWelcomeScreen]; } } } NSString *valueToSave = @"yes"; [[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:@"FirstTimeLoggedIn"]; [[NSUserDefaults standardUserDefaults] synchronize]; return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; }
可能的原因分析
返回值逻辑错误,导致系统误判URL未被处理
你的代码不管前面是否处理了动态链接或授权流程,最后都返回Facebook SDK代理的处理结果。举个例子:如果你的代码已经处理了动态链接,但Facebook SDK返回NO,系统会认为这个URL没被处理,后续可能会停止触发openURL:;或者Facebook处理了不属于它的URL,干扰了你的逻辑流程。这是最可能的直接原因。Firebase动态链接缓存/状态残留
Firebase动态链接SDK会在本地存储已处理的链接状态,覆盖更新App时这些缓存不会被清空。更新后的App启动时,Firebase可能误判链接已处理,或者内部状态异常,间接影响openURL:的触发。NSUserDefaults标记残留
你用NSUserDefaults存储了FirstTimeAppOpened、FirstTimeLoggedIn等标记,这些数据在覆盖更新后会被保留。旧的标记可能触发异常分支逻辑,导致openURL:的处理流程出错。
修复方案
1. 修正openURL:的返回值逻辑
调整代码,确保当你的逻辑处理完URL后直接返回YES,只有未处理的URL才交给Facebook SDK:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options { // 处理授权流程 if ([_currentAuthorizationFlow resumeAuthorizationFlowWithURL:url]) { _currentAuthorizationFlow = nil; return YES; } // 处理Firebase动态链接 FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; NSString *userID = [[NSUserDefaults standardUserDefaults] stringForKey:@"xx"]; NSString *firstTimeAppOpened = [[NSUserDefaults standardUserDefaults] stringForKey:@"xxx"]; if (dynamicLink != nil) { if ([dynamicLink.url.absoluteString length] != 0) { NSLog(@"App opened with link: %@", dynamicLink); NSString *snippet = [NSString stringWithFormat:@"URLScheme: Received dynamic firebase link: %@", dynamicLink.url.absoluteString]; NSString *category = @"DYNAMIC_LINK"; NSString *pathFromURL = [dynamicLink.url.absoluteString lastPathComponent]; [SiteConnector sendAuditWithSnippet:snippet inCategory:category]; NSString *firstTimeAppOpened = [[NSUserDefaults standardUserDefaults] stringForKey:@"FirstTimeAppOpened"]; if ([dynamicLink.url.absoluteString rangeOfString:@"murat"].location == NSNotFound) { [self dynamicLinkBehaviour:pathFromURL second:dynamicLink.url absolutePath:nil]; } else { if (firstTimeAppOpened == nil) { [self onboardingDynamicLink:dynamicLink.url.absoluteString]; } } // 动态链接已处理,直接返回YES return YES; } else { if (userID == nil && firstTimeAppOpened == nil) { [self openWelcomeScreen]; } // 处理了欢迎页逻辑,返回YES return YES; } } // 设置FirstTimeLoggedIn标记 NSString *valueToSave = @"yes"; [[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:@"FirstTimeLoggedIn"]; [[NSUserDefaults standardUserDefaults] synchronize]; // 未处理的URL交给Facebook SDK return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; }
2. 清除Firebase动态链接缓存
在App启动时添加缓存清除逻辑,确保覆盖更新后缓存重置:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 初始化Firebase [FIRApp configure]; // 清除动态链接缓存 [[FIRDynamicLinks dynamicLinks] clearCacheWithCompletion:^(BOOL success) { NSLog(@"Firebase动态链接缓存已清除: %d", success); }]; // 其他初始化逻辑... return YES; }
3. 版本更新时重置NSUserDefaults标记(可选)
如果怀疑旧标记导致逻辑异常,可以在版本更新时重置相关键:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 获取当前版本和上次启动的版本 NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; NSString *lastVersion = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastAppVersion"]; // 首次启动新版本时重置标记 if (![currentVersion isEqualToString:lastVersion]) { [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"FirstTimeAppOpened"]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"FirstTimeLoggedIn"]; [[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:@"LastAppVersion"]; [[NSUserDefaults standardUserDefaults] synchronize]; } // 其他初始化逻辑... return YES; }
验证步骤
- 先通过Firebase动态链接打开App,确认逻辑正常。
- 覆盖安装更新App版本。
- 尝试通过自定义URL Scheme或其他App跳转触发
openURL:,检查是否正常调用。 - 如果问题仍存在,在
openURL:方法中添加更多日志,确认系统是否调用了该方法,以及各个分支的执行情况,进一步定位问题。
内容的提问来源于stack exchange,提问作者IOSporgrammerIOS

