Universal Link Fix Bug

Tip:发现在真机运行中有触发handoff功能的案例,只需要在代理方法中适当返回NO即可。

关于iOS Universal Link 的资料不胜枚举,关于基础配置这里就不再详述。这里主要分享一下,解决其中一个坑位的过程...

之前在配置好通用连接后,觉得完事大吉。然而过了一段时间,产品同事来找茬咯~~~ 
话说,没想到通用链接也有失效这样一回事。万恶的苹果爸爸~~~

基于这个问题的描述如下:
iOS里面有个情况,打开APP的后在右上角形如:
xxx.com(面包屑导航)跳转到safari后,会导致Universal  Link 跳转失效。

在认识这个问题的时候,首先需要考虑的是系统版本因素。发现在iOS11上通过通用链接启动APP后,右上角并没有发现面包屑导航。而在iOS10和iOS9 上会出现此问题,所以问题明朗了一点。

iOS11  下系统机制有所更改,所以本篇命题不会成立。
iOS10  以下,系统机制还不太成熟,这也是本篇命题存在的意义。

能够让产品大大乐此不疲的一定是,某某某家的APP怎么就没问题呢。所以我们不服气的研究了一下某某某家的APP。这里以两个具有代表性的为例。

eg:在微信中,跳转APP...  
今日头条: 两颗星
    表现:呼起APP后,点击右上角面包屑导航。会发现界面是向右侧跳转到Safari,这一点很像是使用 openURL 实现的效果。
网易:    一颗星
    表现:呼起APP后,点击右上角面包屑导航。WTF!!! 不可点,这个解决方案就有点鸡贼了。

Universal Link:失效的表现,点击右上角面包屑导航会发现页面是向左侧pop到Safari。
向左走还是向右走,简直是人生难题。

对比以上的结论:
问题根源,面包屑导航打开的是配置好的通用链接。这会让系统误以为,我们以后都会使用Safari打开通用链接从而导致失效。所以解决问题的思路一定是要在,面包屑导航上做文章了。

能想到的方案如下:
获取采用从状态栏获取网络状态的类似方法,来获取面包屑导航的相关状态。从而问题的解决可以分化为两个方案。

1.在状态栏上,贴一层UIView 覆盖住面包屑导航。这样的好处是,iOS9--iOS11都可以获得一致的体验。难点是要在KeyWindow的最上层添加,否则容易破相。
2.获取面包屑导航的触发事件,使用运行时替换事件。主要目的是,为我们手动调用openURL 方法提供便利,并可以修改跳转链接为普通链接。

我这里采用了第二套方案,详细过程如下:
抓取面包屑导航:

UIApplication *application = [UIApplication sharedApplication];
NSArray* arrChilden;
arrChilden = [[[application valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];

//查看subView 这个是没有面包屑导航时的情况 
_subviewCache   __NSArrayM *    @"4 elements"   0x000060000065f6e0
[0] UIStatusBarServiceItemView *    0x7fa4eac8d310  0x00007fa4eac8d310
[1] UIStatusBarDataNetworkItemView *    0x7fa4ead01ec0  0x00007fa4ead01ec0
[2] UIStatusBarBatteryItemView *    0x7fa4ead1b070  0x00007fa4ead1b070
[3] UIStatusBarTimeItemView *   0x7fa4eae76ad0  0x00007fa4eae76ad0

//查看subView 这个是有面包屑导航时的情况
_subviewCache   __NSArrayM *    @"7 elements"   0x1562a850
[0] UIStatusBarBreadcrumbItemView * 0x16df8ff0
[1] UIStatusBarServiceItemView *    0x16875600
[2] UIStatusBarDataNetworkItemView *    0x16b73cd0
[3] UIStatusBarOpenInSafariItemView *   0x15556580
[4] UIStatusBarBatteryItemView *    0x16b594f0
[5] UIStatusBarBatteryPercentItemView * 0x169e0af0
[6] UIStatusBarTimeItemView *   0x16997bb0

其中 UIStatusBarBreadcrumbItemView 就是面包屑左导航
    UIStatusBarOpenInSafariItemView 就是面包屑右导航
接下来深挖 UIStatusBarOpenInSafariItemView,一下就不详细说了。其中有一个事件是我们所关心的。
SEL: userDidActivateButton:
至此,入手点有了着落。

Final Result:
AppDelegate中修复方法如下:

///注意 - (void)applicationDidBecomeActive:(UIApplication*)application 方法中调用)
- (void)fixUniversalLink{
    
    UIApplication *application = [UIApplication sharedApplication];
    NSArray* arrChilden;
    //是否是iPhoneX
    if ([[application valueForKeyPath:@"statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
        arrChilden = [[[[application valueForKeyPath:@"statusBar"] valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
    } else {
        arrChilden = [[[application valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
    }

    for (id child in arrChilden) {
        
        if ([child isKindOfClass:NSClassFromString(@"UIStatusBarOpenInSafariItemView")]) {
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                Class cls =  [child class];
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wundeclared-selector"
                //原方法
                Method  originalM = class_getInstanceMethod(cls, @selector(userDidActivateButton:));
#pragma clang diagnostic pop
                //替换方法
                Method exchangeM = class_getInstanceMethod([self class], @selector(myDidActivateButton:));
                method_exchangeImplementations(originalM, exchangeM);
            });
        }
    }
}
#pragma mark - 通用链接修复
- (void)myDidActivateButton:(UIButton*)btn{
    NSLog(@"测试....");
    [[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,042评论 25 707
  • 2008年 7月10日 星期四 晴 地上一片狼藉,有盘子的碎片、玻璃杯的碎片,还有各种各样其它碎片。 翁小姚又抓起...
    音乐如水阅读 227评论 0 1
  • 今天又是周一,我看完了我的小说,并把它归还了还回答了一个问题,我觉得自己没有答好这个问题,下次我一定好好回答...
    原味石阅读 268评论 0 0
  • 下定义是一件很难的事情,所有人都有自己的标准,像是对于我,期待的定义是什么呢?大概就是出胡同的口,路两边飞奔的树,...
    繁意阅读 151评论 0 0
  • 当我在办公桌前翻看着一年工作报告的时候,听见几句争吵声音越来越大: 简,这个稿子难道不是你写的?给我的职务...
    龙女卷风阅读 759评论 2 1