firebase 是有谷歌提供一个第三方SDK,实际firebase 包含很多功能,这次主要是讲其中动态链接的功能使用及其注意事项.
年前最后第二版本对接Firebase 的动态链接功能做推广活动,整个开发过程跟测试流程完全没有异样.由于开发过程无法模拟 由分享连接 -> App Store -> 下载完成 -> 应用启动的完整流程,导致了一个致命的错误就是iOS9.0以上系统无法接收到动态链接的回调.每一次事故的发送都是职业生涯沉重的打击.
经过事故的发生,我开始重新查看Firebase动态链接完整的对接文档,并且从新检查所有的对接代码.最终发现问题,以下给大家讲述一下,问题的所在和我个人理解的Firebase动态链接的原理及其注意事项.
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options {
return [self application:app
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
if (dynamicLink) {
if (dynamicLink.url) {
// Handle the deep link. For example, show the deep-linked content,
// apply a promotional offer to the user's account or show customized onboarding view.
// ...
} else {
// Dynamic link has empty deep link. This situation will happens if
// Firebase Dynamic Links iOS SDK tried to retrieve pending dynamic link,
// but pending link is not available for this device/App combination.
// At this point you may display default onboarding view.
}
return YES;
}
return NO;
}
以上代码是Firebase 文档中启动回调的原代码.如果你是对接在AppDelegate的主文件中理论上是不会有问题.而我出现问题是由于我的项目是集成的第三方框架比较多,我采用了Category的管理方式来管理第三方的启动及回调,导致其中
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options {
return [self application:app
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
无法调用,原因就是Category文件中调用原生的代理方法是无法触发AppDelegate对应方法的调起的.
错误代码
//iOS 9.0 以上版本 (不包含9.0)
- (BOOL)hym_firebaseApplication:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options {
if (@available(iOS 9.0, *)) {
return [self application:app openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:[UIApplicationOpenURLOptionsAnnotationKey]];
} else {
// Fallback on earlier versions
}
return YES;
}
正确代码
//iOS 9.0 以上版本 (不包含9.0)
- (BOOL)hym_firebaseApplication:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options {
if (@available(iOS 9.0, *)) {
return [self hym_firebaseApplication:app openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
} else {
// Fallback on earlier versions
}
return YES;
}
//iOS 9.0 以下版本 (包含9.0)
- (BOOL)hym_firebaseApplication:(UIApplication *)application
continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *_Nullable))restorationHandler{
if (@available(iOS 9.0, *)) {
BOOL handled = [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL
completion:^(FIRDynamicLink * _Nullable dynamicLink,
NSError * _Nullable error) {
[self hym_handleTheDeepLink:dynamicLink];
}];
return handled;
} else {
// Fallback on earlier versions
}
return YES;
}
// iOS 9.0 以下 (包含9.0)
- (BOOL)hym_firebaseApplication:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation{
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
if (dynamicLink) {
[self hym_handleTheDeepLink:dynamicLink];
if (dynamicLink.url) {
// Handle the deep link. For example, show the deep-linked content,
// apply a promotional offer to the user's account or show customized onboarding view.
// ...
} else {
// Dynamic link has empty deep link. This situation will happens if
// Firebase Dynamic Links iOS SDK tried to retrieve pending dynamic link,
// but pending link is not available for this device/App combination.
// At this point you may display default onboarding view.
}
return YES;
}
return NO;
}
Firebase 中的文档比较绕 主要注意事项的 //iOS 9.0 以上版本 (包含9.0) 的方法实际是调用了 //iOS 9.0以下的系统代理,再从系统代理里统一调用了回调响应的方法.
主要的事故就是这样引起的,我后面会整理出appDelegate 的Category管理方式的正确文件和以模块形式对接的正确文件. 开始上班了,我会抽空补充的.