【AICon】AI 大模型超全落地场景&最佳实践 了解详情
写点什么

WWDC 案例解读:大众点评相机直接扫描支付是怎么实现的

  • 2020-02-25
  • 本文字数:2859 字

    阅读完需:约 9 分钟

WWDC案例解读:大众点评相机直接扫描支付是怎么实现的

8 月 16 - 19 日,与零一万物李开复、蔚来李斌、面壁智能李大海,及工商银行、交通银行、华夏银行等 100+ 行业专家相聚 FCon x AICon

背景

去年 12 月 4 日,Apple CEO Tim Cook 和王兴共同出现在上海的一家老字号生煎店“大壶春”,现场用大众点评 App 体验了 iOS 11 新功能,包括用地图找店订座、用相机扫码点餐及 Apple Pay 付款等一条龙便利服务。



在今年的 WWDC 上,大众点评 App 更进一步:Apple 技术人员在“Create Great Customer Experience Using Wallet and Apple Pay”演讲中专门重点演示了如何用 iPhone 相机直接扫码点餐下单,并使用 Apple Pay 支付闭环的全流程。这背后的技术是怎么实现的呢?



实现方案

相机扫码

从 iOS 7 开始,系统就通过 AVFoundation 赋予了 App“相机扫码”的能力。不过当时只能通过代码的形式,构建 AVCaptureDevice,并设置输出类型为 AVMetadataObjectTypeQRCode,来实现在 App 内部的二维码识别。


然而,整个 iOS 系统在此后的几年一直没有系统级的扫码入口,直到 iOS 11 发布,Apple 终于在系统“相机”App 内提供了二维码扫描识别并跳转到对应 URL 的能力。

Universal-Link

Universal-Link 是 iOS 9 之后推出的,可以实现 URL 和 App 之间的无缝连接,在此之前是自定义的 URL Scheme。和自定义 URL Scheme 对比,Universal-Link 有如下优势:


  • 唯一性:Universal-Link 使用标准的 HTTP 协议 URL,拥有唯一性。

  • 安全性:App 可以控制处理哪些 URL。

  • 简单灵活:URL 对于 H5 和 App 是通用的,如果没有安装 App,就会跳转到 Safari 打开对应 H5。

  • 私密性:在跳转之前并不需要知道用户是否安装目标 App。


结合“相机扫码”和 Universal-Link,我们就可以做到从系统“相机扫码”直接唤起 App 了。


具体方案:将一个 Universal-Link 链接对应的二维码作为物料投放,用户直接使用系统“相机”扫描此二维码,如果装有大众点评 App,会出现“是否用大众点评打开”的提示框,点击即进入 App。如下所示:

面临挑战

上述方案是我们基于 iOS 系统现有能力做出的最佳实践,然而现实世界总有很多“意外惊喜”等待着我们:


  • 物料已经大规模投放出去了,没办法修改怎么办?

  • 整个流程发起是通过“相机扫码”进行,业务如何知道入口在哪?

  • Universal-Link 在微信里不能跳怎么办?


我们知道 Universal-Link 的生效主要依赖两部分:


  • AppTarget 的 Capabilities 中配置的 Associated Domains,用以控制 Universal-Link 下的 Domain。

  • 部署在 WebServer 上的 Apple-App-Site-Association,用以控制对应 Domain 下的 Path。


也就是说,在大型工程化项目中使用 Universal-Link,URL 必须遵循一定的规则,才能做到所有业务共同使用互不干扰,点评 App 在引入 Universal-Link 时也制定了使用规范。


然而由于对应的物料已经大量投放,物料中二维码的 URL 在投放时并没有考虑 Universal-Link 的适配,无法遵循上面的“最佳实践”,而重新更换物料的成本又非常高,时间上也不允许。


所以我们只好“另辟蹊径”实现这个功能了。由于 Universal-Link 本身对 URL 没有任何限制,理论上我们可以通过部署配置把任意一条 URL 变成 Universal-Link。


这样一来,投放出去的物料二维码就无法遵循我们已经定义好的 Universal-Link 使用规范,但这也是我们必须接受的“妥协”,在局部牺牲一些规范性换来重要功能的实现。


事情到此还没有完全结束,这种实现方式会带来另一个问题:这条物料二维码对应 URL 在 WebView 内打开的行为会发生改变。


按照 Apple 官方的解释:Universal-Link 由用户“主动”触发,例如在邮件,记事本或是其它 App 中通过 openURL 唤起 App 打开这个 URL;而如果用户处在 Safari 浏览器内直接输入或是点击链接打开这个 URL,系统会在同源(Domain)页面下直接打开,非同源页面则会直接唤起 App。


换句话说,如果在 App 内的 WebView 打开非同源某个页面,然后又在这个页面上点击了 Universal-Link 链接,这会变成一次对系统 openURL 方法的直接调用,如果不做处理有可能会跳出 App,即使处理过大部分 App 也会在此时打开一个新的页面。


这显然不是我们希望得到的结果,但我们又必须将这些 URL 配置成 Universal-Link。最终在非常困难的情况下,我们和业务同学达成共识:对于这批特殊的投放物料二维码,业务系统保证 URL 使用场景的唯一性,不会在除二维码之外的其它场景使用这批特征 URL,绕过 App 内 WebView 打开异常的 Case。


这样我们完成了“对于既有投放二维码的 iOS 相机扫码唤起 App”实现。


在这个特殊的场景中,整个流程的发起始自于 App 外,业务非常需要了解当前处于“相机扫码唤起 App”的场景。


遗憾的是 iOS 系统除了 userActivity 的相关回调之外,并没有一个明确的 App 启动路径标识,我们只能知道 App 是通过 Universal-Link 的方式被唤醒了。


由于启动节点在 App 控制权范围以外,任何 Native 埋点的方式都不能在此时生效,我们唯一可以拿到的是那条被唤醒的 URL,缺乏足够的上下文可能是所有启动相关业务最难以处理的部分。


由于问题 1 的解决,我们知道这条 URL 在 App Scope 内是有场景唯一性的,所以我们可以据此来比较 Tricky 的判断当前的场景。 拿到当前启动场景标识之后,就要考虑如何告知业务。


最简单的方式就是通过修改 URL,告知业务具体特征,但作为一个通用平台型 App 直接修改业务方的原始 URL 显然不是合适的行为,而且可能造成不必要的麻烦,Header,Cookie,JSBridge 等都可以考虑作为与 H5 的通信方式。


到此为止,我们完成了“从系统相机扫码唤起 App 进入相应页面”。然而,在国内微信才是各种二维码最大的扫描入口,在今年的 1 月份,微信彻底关闭了 Universal-Link 的跳转行为,任何 Universal-Link 在微信里都不能往外跳了。


“捡了芝麻,丢了西瓜”,这个 ROI 对我们来说过于沉重不能接受。考虑在 Universal-Link 诞生以前,我们都是通过 openSchema 的方式唤起 App,“综合链接”是当时 H5 在微信唤起 App 的主要方式,我们可以在 Universal-Link 页面内再套一层综合链接,并在此区分用户场景,完成从微信唤起 App 的“初心”。

结语

大众点评 App 参与了过去多届 WWDC 的现场演示,从 iOS 6 的 PassKit 开始,经历 Flat Design,MessageKit,MapKit,SiriKit,ApplePay 到 WWDC2018 的 ApplePay 闪付。我们积累了丰富的与 Apple 沟通合作经验,既有驻场 Apple Campus 的封闭式开发,也有在 IAPM 的 Face2Face,更多时候是在安化路 492 号的远程合作。



通常 BD 同学都会基于点评 App 现有功能和 Apple 提供的新能力,找到需求点。这种基于外部系统升级适配的二次开发,总会遇到各种问题。有些问题会比较容易可以直接解决,有些问题会挑战我们设定的边界需要我们做出妥协,还有些问题无法正面突破只能规避。


二进制世界总是由输入,计算,输出来定义。合理规划整体架构,明确划分输入输出边界,尽量减少外部依赖,可以让我们在缺少上下文,不能端到端掌控整体流程的情况下依旧游刃有余。

团队介绍

点评平台移动研发中心总体负责大众点评 APP。依托平台能力,我们不断输出高质量服务:Shark,Picasso,Logan,MCI,移动之家,Appkit 等,在这里和“最好的合作伙伴“以“最严格的标准”做“最复杂的业务”,经受考验,砥砺前行,共同打造业界领先的移动开发团队。


2020-02-25 20:322993

评论

发布
暂无评论
发现更多内容

[Day1]-[广度搜索(BFS)] 二叉树最小高度

方勇(gopher)

LeetCode BFS 数据结构算法

失眠的岁月,我们都交了哪些科技智商税?

脑极体

公平的获得财富的机会,区块链通证经济是未来的必然趋势

CECBC

JS中的函数参数默认值是如何写的?

Changing Lin

3月月更

另一个 effective go 中文版

黑客不够黑

【模块六】拆分电商系统为微服务

yhjhero

#架构训练营

云原生-模块十二

hunk

毕业总结

黄秀明

「架构实战营」

架构训练营 模块六

Geek_16d2b8

架构训练营 模块六

【架构实战营】毕业总结

wgl

架构实战营

模块六作业

Leo

架构实战营

电商系统拆分为微服务

凌波微步

「架构实战营」

DDD实战(6):战略设计之技术决策

深清秋

DDD 软件架构 生鲜电商系统 3月月更

重学架构之拆分电商系统为微服务

陈华英

架构实战营

架构训练营模块六

刘帅

Web 3.0是什么?区块链热潮下2022年必懂的科技概念

CECBC

一文概述:云端常见的攻防及实践

穿过生命散发芬芳

3月月更

电商系统微服务拆分实践

IT屠狗辈

微服务 架构实战营 电商系统架构 架构拆分

「架构实战营」毕业总结

DaiChen

「架构实战营」

模块六作业

blazar

「架构实战营」

电商系统微服务拆分

邹玉麒

「架构实战营」

「架构实战营」模块六 电商微服务框架设计

hxb

「架构实战营」

电商系统微服务拆分

tom

《直击本质》——读后上

圣迪

系统性思考 直击本质 金字塔原理 本质

模块六作业

Geek_ec866b

架构训练营

模块九作业-设计电商秒杀系统

CH

架构实战营

一文带你了解 Python 中的装饰器

踏雪痕

Python 装饰器 3月程序媛福利 3月月更

底什么是伪静态?为什么要做伪静态?

源字节1号

网站建设 SEO伪静态

【架构实战营】毕业设计项目

wgl

架构实战营

架构训练营第一期作业

Geek_bc9c8d

「架构实战营」模块九《十万级到亿万级 IM 架构实战》作业

DaiChen

作业 「架构实战营」 模块九

WWDC案例解读:大众点评相机直接扫描支付是怎么实现的_文化 & 方法_美团技术团队_InfoQ精选文章