You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次下载后经动态链接更新App时openURL方法未触发的问题

Firebase动态链接触发后覆盖更新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]];
}

可能的原因分析

  1. 返回值逻辑错误,导致系统误判URL未被处理
    你的代码不管前面是否处理了动态链接或授权流程,最后都返回Facebook SDK代理的处理结果。举个例子:如果你的代码已经处理了动态链接,但Facebook SDK返回NO,系统会认为这个URL没被处理,后续可能会停止触发openURL:;或者Facebook处理了不属于它的URL,干扰了你的逻辑流程。这是最可能的直接原因。

  2. Firebase动态链接缓存/状态残留
    Firebase动态链接SDK会在本地存储已处理的链接状态,覆盖更新App时这些缓存不会被清空。更新后的App启动时,Firebase可能误判链接已处理,或者内部状态异常,间接影响openURL:的触发。

  3. 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;
}

验证步骤

  1. 先通过Firebase动态链接打开App,确认逻辑正常。
  2. 覆盖安装更新App版本。
  3. 尝试通过自定义URL Scheme或其他App跳转触发openURL:,检查是否正常调用。
  4. 如果问题仍存在,在openURL:方法中添加更多日志,确认系统是否调用了该方法,以及各个分支的执行情况,进一步定位问题。

内容的提问来源于stack exchange,提问作者IOSporgrammerIOS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:58:24