阿里巴巴淘系技术

阿里巴巴淘系技术 查看完整档案

杭州编辑  |  填写毕业院校淘宝  |  技术专家 编辑填写个人主网站
编辑

阿里巴巴集团淘系技术部官方账号。淘系技术旗下包含淘宝技术、天猫技术、闲鱼技术、躺平等团队和业务。我们服务9亿用户,赋能各行业1000万商家,并成功主导了11次阿里巴巴经济体双十一技术大考,打造了全球领先的线上新零售技术平台。
我们的愿景是致力于成为全球最懂商业的技术创新团队,让科技引领面向未来的商业创新和进步。
公众号关注:淘系技术

个人动态

阿里巴巴淘系技术 发布了文章 · 9月14日

聊聊鸿蒙系统与开发者生态前景

来自于阿里淘系的安卓开发同学之羲,站在开发者角度,给大家聊聊华为鸿蒙系统2.0版本后对鸿蒙生态、消费者端厂商、芯片厂商以及二三方应用开发&应用市场带来的影响。

本篇回答仅为开发者个人角度观点,欢迎大家一起讨论交流。

从1.0到2.0?

近日,中美关系的不确定性再次加大,国家层面提倡科技创新,强调把原始创新能力提升摆在更加突出的位置,努力实现更多”从0到1”的突破。在这样科技强国的大背景下,华为作为中国科技的领跑者之一,华为开发者大会9月10日在松山湖召开,再次提到举世曙目的鸿蒙操作系统,并发布了鸿蒙2.0以及最近的发展路线图。

从去年鸿蒙系统发布之始,鸿蒙系统就备受争议,其相关话题在知乎,贴吧等社区也火了一把。而最近发布的2.0,再次激发了行业内的关注。实际上,在鸿蒙开源官网,当前开源的版本仍然是标记为OpenHarmony 1.0 baseline的TAG。2.0的源码是否在路上,我们不得而知。

image.png

不可否认,去年的开源,那是千呼万唤始出来,犹抱琵琶半遮面,今年的相关文档与源码比去年完善了许多,似乎是一个可玩的版本了,可以烧在开发版上运行。 但相比Android/iOS等成熟的开发者工具链,略显简陋。确实是刚启步,我们也不能要求华为一出来就是成熟的产品。今天,笔者将从开发者生态的角度来聊聊鸿蒙系统。

鸿蒙生态的层次化

作为开发者,最近切的希望是了解未来能支持哪些设备,从鸿蒙2.0的路线图看,现在主要还是智慧屏,车机,手表等专有领域上,并没有类似手机这样的应用市场,自由上架的完整意义上的开发者生态。而据说今年年底会有可运行在手机上的beta版本(一定不要忘了beta这个词),我们再试目以待。

其实蛮喜欢华为的一句话,"没有人能够熄灭满天星光,每一位开发者,都是华为要汇聚的星星之火。"愿望很美好。华为开源的初衷,应该是为了让更多的友商,包括设备商,oem商,芯片厂商,iot商,应用开发商等一起进来合作,所以,明显华为对生态的设计上,是进行了分层的,在不同的成熟期,主要推动相应的生态合作伙伴。

消费者端厂商

分析一下,不难得出一个结论,开源的版本和商用的版本,应该是两个不同的分支,商用的分支,应该会完善很多,如果按华为上线的智慧屏是采用鸿蒙系统来看,它们之间,猜测还是有个代差,而且未来会一直保持这个代差。当然我们也不期望华为一下子把投入多年的软件资产开放出来。 因此,在当前的状态下,并不能奢望其他的消费者端的厂商开发出基于鸿蒙系统的电子产品,他们一定是等着这个系统成熟或者某个外因(众所周知的如华为中兴)而不得不用。这一层的厂商,应该是在观望中。

芯片厂商

而对于芯片厂商,如果华为鸿蒙系统有电子产品面世,必然会有一些与华为合作的厂商参与进来,目前来说,我更愿意相信,如果有,还是主要存在于华为内部。而方案集成厂商的合作,想必会更加遥远,需要基于鸿蒙的前景更加明确后,才会有厂商进来解决更大规模化的问题。

二三方应用开发&应用市场

华为当前主要推动生态参加与者,我相信更多是有合作的二方以及少量的三方应用开发商。主要以解决某些特定场景的应用为主。从目前华为提供的开发资料看,目前支持Java和JS,未来可能有更多的语言。

image.png

鸿蒙的应用,以.hap结尾,类似于android的.apk。从目前的资料看,hap的编写很类似android的开发,无论是ide或是api,都有一定的相似性。对android开发者的学习成本看起来不高。

image.png

而另一种方式,则是以小程序为代表的前端技术栈开发方式。

image.png

像阿里淘宝这样的三方开发者,要融入鸿蒙这样的生态,相信华为还有很长的一段路要走,目前还没有看到类似应用市场的发布渠道。笔者认为,目前鸿蒙上的应用开发方式,虽然类android,类小程序,好像即照顾了Android开发者,又照顾前端开发者,但终归不是兼容的。如果不能兼容android系统的runtime环境,与现有的android生态作衔接,鸿蒙的路将会非常艰难。

写在最后

尽管与国外多个优秀的操作系统相比,仍存在一定差距,不管怎样,鸿蒙作为能够运行在电子设备上可商业化的国产操作系统,的确是意义非凡。不必妄自菲薄,客观的看待它,了解它。期望鸿蒙操作系统能如同像它的名字一样,为中国科技的腾飞,开创一片天空,在科技世界的舞台上有它一席之地。

——————————————————————————————————————————

本账号主体为阿里巴巴淘系技术,淘系技术部隶属于阿里巴巴新零售技术事业群,旗下包含淘宝技术、天猫技术、农村淘宝技术、闲鱼、躺平等团队和业务,是一支是具有商业和技术双重基因的螺旋体。

欢迎收藏点赞关注我们!共同进步~ :)更多技术干货可关注【淘系技术】公众号

查看原文

赞 3 收藏 0 评论 0

阿里巴巴淘系技术 发布了文章 · 8月12日

面向5G的阿里自研标准化协议库XQUIC

XQUIC是阿里巴巴淘系架构团队自研的IETF QUIC标准化协议库实现,在手机淘宝上进行了广泛的应用,并在多个不同类型的业务场景下取得明显的效果提升,为手机淘宝APP的用户带来丝般顺滑的网络体验:

  • 在RPC请求场景,网络耗时降低15%
  • 在直播高峰期场景,卡顿率降低30%、秒开率提升2%
  • 在短视频场景,卡顿率降低20%

从以上提升效果可以看出,对QUIC的一个常见认知谬误:“QUIC只对弱网场景有优化提升”是不准确的。实际上QUIC对于整体网络体验有普遍提升,弱网场景由于基线较低、提升空间更显著。此外,在5G推广初期,基站部署不够密集的情况下,如何保证稳定有效带宽速率,是未来2-3年内手机视频应用将面临的重大挑战,而我们研发的MPQUIC将为这些挑战提供有效的解决方案。

本文将会重点介绍XQUIC的设计原理,面向业务场景的网络传输优化,以及面向5G的Multipath QUIC技术(多路径QUIC)。

QUIC

网络分层模型及QUIC进化史

图1. 网络七层/四层模型 和 QUIC分层设计

为了方便说明QUIC在网络通信协议栈中所处的位置及职能,我们简单回顾一下网络OSI模型(七层模型)和TCP/IP模型(四层模型)。从两套网络模型中可以看出,网络传输行为和策略主要由传输层来控制,而TCP作为过去30年最为流行和广泛使用的传输层协议,是由操作系统控制和实现的。

QUIC是由Google从2013年开始研究的基于UDP的可靠传输协议,它最早的原型是SPDY + QUIC-Crypto + Reliable UDP,后来经历了SPDY[1]转型为2015年5月IETF正式发布的HTTP/2.0[2],以及2016年TLS/1.3[3]的正式发布。QUIC在IETF的标准化工作组自2016年成立,考虑到HTTP/2.0和TLS/1.3的发布,它的核心协议族逐步进化为现在的HTTP/3.0 + TLS/1.3 + QUIC-Transport的组合。

QUIC带来的核心收益是什么

众所周知,QUIC具备多路复用/0-RTT握手/连接迁移等多种优点,然而在这些优势中,最关键的核心收益,当属QUIC将四/七层网络模型中控制传输行为的传输层,从内核态实现迁移到了用户态实现,由应用软件控制。这将带来2个巨大的优势:

(1) 迭代优化效率大大提升。以服务端角度而言,大型在线系统的内核升级成本往往是非常高的,考虑到稳定性等因素,升级周期从月到年为单位不等。以客户端角度而言,手机操作系统版本升级同样由厂商控制,升级周期同样难以把控。调整为用户态实现后,端到端的升级都非常方便,版本迭代周期以周为计(甚至更快)。

(2) 灵活适应不同业务场景的网络需求。在过去4G的飞速发展中,短视频、直播等新的业务场景随着基建提供的下行带宽增长开始出现,在流媒体传输对于稳定高带宽和低延迟的诉求下,TCP纷纷被各类标准/私有UDP解决方案逐步替代,难以争得一席之地。背后的原因是,实现在内核态的TCP,难以用一套拥塞控制算法/参数适应快速发展的各类业务场景。这一缺陷将在5G下变得更加显著。QUIC则可将拥塞控制算法/参数调控到连接的粒度,针对同一个APP内的不同业务场景(例如RPC/短视频/直播等)具备灵活适配/升级的能力。

在众多增强型UDP的选择中,QUIC相较于其他的方案最为通用,不仅具备对于HTTP系列的良好兼容性,同时其优秀的的分层设计,也使得它可以将传输层单独剥离作为TCP的替代方案,为其他应用层协议提供可靠/非可靠传输能力(是的,QUIC也有非可靠传输草案设计)。

XQUIC是什么、为什么选择自研 + 标准


XQUIC是阿里自研的IETF QUIC标准化实现,这个项目由淘系架构网关与基础网络团队发起和主导,当前有阿里云CDN、达摩院XG实验室与AIS网络研究团队等多个团队参与其中。

现今QUIC有多家开源实现,为什么选择标准协议 + 自研实现的道路?我们从14年开始关注Google在QUIC上的实践(手机淘宝在16年全面应用HTTP/2),从17年底开始跟进并尝试在电商场景落地GQUIC[4],在18年底在手淘图片、短视频等场景落地GQUIC并拿到了一定的网络体验收益。然而在使用开源方案的过程中或多或少碰到了一些问题,Google的实现是所有开源实现中最为成熟优秀的,然而由于Chromium复杂的运行环境和C++实现的缘故,GQUIC包大小在优化后仍然有2.4M左右,这使得我们在集成手淘时面临困难。在不影响互通性的前提下,我们进行了大量裁剪才勉强能够达到手淘集成的包大小要求,然而在版本升级的情况下难以持续迭代。其他的开源实现也有类似或其他的问题(例如依赖过多、无服务端实现、无稳定性保障等)。最终促使我们走上自研实现的道路。

为什么要选择IETF QUIC[5]标准化草案的协议版本?过去我们也尝试过自研私有协议,在端到端都由内部控制的场景下,私有协议的确是很方便的,但私有协议方案很难走出去建立一个生态圈 / 或者与其他的应用生态圈结合(遵循相同的标准化协议实现互联互通);从阿里作为云厂商的角度,私有协议也很难与外部客户打通;同时由于IETF开放讨论的工作模式,协议在安全性、扩展性上会有更全面充分的考量。

因此我们选择IETF QUIC标准化草案版本来落地。截止目前,IETF工作组草案已经演化到draft-29版本(2020.6.10发布),XQUIC已经支持该版本,并能够与其他开源实现基于draft-29互通。

XQUIC整体架构和传输框架设计

XQUIC是IETF QUIC草案版本的一个C协议库实现,端到端的整体链路架构设计如下图所示。XQUIC内部包含了QUIC-Transport(传输层)、QUIC-TLS(加密层、与TLS/1.3对接)和HTTP/3.0(应用层)的实现。在外部依赖方面,TLS/1.3依赖了开源boringssl或openssl实现(两者XQUIC都做了支持、可用编译选项控制),除此之外无其他外部依赖。

图2. XQUIC端到端架构设计 和 内部分层模块

XQUIC整体包大小在900KB左右(包含boringssl的情况下),对于客户端集成是较为轻量的(支持Android/iOS)。服务端方面,由于阿里内部网关体系广泛使用Tengine(Nginx开源分支),我们开发了一个ngx_xquic_module用于适配Tengine服务端。协议的调度方面,由客户端网络库与调度服务AMDC配合完成,可以根据版本/地域/运营商/设备百分比进行协议调度。

XQUIC传输层内部流程设计如下图,可以看到XQUIC内部的读写事件主流程。考虑到跨平台兼容性,UDP收发接口由外部实现并注册回调接口。XQUIC内部维护了每条连接的状态机、Stream状态机,在Stream级别实现可靠传输(这也是根本上解决TCP头部阻塞的关键),并通过读事件通知的方式将数据投递给应用层。传输层Stream与应用层HTTP/3的Request Stream有一一映射关系,通过这样的方式解决HTTP/2 over TCP的头部阻塞问题。

图3. XQUIC读写事件主流程设计

考虑到IETF QUIC传输层的设计可以独立剥离,并作为TCP的替代方案对接其他应用层协议,XQUIC内部实现同样基于这样的分层方式,并对外提供两套原生接口:HTTP/3请求应答接口 和 传输层独立接口(类似TCP),使得例如RTMP、上传协议等可以较为轻松地接入。

图4. XQUIC内部的连接状态机设计(参考TCP)

XQUIC拥塞控制算法模块

我们将XQUIC传输层的内部设计放大,其中拥塞控制算法模块,是决定传输行为和效率的核心模块之一。

图5. XQUIC拥塞控制算法模块设计

为了能够方便地实现多套拥塞控制算法,我们将拥塞控制算法流程抽象成7个回调接口,其中最核心的两个接口onAck和onLost用于让算法实现收到报文ack和检测到丢包时的处理逻辑。XQUIC内部实现了多套拥塞控制算法,包括最常见的Cubic、New Reno,以及音视频场景下比较流行的BBR v1和v2,每种算法都只需要实现这7个回调接口即可实现完整算法逻辑。

为了方便用数据驱动网络体验优化,我们将连接的丢包率、RTT、带宽等信息通过埋点数据采样和分析的方式,结合每个版本的算法调整进行效果分析。同时在实验环境下模拟真实用户的网络环境分布,更好地预先评估算法调整对于网络体验的改进效果。

面向业务场景的传输优化

XQUIC在RPC请求场景降低网络耗时15%,在短视频场景下降低20%卡顿率,在直播场景高峰期降低30%卡顿率、提升2%秒开率(相对于TCP)。以下基于当下非常火热的直播场景,介绍XQUIC如何面向业务场景优化网络体验。

优化背景

部分用户网络环境比较差,存在直播拉流打开慢、卡顿问题。

图6. 某节点丢包率和RTT统计分布

这是CDN某节点上统计的丢包率和RTT分布数据,可以看到,有5%的连接丢包率超过20%,0.5%的连接RTT超过500ms,如何优化网络较差用户的流媒体观看体验成为关键。

秒开卡顿模型

图7. 直播拉流模型

直播拉流可以理解为一个注水模型,上面是CDN服务器,中间是播放器缓冲区,可以理解成一个管道,下面是用户的体感,用户点击播放时,CDN不断向管道里注水,当水量达到播放器初始buffer时,首帧画面出现,然后播放器以一定速率排水,当水被排完时,播放器画面出现停顿,当重新蓄满支持播放的水后,继续播放。

我们假设Initial Buffer(首帧)为100K(实际调整以真实情况为准),起播时间 T1 < 1s 记为秒开,停顿时间 T2 > 100ms 记为卡顿。

  • 优化目标
  • 提升秒开:1s内下载完100K
  • 降低卡顿:保持下载速率稳定,从而保持管道内始终有水
  • 核心思路
  • 提升秒开核心--快
  • 高丢包率用户:加快重传
  • 高延迟用户:减少往返次数
  • 降低卡顿核心--稳
  • 优化拥塞算法机制,稳定高效地利用带宽

拥塞算法选型

常见的拥塞算法可分为三类:

  • 基于路径时延(如Vegas、Westwood)

将路径时延上升作为发生拥塞的信号,在单一的网络环境下(所有连接都使用基于路径时延的拥塞算法)是可行的,但是在复杂的网络环境下,带宽容易被其他算法抢占,带宽利用率最低。

  • 基于丢包(如Cubic、NewReno)

将丢包作为发生拥塞的信号,其背后的逻辑是路由器、交换机的缓存都是有限的,拥塞会导致缓存用尽,进而队列中的一些报文会被丢弃。

拥塞会导致丢包,但是丢包却不一定拥塞导致的。事实上,丢包可以分为两类,一类是拥塞丢包,另一类是噪声丢包,特别是在无线网络环境中,数据以无线电的方式进行传递,无线路由器信号干扰、蜂窝信号不稳定等都会导致信号失真,最终数据链路层CRC校验失败将报文丢弃。

基于丢包的拥塞算法容易被噪声丢包干扰,在高丢包率高延迟的环境中带宽利用率较低。

  • 基于带宽时延探测(如BBR)

既然无法区分拥塞丢包和噪声丢包,那么就不以丢包作为拥塞信号,而是通过探测最大带宽和最小路径时延来确定路径的容量。抗丢包能力强,带宽利用率高。

三种类型的拥塞算法没有谁好谁坏,都是顺应当时的网络环境的产物,随着路由器、交换机缓存越来越大,无线网络的比例越来越高,基于路径时延和基于丢包的的拥塞算法就显得不合时宜了。对于流媒体、文件上传等对带宽需求比较大的场景,BBR成为更优的选择。

秒开率优化

✎ 加快握手包重传

图8. TCP握手阶段出现丢包

如图,TCP在握手时,由于尚未收到对端的ACK,无法计算路径RTT,因此,RFC定义了初始重传超时,当超过这个超时时间还未收到对端ACK,就重发sync报文。

TCP秒开率上限:Linux内核中的初始重传超时为1s (RFC6298, June 2011),3%的丢包率意味着TCP秒开率理论上限为97%,调低初始重传时间可以有效提升秒开率。

同理,如果你有一个RPC接口超时时间为1s,那么在3%丢包率的环境下,接口成功率不会超过97%。

图9. TCP和QUIC握手阶段 - 伪重传模拟

另一方面,调低初始重传超时会引发伪重传,需要根据用户RTT分布进行取舍,比如初始重传超时调低到500ms,那么RTT大于500ms的用户在握手期间将会多发一个sync报文。

减少往返次数

慢启动阶段 N 个 RTT 内的吞吐量(不考虑丢包):

T = init_cwnd * (2^N-1) * MSS,  N = ⌊t / RTT ⌋

Linux内核初始拥塞窗口=10(RFC 6928,April 2013)

首帧100KB,需要4个RTT,如果RTT>250ms,意味着必然无法秒开。在我们举的这个例子中,如果调整为32,那么只需要2个RTT。

图10. 宽带速率报告

从2015到2019,固定带宽翻了4.8倍。从2016到2019,移动宽带翻了5.3倍。初始拥塞窗口从10调整为32在合理范围内。

卡顿率优化

✎ BBR RTT探测优化

图11. BBR v1示意图:ProbeRTT阶段

问题

  • BBR v1的ProbeRTT阶段会把inflight降到4*packet并保持至少200ms。会导致传输速率断崖式下跌,引起卡顿
  • 10s进入一次ProbeRTT,无法适应RTT频繁变化的场景

优化方案

  • 减少带宽突降:inflight 降到 4*packet  改为降到 0.75 * Estimated_BDP
  • 加快探测频率:ProbeRTT进入频率 10s 改为 2.5s

推导过程

  • 为什么是 0.75x?

Max Estimated_BDP = 1.25*realBDP

0.75 * Estimated_BDP = 0.75 * 1.25 * realBDP = 0.9375* realBDP

保证inflight < realBDP, 确保RTT准确性。

  • 为什么是 2.5s?

优化后BBR带宽利用率:(0.2s * 75% + 2.5s * 100%) / (0.2s+ 2.5s) = 98.1%

原生BBR带宽利用率:(0.2s * 0% + 10s * 100%) / (0.2s + 10s) = 98.0%

在整体带宽利用率不降低的情况下,调整到2.5s能达到更快感知网络变化的效果。

优化效果

保证带宽利用率不低于原生BBR的前提下,使得发送更平滑,更快探测到RTT的变化。

✎ BBR带宽探测优化**

图12. BBR v1示意图:StartUp 和 ProbeBW阶段

问题分析

StartUp阶段2.89和ProbeBW阶段1.25的增益系数导致拥塞丢包,引发卡顿和重传率升高(Cubic重传率3%, BBR重传率4%)重传导致带宽成本增加1%。

优化策略

图13. 带宽变化示意图

定义两个参数:

期望带宽:满足业务需要的最小带宽

最大期望带宽:能跑到的最大带宽

未达到期望带宽时采用较大的增益系数,较激进探测带宽。

达到期望带宽后采用较小的增益系数,较保守探测带宽。

优化效果

成本角度:重传率由4%降到3%,与Cubic一致,在不增加成本的前提下降低卡顿率。

另外,该策略可以推广到限速场景,如5G视频下载限速,避免浪费过多用户流量。

卡顿、秒开优化效果

在直播拉流场景下与TCP相比较,高峰期卡顿率降低30%+,秒开率提升2%。

写在优化最后的思考

最后,我们看看TCP初始重传超时和初始拥塞窗口的发展历程:

  • 初始重传时间
  • RFC1122 (October 1989) 为3s
  • RFC6298 (June 2011) 改为1s,理由为97.5%的连接RTT<1s
  • 初始拥塞窗口
  • RFC 3390 (October 2002) 为 min(4 * MSS, max(2 * MSS, 4380 bytes))(MSS=1460时为3)
  • RFC 6928 (April 2013) 改为 min (10 * MSS, max (2 * MSS, 14600))(MSS=1460时为10)—— 由google提出,理由为 90% of Google's search responses can fit in 10 segments (15KB).

首先IETF RFC是国际标准,需要考虑各个国家的网络情况,总会有一些网络较慢的地区。在TCP的RFC标准中,由于内核态实现不得不面临一刀切的参数选取方案,需要在考虑大盘分布的情况下兼顾长尾地区。

对比来看,QUIC作为用户态协议栈,其灵活性相比内核态实现的TCP有很大优势。未来我们甚至有机会为每个用户训练出所在网络环境最合适的一套最优算法和参数,也许可以称之为千人千面的网络体验优化:)

Multipath QUIC技术

Multipath QUIC(多路径QUIC)是当前XQUIC内部正在研究和尝试落地的一项新技术。

MPQUIC可以同时利用cellular和wifi双通道进行数据传输,不仅提升了数据的下载和上传速度,同时也加强了应用对抗弱网的能力,从而进一步提高用户的端到端体验。此外,由于5G比4G的无线信号频率更高,5G的信道衰落问题也会更严重。所以在5G部署初期,基站不够密集的情况下如何保证良好信号覆盖是未来2-3年内手机视频应用的重大挑战,而我们研发的MPQUIC将为这些挑战提供有效的解决方案。

Multipath QUIC 的前身是MPTCP[6]。MPTCP在IETF有相对成熟的一整套RFC标准,但同样由于其实现在内核态,导致落地成本高,规模化推广相对困难。业界也有对MPTCP的应用先例,例如苹果在iOS内核态实现了MPTCP,并将其应用在Siri、Apple Push Notification Service和Apple Music中,用来保障消息的送达率、降低音乐播放的卡顿次数和卡顿时间。

我们在18年曾与手机厂商合作(MPTCP同样需要厂商支持),并尝试搭建demo服务器验证端到端的优化效果,实验环境下测试对「收藏夹商品展示耗时」与「直播间首帧播放耗时」降低12-50%不等,然而最终由于落地成本太高并未规模化使用。由于XQUIC的用户态协议栈能够大大降低规模化落地的成本,现在我们重新尝试在QUIC的传输层实现多路径技术。

图15. Multipath QUIC协议栈模型

Multipath QUIC对于移动端用户最核心的提升在于,通过在协议栈层面实现多通道技术,能够在移动端同时复用Wi-Fi和蜂窝移动网络,来达到突破单条物理链路带宽上限的效果;在单边网络信号强度弱的情况下,可以通过另一条通道补偿。适用的业务场景包括上传、短视频点播和直播,可以提升网络传输速率、降低文件传输耗时、提升视频的秒开和卡顿率。在3GPP Release 17标准中也有可能将MPQUIC引入作为5G标准的一部分[7]。

技术层面上,和MPTCP不同,我们自研的MPQUIC采取了全新的算法设计,这使得MPQUIC相比于MPTCP性能更加优化,解决了slow path blocking问题。在弱网中的性能比以往提升30%以上。

图16. 弱网下相对单路径的文件平均下载时间降低比例(实验数据)

图17. 弱网下相对单路径的视频播放卡顿率降低比例(实验数据)

在推进MPQUIC技术落地的过程中,我们将会尝试在IETF工作组推进我们的方案作为MPQUIC草案的部分内容[8]。期望能够为MPQUIC的RFC标准制定和落地贡献一份力量。

下一步的未来

我们论证了QUIC的核心优势在于用户态的传输层实现(面向业务场景具备灵活调优的能力),而非单一针对弱网的优化。在业务场景的扩展方面,除了RPC、短视频、直播等场景外,XQUIC还会对其他场景例如上传链路等进行优化。

在5G逐步开始普及的时代背景下,IETF QUIC工作组预计也将在2020年底左右将QUIC草案发布为RFC标准,我们推测在5G大背景下QUIC的重要性将会进一步凸显。

QUIC/MPQUIC对于5G

对于5G下eMBB(Enhanced Mobile Broadband)和URLLC(Ultra Reliable Low Latency)带来的不同高带宽/低延迟业务场景,QUIC将能够更好地发挥优势,贴合场景需求调整传输策略(拥塞控制算法、ACK/重传策略)。对于5G运营商提供的切片能力,QUIC同样可以针对不同的切片适配合适的算法组合,使得基础设施提供的传输能力能够尽量达到最大化利用的效果。在XQUIC的传输层实现设计中,同样预留了所需的适配能力。

在5G推广期间,在基站部署不够密集的情况下,保障稳定的有效带宽将会是音视频类的应用场景面临的巨大挑战。Multipath QUIC技术能够在用户态协议栈提供有效的解决方案,然而这项新技术仍然有很多难点需要攻克,同时3GPP标准化组织也在关注这一技术的发展情况。

XQUIC开源计划

阿里淘系技术架构团队计划在2020年底开源XQUIC,期望能够帮助加速IETF标准化QUIC的推广,并期待更多的开源社区开发者参与到这个项目中来。

附录:参考文献

[1] SPDY - HTTP/2.0原型,由Google主导的支持双工通信的应用层协议

[2] HTTP/2.0 - https://tools.ietf.org/html/r...

[3] TLS/1.3 - https://tools.ietf.org/html/r...

[4] GQUIC - 指Google QUIC版本,与IETF QUIC草案版本有一定差异

[5] IETF QUIC - 指IETF QUIC工作组正在推进的QUIC系列草案:https://datatracker.ietf.org/...,包括QUIC-Transport、QUIC-TLS、QUIC-recovery、HTTP/3.0、QPACK等一系列草案内容

[6] MPTCP - https://datatracker.ietf.org/...

[7] 3GPP向IETF提出的需求说明 https://tools.ietf.org/html/d...

[8] MPQUIC - 我们正在尝试推进的草案 https://datatracker.ietf.org/...

淘系架构与基础服务团队

致力于为淘系和阿里提供基础核心能力、产品与解决方案:

•  下一代网络协议QUIC的实现与落地 - XQUIC
•  自适应高可用解决方案与核心能力 - Noah
•  新一代业务研发模式平台 - Gaia
•  支撑整个阿里的移动中间件体系(千万级QPS接入网关、API网关、推送/消息、移动配置中心等)
团队大牛云集~~ 想要加入我们,请邮件简历至:miaoji.lym@alibaba-inc.com

本篇内容来自于阿里巴巴淘系技术部,高级技术专家喵吉。
更多精彩内容可关注【淘系技术】公众号。

查看原文

赞 0 收藏 0 评论 0

阿里巴巴淘系技术 发布了文章 · 8月11日

Swift 5.3的进化:语法、标准库、调试能力大幅提升

概括

Swift 从 5.0 的 ABI 稳定到5.1 的模块稳定,Swift 终于不是《Swift 入门到重学》了。本次 WWDC2020,Swift 5.3 正式发布,Swift 依旧朝着安全、高效、易读的方向持续发力,不断的在改进语法,增强代码的表达能力和易用性。因为 Swift 的模块稳定,SPM 现在也支持了二进制模块的分发,逐渐完善的社区生态也在不断拓宽 Swift 可以涉足的领域,而不仅仅是在 Apple 平台之上。

下图展示了 WWDC2020 中 Swift 相关内容的脑图,希望可以帮助大家快速了解。

image.png

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师星志。
更多精彩内容可关注【淘系技术】公众号。)

语言环境的完善和拓展

一门完善编程语言有三个最基本的要素:语法、标准库、调试能力。语法设计决定了语言的编程范式;标准库决定了语言的基本能力;调试能力决定了开发者的体验和语言的稳定性。

苹果在 Swift 的迭代过程中不断的强化这几点,我们可以来看看 Swift 又得到了哪些提升。

语法特性

Swift 的语法设计核心还是 OOP,但是这不妨碍 Swift 的语法在支持 POP 和函数式编程甚至 DSL 得到的强化。Swift 也因为 SDL 特性的加入,开始逐渐的适应声明式编程的方向发展,比如后文提到的 @main 等等。

Multiple trailing closure

image.png

这个改进解决了当函数最后几个参数为闭包的情况下,导致的括号嵌套的问题,API 更加简洁也更加具有表达性。SwiftUI 利用这个语言特性,也变得更加简洁易懂。

KeyPath as Function

image

现在 KeyPath 可以当做函数来使用了。这个语法糖解决的问题当我们使用类似 map 一样的函数时,只需要取出对应数据模型中的某一个属性,为此我们不得不写类似 map { $0.property } 的代码,有了这个语法糖,事情就可以简化成了 map(\.property)

Type-based program entry point (@main)

引入了新的修饰符 @main,可以标记在带有 public static func main() 函数实现的所有类型,无论 main 函数时从拓展来得还是继承来的。添加这个特性的意义在与维持声明式的语义,将声明式语义进行到底。YES!


Increase availability of implicit self in closures

以前我们写逃逸闭包时如果捕获了 self,我们需要在跟 self 有关的地方写上 self. 以警示我们注意循环引用。

image.png

如果在闭包的捕获列表中显示声明捕获 self,在闭包中对 self 相关的访问可以省略。如果是在不可变的函数中访问,self 可以直接省略(为了 SwiftUI)。

image.png

其实这一点改进有用但是覆盖面并不是很广,因为在实际的应用中,我们都是尽量先弱引用 self 后再强引用 self,来保证 self 的可访问性。在如下场景就得不到此项优化:

image

Multi-pattern catch clauses

这种写法可以自动实现错误匹配,进入到对应的错误处理中,而不需要使用 switch,增强语言的可读性。

image.png

Enum enhancements

自动符合 Comparable

编译器现在可以自动为你生成 Comparable 的相关方法,实现 Enum 的比较。

image.png

Enum case 可以用来适配 protocol

这个特性看引用场景需要吧,官方给了一个比较好的例子。具体相关内容可以参考 SE-0280。

image.png

DSL 新增对 switch 的支持

现在可以在 SwiftUI 等 Swift DSL 中使用 switch-case 来进行模式匹配,之前只有对 if-else 的支持。某种程度上也是为 SwiftUI 而生的能力。

image.png

标准库

其实这里说标准库是广义的标准库,其中包括了开发者随语言分发的标准库,如标准 I/O 库等,运行时环境,编译环境,一方库等等。苹果今年在这部分下足了功夫,因为标准库、各种各样的一方三方库才是展现一门语言能力的地方,否则再好的语法也不会有人用,语言终究还是工具,能解决问题才是关键。

Swift 5.3 在代码尺寸和运行时都有不小的提升。Swift Package Manager(SPM)增加对二进制和资源的支持,深度集成 Xcode,亲儿子的优势逐渐显示了出来。Swift 本来设计的初衷本来就是一门 General Purpose 的语言,今年苹果正式宣布 Swift 支持了 Apple platform,Ubuntu/CentOS/Amazon Linux,不久的将来也会支持 Windows,正式成为一门优秀的跨平台语言。

标准库更新

  • Float16 的支持,具有更好的运算性能
  • Apple Archive 一种功能类似 zip 的压缩文件,苹果就是用这种格式来更新系统
  • Swift System 对操作系统基础 API 的包装,让 API 更健壮易用
  • OSLog 推荐使用的 logging system

从这些更新可以看出,苹果对 Swift 的底层操作非常关心,Swift System 的出现让使用 Swift 底层开发者脱离 OS C API 的折磨,获得更一致更健壮的代码体验。

新的一方库

Code Size and Runtime

在使用 UIKit 的情况下,Swift 4.1 时生成的二进制代码已经从 OC 的两倍还多,但是在 Swift 5.3 中,这个差距已经缩小到小于 1.5 倍了。也就是说之前大量使用 Swift app 会自动得到二进制大小的优化,而对于担忧 Swift 会造成包大小问题的 App,现在已经不算是很大的问题了。因为只需要付出可以接受的代价,就能获得 Swift 带来的安全性能和开发体验。

image.png

如果 App 使用了纯 SwiftUI,二进制代码甚至可以缩小 43% 之多。可见苹果优化 Swift 的功底之深,而且这些优化,只需要从新编译一次即可享受,何乐而不为。

image.png

因为 Swift 更紧凑的值类型,运行时的内存,分配相同的对象所需的空间自然比 OC 更小。Swift 5.3 相较 5.1,运行时的必要额外信息存储要少非常多,甚至做到了比 OC 还要少,大大减小了 Swift 的运行时内存。这对低内存的设备是非常有帮助的,同时,更少的系统内存意味着更多的用户内存。而这一切,只需要重新编译即可。

image.png

Swift 底层的不断优化也让其成为一门高效的语言,降低运行时的要求,就可以提升其应用的场景。

Swift Package Manager

SPM 作为 Swift 生态非常重要的一环,也迎来了更新。

  • SPM 支持二进制包分发
  • SPM 支持了资源的打包

这两点更新已经表明了 SPM 的能力已经足够完善了。目前具有一定规模 App 的内部模块都开始使用 Cocoapods 做二进制组件化的集成,这样可以明确对代码解耦,提高打包的效率。在这样的背景之下,SPM 对这两点关键特性的支持已经可以覆盖住大型 App 需求了,而且 SPM 不单单只跟 Swift 玩,C Family 它都可以支持。

在 SPM 与 Cocoapods 的对比中,亲儿子 SPM 跟 Xcode 深入整合,Xcode 可以直接打开编辑 swift package,Xcode 因为 SPM 设计了对应的操作界面,降低了开发和使用的门槛。成熟的工具链也让联调 Swift Package 轻而易举。而 Cocoapods 由社区维护,每一次 Xcode 更新其响应也不算很及时,在针对大型 App 时因为 Podfile 与 podspec 的分离导致了许多不一致,使用 ruby 还有一定的门槛。

现在也许是拥抱 SPM 的好时机。

跨平台

现在官方支持的操作系统列表如下:

  • Apple platform
  • Ubuntu 16.04, 18.04, 20.04
  • CentOS 8
  • Amazon Linux 2
  • Windows (coming soon)

真正做到的跨平台,并且 Swift 官方支持 AWS Lambda。AWS Lambda Runtime 已经开源,支持了 AWS 的 FaaS 编程,进一步的拓宽了 Swift 涉足的领域。

调试能力(开发者体验)

调试和开发者体验也是一门语言非常重要的一环,因为没有人会写出没有错误的代码,检查错误的能力和工具对一门语言来说十分重要。苹果也十分注重这一方面,在开发者体验上下足了功夫。

更加智能的诊断信息

刚开始使用 Swift 的开发者可能经常会对 Xcode 的报错信息不知所云,在引入 SwiftUI 后,这个问题尤为明显。笔者第一次编写 SwiftUI 时,只要 body 中某个地方出错,报出来的错误都是不正确的,只能通过肉眼检查和推断才能明白自己的错误,十分痛苦。

现在苹果重制了诊断能力,现在 Swift 的错误诊断比之前准确了许多,错误没有乱报并且错误提示也变得很好理解,特别是 SwiftUI,很容易知道错在哪了。在 Swift 中,编译通过就是对正确性的一个很好的证明,除非你用不安全的方式让编译器闭嘴。

自动补全

经过强化的类型推断系统,也增强了 Swift 的代码补全能力。这个估计升级到 Xcode 12 就可以顺利体验了。同时代码缩进能力也得到了加强。

LLDB

image.png

积极拥抱 Swift

看了这么多年 WWDC,每次看时大家应该都有一种心态

只支持最新版本,我们才支持 iOS X (低版本),这些东西跟我没关系

感觉 Swift 真香,但是现实只让我使用 OC(叹口气)

什么语言不是用,OC 这么多年肯定够用了

危机

然而如果不及时做出改变,保持能用就行,在前进的路上,背上的担子就会越来越重。当发现快走不动时,又回过头来看 WWDC,就会发现,原来解决方案很久以前就已经给出来了,只是当时不觉得是个问题,这不支持那不合适,但是现在想拿出来使用的时候,面对背上那一团团的乱码,却又束手无策。

做出改变是痛苦的,但是当以前觉得痒就挠挠就解决了的事情,逐渐变成现在的痛点时,要做出改变也许会更痛苦。

Swift 的出现就是为了替代并且超越 Objective-C 的语言,虽然说苹果因为历史原因还在使用 OC,但是种种迹象表明,苹果正在做积极的工作,逐渐通过 Swift 降低 OC 在整个系统的比重。

社区也在积极的转变,许多著名的第三方库都已经迁移至 Swift,OC 版本已经不再维护,例如 Lottie 已经在 Swift 版本上出现了 OC 版本不存在的特性,并且 OC 版本不再维护。这种现象慢慢会越来越多。

改变

我们也在积极探索 Swift 在手淘的落地,取得了 Swift 5.1 能模块在手淘中正确运行起来的阶段性成就。

现在时机已经成熟,语言特性,SPM,工具链,标准库都已经足够强大,是时候做出改变了。

Swift 虽然看起来很简单,但其实它是一种下限低,上限高的语言,集团内部的 Swift 环境,需要大家来一起维护。我们未来也要加强 Swift 语言相关的培训,让开发者真正理解 Swift,上手 Swift,成为一名 Swifter 而不是 OSwifter。

手淘客户端团队正在进行社招招聘,岗位有iOS Android客户端开发工程师等,欢迎推荐。

简历投递:junzhan.yzw@taobao.com

参考

  1. SwiftUI 背后那些事儿
  2. WWDC20 What's new in Swift
  3. WWDC19 What's new in Swift
  4. WWDC18 What's new in Swift
  5. WWDC17 What's new in Swift
  6. WWDC16 What's new in Swift)
  7. WWDC20 Swift packages: Resources and localization
  8. WWDC20 What's new in SwiftUI
  9. Swift 5 时代的机遇与挑战到底在哪里?
  10. Swift Evolution

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师星志。
更多精彩内容可关注【淘系技术】公众号。)

查看原文

赞 3 收藏 1 评论 0

阿里巴巴淘系技术 发布了文章 · 8月10日

Core Image:iOS图像处理技术追踪

简介

Core Image是苹果官方提供的图像处理框架,通过丰富的built-in(内置)或自定义Filter(过滤器)高效处理静态图片、动态图片或视频。开发者还可以通过构造Filter链或自定义Core Image Kernel来实现更丰富的效果。

在WWDC20中,苹果官方针对Core Image技术在以下三方面做了优化:Core Image对视频/动图的支持、基于Metal构建Core Image (CI) Kernel以及Core Image的Debug支持。这三方面会在下文逐一提到,文末笔者也会浅谈Core Image在手淘图片库中的应用可能以及对Core Image技术的展望。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师越伯。
更多精彩内容可关注【淘系技术】公众号。)

优化Core Image对视频/动图的支持

1. 创建CIContext

创建CIContext时,需要遵循一个view一个context的原则。由于视频的每一帧都会发生变化,将CIContext的cacheIntermediates属性设置为false可以大大减少内存消耗。

如果在使用Core Image时将同时运用Metal(作为输入或输出),通过设置MTLCommandQueue属性创建CIContext将会是较好选择。在不使用MTLCommandQueue的情况下,每一个Metal或CoreImage执行的任务都在不同队列中并以wait命令分隔开,导致任务执行效率低。通过设置MTLCommandQueue创建的CIContext和相应的Metal任务在同一队列中,能提高app的运行效率。

image.png

图一、不使用MTLCommandQueue的工作流程

image.png

图二、使用MTLCommandQueue的工作流程

2. 编写Core Image Kernel(在Metal中实现)

为了将效果处理得更丰富,通过Metal来实现自定义CI Kernel是个高效的选择。苹果官方提供了的许多方便部署的内置工具(都通过Metal实现),如内置CI滤镜。通过Metal实现自定义CI Kernel,不仅app的runtime编译时间将会大大减少(这段工作会移至app构建完成后进行),开发者还能获得高性能语言特性(如gather-reads、group-writes、半精度浮点数)、高效开发体验(如缩进检查、缩进高光)等功能。

3. 选择合适的View类

如果要对视频/动图应用特效,静态内容View如UIImageView或NSImageView应当被避免。AVPlayerView和MetalKit View(MTKView)是个两个不错的选择。前者为简单选择,后者为进阶选择。

使用AVPlayerView时,需要创建AVMutableVideoComposition对象,CI滤镜在block中执行图像处理任务。在进行断点debug时,通过点击CIImage对象地址右侧的眼睛图示可以浏览CI滤镜处理流程的详细信息。官方提供的案例中,Core Image还将10位的HDR视频帧数据自动从HLG转化成了Core Image working space。

image.png

图三、CI Image断点测试中展现的处理流程

使用MTKView时,开发者需要以frame和device作为参数重载init方法。VIew对应的CIContext也将在init函数中被创建。如果我们在macOS中开发支持HDR的view,color-Pixel-Format属性需要被设定为rgba16Float,wants-Extended-Dynamic-Range-Content属性需要被设定为true。设定完init方法后,开发者需要实现draw-in view方法。需要注意的是,此处并未直接将Metal材质传入CIRenderDestination函数,而是创建了一个会返回texture的block。这使得CIContext能在前面的帧尚未完成时将Metal工作入队。之后该方法会执行渲染任务(至指定目的地)并创建command buffer将当前绘制结果渲染至view。

本人也亲自尝试了通过Core Image处理视频的整个流程。以下案例使用CIVortexDistortion滤镜对视频进行逐帧处理并渲染,展示内容包含核心代码、原视频、CI滤镜处理后视频以及断点测试的滤镜逐帧处理图示。

image

代码一、测试核心代码

3.pngimage.png

断点调试时Core Image对每帧的处理流程

基于Metal构建Core Image Kernel

使用CI Kernel有诸多优势,包括上文提及的缩短runtime编译时间、高性能语言特性(如gather-reads、group-writes、半精度浮点数)、高效开发体验(如缩进检查、缩进高光)。基于Metal构建CI Kernel有5步流程,会在下文进行逐一介绍。

1. 在项目中增加自定义构建规则

苹果官方推荐在项目target中增加两项自定义构建规则。第一个构建规则针对以“.ci.metal”为后缀名的文件。该构建规则会创建一个以“.ci.air”为后缀名的二进制输出文件。

image.png

图五、针对“*.ci.metal”文件的构建规则

第二个构建规则针对以“.ci.air”为后缀名的文件(上一个构建规则的输出结果)。该构建规则会在app的资源文件夹内创建以“.ci.metallib”为后缀名的输出文件。

image.png

图六、针对“*.ci.air”文件的构建规则

2. 在项目中增加.ci.metal资源

在Xcode提供的创建面板中选择Metal File即可。开发者对Metal File进行命名时需要以“.ci”作为后缀名,这样项目中新生成的文件会以“.ci.metal”作为后缀名。

3. 编写Metal Kernel

便携Metal Kernel需要include CoreImage.h头文件,用来使用Metal和Core Image提供的各种类。官方提供的范例编写了一个CIColorKernel,输入参数为coreimage::samle_t对象(表示输入图片的一个像素)、time和coreimage::destination对象,返回float4像素。

image.png

图七、苹果官方提供的代码范例:Metal Kernel编写

苹果官方为开发者提供了描述CI Kernel中Metal Shader语言的文档,详情见「 Metal Shading Language for Core Image Kernels」。

4. 加载Kernel并应用于新图像(基于Swift)

Kernel会被CI滤镜的子类使用。苹果官方推荐开发者在实例化滤镜的CIKernel对象时使用静态属性(static property),这种情况下加载metallib资源的工作仅会执行一次(在首次需要时)。CI滤镜的子类也必须重载输出图片的属性,Kernel将在getter中进行图像处理并创建新图像。

image.png

图八、苹果官方提供的代码范例:Kernel加载与使用

Core Image的Debug支持

苹果官方在WWDC20详细介绍了Debug特性:CI_PRINT_TREE。

什么是CI_PRINT_TREE

CI_PRINT_TREE的基础框架与Xcode提供的Core Image Quick Look支持相同。Core Image Quick Look为开发者提供了快捷可视化的Core Image图片(详见上文图三),而CI_PRINT_TREE支持几种不同的模式和选项用来查看Core Image如何优化和渲染图像。

如何启用CI_PRINT_TREE

苹果官方提供了CI_PRINT_TREE的两种启动方式。最常用的方法是编辑Xcode target scheme,在Arugments窗体下的环境变量列表中加入CI_PRINT_TREE并设置值。另一种方法是在Terminal.app中通过命令行启动CI_PRINT_TREE(需要在执行应用程序前设定)。

image.png

image.png

图九、启用CI_PRINT_TREE的两种方式

如何控制CI_PRINT_TREE

CI_PRINT_TREE的字符串格式为“<graph type> <output type> <options>”

  1. graph type:表示Core Image render的若干stage,包括type-1初始图像(有助于查看被使用的色彩空间)、type-2优化后的图像(有助于查看core image对render的优化效果)、type-4级联图像(有助于查看各stage如何级联于GPU程序,以便了解render需要多少中间缓存)以及type-7(输出图像type1、2和4)。

image.png

图十、苹果官方对graph type四个stage的描述

  1. output type:输出格式可以是pdf或png。在macOS上trees会被存储在临时项目文件夹,在iOS上trees会被存储在文档(Documents)目录下。如果output type没有确定,core image会把tree以紧凑文本格式输出在标准输出(stdout)。通过设置CI_LOG_FILE="oslog",文本也可以前往Console.app(在iOS开发中更为方便)。
  2. options:对于CI_PRINT_TREE,开发者可以设定额外的选项。如通过设定context==name来限制输出(仅输出名字相同的context),或是通过设定frame-n来框定具体输出context的哪一帧。更多option及详情请见图十一。设定option对debug能提供很大帮助,但也需谨慎使用,因为生产这些文件需要额外的时间和内存。

image.png

图十一、苹果官方提供的option

image.png

图十二、type设定为7时tmp文件夹下的文件

如何获得CI_PRINT_TREE文件

在macOS中,开发者只需要进入“/tmp”文件夹就能找到生成的CI_PRINT_TREE文件。需要注意的是沙盒应用会使用特有的临时存储文件夹。在iOS中,开发者需要将Custom iOS Target Properties中的“Application supports iTunes file sharing”项设为YES(图十三)。这样生成的CI_PRINT_TREE文件可以在连接中的iOS设备上被找到并拖拽至macOS存储中。

image.png

图十三、Custom iOS Target Properties中进行设置

如何解释CI_PRINT_TREE文件

读CI_PRINT_TREE时,需要遵循以下规则:

  • 输入在底层,输出在顶层  
  • 绿色节点代表卷曲内核(warp kernel),红色节点代表颜色内核(color kernel)

image.png

图十四、绿色节点与红色节点示例

  • 在树的初始位置(initial tree)很容易找到颜色搭配节点(colormatch nodes),里面记录了搭配前后的色彩空间名称。苹果官方提供的案例为ITUR_2100_HLG_to_workingspace,即HLG色彩空间转化为Core Image线性色彩空间。

image.png

图十五、苹果官方案例中initial tree对色彩空间的描述

  • 每个节点会显示Region of Interest(ROI),表示该节点在render中被使用的范围。

如果开发者在CI_PRINT_TREE控制字符串中选择type-4并在option中设定dump-intermediates,产生的级联图片会展示中间缓存的每一次pass(除了output pass)及其耗时、像素点数量和像素点格式(用来查找耗时大、占内存大的pass)。这对render内追踪错误非常有帮助。如果树中没有展示中间图,那么说明这张图在先前渲染的时候已被缓存,因此Core Image没有渲染它的必要。

image.png

图十六、设定dump-intermediates的debug效果展示

Core Image在手淘图片库中的应用可能

手淘图片库中的CDN图片适配处理库(TBCDNImage)的核心目的是为不同终端设备、网络环境下的图片展示提供最优解。目前考虑的维度主要是终端设备硬件和网络状态,考虑的参数则是图片尺寸、压缩比率、锐化等图片属性。随着苹果在Core Image、端智能(CoreML)、硬件支持(自研芯片)等方面进行技术提升,淘的CDN图片适配处理库可以考虑增加“图片内容”作为新的维度,增加亮度、对比度、滤镜、图片种类等新参数。以下为部分应用场景:

  • 识别亮度较暗的图片,提升亮度做CDN图片适配处理
  • 判断图片内容种类(如美食),根据不同内容种类的图片增加适合的滤镜做CDN图片适配处理
  • 根据移动终端设备屏幕亮度(或深/浅色模式)修改图片色调做CDN图片适配处理,达到护眼效果

对Core Image技术的展望

总结全文,WWDC20对Core Image技术的提升主要在三方面:

  • 优化CI对视频/动图的支持,包括开发流程简化、逐帧处理性能提升等。
  • 允许开发者更自由的构建Core Image Kernel,使CI的特效处理更加丰富
  • 针对CI开发流程提供更高效的Debug支持

随着苹果未来自研芯片的底层硬件支持将提供视频流流畅的逐帧处理与渲染。笔者认为Core Image技术将会在以下场景有较大应用价值:

  • 直播滤镜/特效功能原生化(摆脱自研或第三方API),实现质量更高的实时滤镜渲染
  • 视频拍摄增加滤镜功能(如淘宝或咸鱼的商品视频录制)

参考:

① https://developer.apple.com/m...

https://github.com/duzhaoquan...

团队招人

手淘客户端团队正在进行社招招聘,岗位有iOS Android客户端开发工程师、欢迎大家加入我们。

简历投递:junzhan.yzw@taobao.com

更多有关手淘的技术内容分享敬请关注VX公众号【淘系技术】

查看原文

赞 1 收藏 0 评论 0

阿里巴巴淘系技术 发布了文章 · 7月29日

WWDC20:无线网络优化实践,带来哪些启发?

0. 引

网络技术作为互联网应用赖以存在的技术基础,速度与安全永远是其核心使命,本次WWDC的网络类topic涵盖内容基本还是围绕这两个点来展开。本次WWDC网络类session在基础网络技术上譬如新协议、新算法方面着墨并不多;也未提出新的类似NSURLSession / Network.framework之类的新网络组件。站在应用视角,本次WWDC网络类session可分为两大类:

  • 无线网络体验优化实践在系统层面的标准化;
  • 本地网络应用的权限管控增强。

在第一类议题中,我们看到很多已经在手淘中的类似实践,或标准或自研,说明手淘在网络技术的开发与应用上还是较为深入和前沿的,基本走在全球业界前列。根据我们手淘的业务特点,笔者重点关注第一类session,并简单探讨该新技术可以我们带来什么样启发和变化。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发专家 无宸。
更多精彩内容可关注【淘系技术】公众号。)

1. 使用加密DNS

DNS解析是网络的连接的第一步,这里提到的"加密DNS"是什么、它解决什么问题?

1.1 解决什么问题

一是传统Local DNS的查询与回复均基于非加密UDP,我们常见的DNS劫持问题

image.png

二是Local DNS Server本身不可信,或者本地Local DNS 服务不可用

image.png

其实针对DNS解析过程中以上两个问题,在实践中早就有了解决方案,就是HTTPDNS, 各大云厂商也都有成熟产品售卖,那苹果这里的加密DNS与我们的现有HTTPDNS有何不同呢?现有HTTPDNS有两个很大的问题:一是对业务的侵入性,即如果某个网络连接需要使用HTTPDNS的能力,首先他需要集成服务商提供的SDK, 引入相应的Class,然后修改网络连接的阶段的代码;二是面临各种技术坑,比如302场景的IP直连处理、WebView下IP直连如何处理Cookie、以及iOS上的老大难的SNI问题等,这些都需要业务开发者付出极大的努力和尝试。

iOS 14 上的 Encrypted DNS 功能很好的解决了现有HTTPDNS的存在的问题。

1.2 规范与标准

iOS 14 开始系统原生支持两种标准规范的 Encrypted DNS, 分别是 DNS over TLS 与 DNS over HTTPS.

image.png

具体协议标准可以参见:rfc7858 (DoT)rfc8484 (DoH)

1.3 如何实现

iOS 14 提供了两种设置加密DNS的方法。第一种方式是选择一个DNS服务器作为系统全局所有App默认的DNS解析器,如果你提供的是一个公共DNS服务器,你可以使用NEDNSSettingsManager API编写一个NetworkExtension App完成系统全局加密DNS设置。或者如果你使用MDM(Mobile Device Management)管理设备的企业设置;你可以推送一个包含DNSSettings paload的profile文件完成加密DNS设置。

image.png

使用NetworkExtension设置系统域全局DNS服务器示例代码:

图1.png

上述代码首先通过NEDNSSettingsManager加载配置,加载成功后,创建一个基于DoH协议的NEDNSOverHTTPSSettings实例,对其配置DNS IP地址和域名,DNS IP地址是可选配置的。然后将NEDNSOverHTTPSSettings实例配置到NEDNSSettingsManager共享实例的dnsSettings属性,最后保存配置。

一条DNS配置包括DNS服务器地址、DoT/DoH协议、一组网络规则。网络规则确保DNS设置兼容不同的网络。因为公共DNS服务器是无法解析本地网络的私有域名,比如只有企业WiFi网络内的DNS服务器可以解析员工访问的私有域名,这类情况就需要手动指定网络规则兼容企业WiFi网。网络规则可以针对不同网络类型定义行为,比如蜂窝网、WiFi、或者具体的WiFi SSID。在匹配的网络下,你可以禁用配置的全局DNS设置,或者对私有域名不使用DNS设置。而在一些情况下,兼容性会自动处理。比如强制门户网络(captive portal), 手机在连接上某个WiFi的时候,自动弹出一个页面输入账号密码才能连接网络。这种情况下系统域全局DNS配置会做例外处理。

网络规则设置示例代码:

图2.png

上述代码设置了三个网络规则,第一个规则表示DNS配置应该在SSID="MyWorkWiFi"的WiFi网络生效,但对私有企业域名enterprise.example.net不开启。 第二个规则表示规则在蜂窝网下应该被禁止使用;第三个NEOnDemandRuleConnect表示DNS配置应该默认开启;因为配置DNS是系统支持的,所以在编写NetworkExtension App时不需要实现Extension程序,只需要在Network Extensions中勾选DNS Settings选项。

图7.png

运行NetworkExtension App,DNS配置将会被安装到系统,为了让DNS配置生效,需要前往设置->通用 & Network->DNS手动启用。

图3.png

一些网络可能会通过策略阻止你使用加密的DNS服务器。这些网络尝试分析DNS查询请求来过滤流量。对于此类网络,系统会被标记隐私警告提示,在该网络下的网络连接将会失败。

图4.png

第二种方式是针对单个App的所有连接或部分连接启用加密DNS。

image.png

如果你只想为你的App使用加密DNS,而非涉及整个系统域。你可以适配Network framework的PrivacyContext,对你的整个App开启加密DNS,或者仅对某一连接开启。不管使用的是URLSessionTask,或Network framework连接或getaddrinfo的POSIX API,这种方式都有效。

对单个连接使用加密DNS示例代码:

图5.png

验证请求是否使用加密DNS:

截屏2020-06-26 上午1.24.27.png

如果你想在App范围内使用加密DNS,你可以配置默认的PrivacyContext;App内发起的每个DNS解析都会使用这个配置。不管是URLSessionTask,还是类似getaddrinfo的底层API。

图6.png

1.4 现有实践对比及启发

  • 与现有实践对比

上文已经提到过HTTPDNS产品,手淘的域名解析,采用的是类似于HTTPDNS原理,但更加复杂的调度方案。但是相比于这种系统层面的标准化方案,解决了现有实践中的两大难题:

  • 对业务的侵入性:业务必须修改现有网络连接的阶段的代码;
  • 交互的标准兼容性不足:IP直连下的302问题、Cookie问题、SNI问题等
  • 带来的变化

一是在应用内部,我们可以对业务透明提供提供全局的域名调度或者域名兜底解析能力, 不再是只有用到特定组件或SDK才可以。二是苹果放开系统级别DNS接管后,用户设备上的服务相比原Local DNS的“中立性”如何管控?对特定业务是否甚至会造成恶化?如果对外部应用的这种“中立性”疑问或担心确实存在,则这种系统标准化的加密DNS对手淘这种大型应用则是必选项。

2. 受限网络中推送

2.1 解决什么问题

当向iOS设备推送消息时,业务服务器需要将消息先发送给APNS服务器,APNS服务器再将消息转换为通知payload推送给目标设备。如果设备所在的WiFi网络没有连接互联网或者当前网络受限,比如在游艇、医院、野营地这些地方,设备没有与APNS服务器建立有效连接,APNS消息投递将会失败。

截屏2020-06-27 上午12.46.47.png

对于一些App来说,接收推送消息是App的一项非常重要的功能,即使在没有互联网连接的情况下也需要持续稳定工作。为了满足这一需求,iOS 14中增加了本地推送连接(Local Push Connectivity)API,这是NetworkExtension家族中新的API。本地推送连接API允许开发者创建自己的推送连接服务,通过开发一个App Extension,在指定的WiFi网络下可以直接与本地业务服务器通信。

截屏2020-06-27 上午1.02.19.png

上图中,App Extension主要负责保持与本地业务服务器之间的连接,以及接收业务服务器发来的通知。因为没有了APNS,开发者需要为业务服务器与App Extension定义自己的通信协议。主App需要配置具体在哪个WiFi网络下使用本地推送连接。当App加入到指定的WiFi网络,系统会拉起App Extension, 并在后台持续运行。当App断开与指定WiFi网络的连接,系统将停止App Extension运行。

2.2 如何实现

本地推送连接对那些推送功能非常重要,而设备所在网络受限的场景非常适合。而对于常规的推送需求,依然推荐使用PushKit或UserNotification API处理APNS推送消息。每台设备和APNS服务器之间只建立一条APNS连接,设备上所有App都公用这一条连接,所以APNS非常省电。

APNS与本地推送连接对比:

截屏2020-06-27 上午1.25.28.png

新的本地推送连接API由两个类组成:NEAppPushManager和NEAppPushProvider。NEAppPushManager在主App中使用,主App使用NEAppPushManager创建一个配置,配置中指定具体哪个WiFi网络下运行本地推送连接。你可以使用NEAppPushManager加载/移除/保存配置。NEAppPushProvider则在App Extension使用。在App Extension中实现一个NEAppPushProvider的子类,子类中需要覆盖生命周期管理方法,这些方法在App Extension运行和停止时被调用。

App Extension主要处理两类推送,一类是常规的推送通知,一类是VoIP呼叫通知。如果是常规的推送通知,App Extension收到消息后,可以使用UserNotification API构造一个本地推送显示推送信息。如果是VoIP呼叫通知,App Extension使用NEAppPushProvider类将呼叫信息报告给系统。如果此时主App不在运行,系统将唤醒主App,并将消息投递给它,最后主App再使用CallKit API显示呼叫界面。

截屏2020-06-27 上午11.40.13.png

下面是在主App中使用NEAppPushManager的示例代码:

截屏2020-06-27 上午1.44.40.png

上述代码创建了一个NEAppPushManager实例,并配置实例的各个属性值。matchSSIDs表示在指定的WiFi网络下才启用本地推送连接。providerBundleIdentifier表示App Extension的包名,providerConfiguration是传给App Extension的一些配置,在App Extension内可以通过NEAppPushProvider的providerConfiguration属性获取。isEnabled表示使用这个配置开启本地推送连接。最后调用saveToPreferences方法持久化配置。下面是App Extension实现NEAppPushProvider子类的示例代码:

截屏2020-06-27 上午1.46.47.png

系统调用start(completionHandler:)方法启动App Extension,在这个方法内App Extension与本地业务服务器建立连接。当App Extension停止运行,系统调用stop(with:)方法, 在这个方法内App Extension断开与业务服务器的连接。handleIncomingVoIPCall(callInfo:)方法在收到VoIP呼叫时被调用,在方法内App Extension调用reportIncomingCall(userInfo:)将该事件上报给系统。随后系统将会唤醒主App,并将呼叫信息传递给主App。主App处理系统传入的呼叫信息示例代码:

图8.png

以上代码在AppDelegate的didFinishLaunchingWithOptions方法内使用NEAppPushManager加载所有配置,并设置每个NEAppPushManager示例的代理属性。系统会在主线程中将接收到呼叫信息通过didReceiveIncomingCallWithUserInfo方法投递给主App。主App必须通过CallKit API将呼入信息上报给CallKit展示呼叫界面。

2.3 价值场景

如果只考虑推送本身,对于手淘或者大部分消费类应用来说,笔者认为价值并不大,因为此类APP不可能在一个封闭的本地网络里去部署资源来提供服务能力。这里一个可应用的点在于:设备一旦进入特定网络环境,触发App Extension, 进而唤起主App,应用可在后台完成一定事务。因为 iOS App 一直缺乏后台服务能力,这种特定网络环境的触发唤醒,极大的补充了这一能力。

3. 现代网络技术的应用

苹果在这次WWDC中,把一些较新的网络技术,对应用的体验提升,做了一个简单综述,包括IPv6、HTTP/2、TLS1.3, MTCP、以及HTTP/3。这些技术在手淘基本都有涉及,有些是已经是大规模部署、有些是正在逐步推进中。对各个应用来说,如果已经在应用这些技术了,则云端均尽可能标准化,便于进一步推广和复用。这里简单的对苹果的综述做一个搬运:

3.1 IPv6

苹果根据最新统计,苹果全球设备TCP连接占比中,IPv6占比26%,IPv4占比74%,其中74%的占比中有20%是因为服务端没有开启IPv6支持。在建连时间方面,由于减少了NAT使用,提高了路由效率,IPv6的建连时间比IPv4快1.4倍。开发者只需使用URLSession和Network.framework API,IPv6网络适配将自动支持。

截屏2020-06-29 下午7.44.02.png

以上是苹果的数据。阿里巴巴集团从18年开始大力推进IPv6的建设,目前我们在IPv6整体应用规模上在业界是属于头部大厂。但根据我们应用的实际效果数据,以及业界友商的应用数据,性能提升并不明显。以及工信部的IPv6建设目标来看,性能提升也不是IPv6建设的目标,只要达到IPv4同等水平即可。IPv6 的意义就在解决IPv4地址空间枯竭的问题,更多的在规模、安全,而不是性能提升。就企业而言,例如可以降低IPv4地址的购买费用;就国家而言,IPv6 突破了IPv4中国境内无DNS根结点的风险。IPv6目前阶段在国内尚处于发展中,基础运营商覆盖、家用网络接入设备支持、应用服务的支持,正在快速发展中。

3.2 HTTP/2

HTTP/2的多路复用特性使得对同一服务器的多个请求复用到单个连接上,不必等待前一个请求响应结束才能发送下一个请求,不仅节省了时间也提升了性能。头部压缩特性提升了带宽利用率,通过简化消息内容,从而降低消息的大小。根据最新统计,在Safari中HTTP2 Web流量占比79%,HTTP/2比HTTP/1.1快1.8倍。如果服务端支持HTTP/2,URLSession将默认使用HTTP/2。

截屏2020-06-29 下午11.02.47.png

在手淘业务中,全面应用HTTP2已经有三四年之久,其使用规模比苹果统计的结果要高的多,取得了巨大的体验提升收获。手淘的核心流量分为两类:API请求MTOP于图片CDN请求,这两类的HTTP2的流量占比约超过 98%,基本实现核心流量全部长连化。但当前手淘的HTTP2技术在设备支持之前即大规模应用,协议栈完全自研,为进一步提升建联速度,又做了一些预置证书的优化。下一步将逐步使基础网络依赖标准化平台能力,降低对私有协议栈的依赖,可降低包大小以及提升产品复用体验。

3.3 TLS1.3

TLS1.3通过减少一次握手减少了建连时间,通过形式化验证(Formal Verification)与减少被错误配置的可能性,提高了通信安全。从iOS 13.4开始,TLS1.3默认在URLSession和Network.framework开启。根据最新统计,在最新的iOS系统上,大约49%的连接使用TLS1.3。使用TLS1.3比使用TLS1.2建连时间快1.3倍。如果服务端支持TLS1.3,URLSession将默认使用TLS1.3。

截屏2020-06-29 下午11.02.24.png

目前手淘的HTTP/2 的TLS version仍然还是基于TLS1.2,不过为了解决低版本TLS的性能之殇,手淘网络通过预置证书与自定义 SSL 握手流程,创新自研了slight-ssl协议,实现了 0rtt 的效果。TLS 1.3 标准在系统层面的全面支持,对应用来说是一个明确的技术趋势信号,我们的网络协议需尽快标准化,对网络管道两端来说,客户端应用层网络接口需全面升级到NSURLSession或Network.framework, 实现对系统标准能力的应用;云端也许全面支持TLS1.3,可不依赖端侧SDK即可提供更新安全、高效、标准的网连接。

3.4 MultiPath TCP

MultiPath TCP 允许在一条TCP链路中建立多个子通道。当设备切换网络时,单个TCP连接依然可以继续使用。苹果的Apple Music与Siri服务都使用了MultiPath TCP。Apple Music在使用MultiPath TCP之后,音乐播放卡顿次数减少了13%,卡顿持续时间减少了22%。开启MultiPath TCP需要客户端和服务端都支持才能生效,服务端支持MultiPath TCP可参考:http://multipath-tcp.org/

其实手淘在这方面也有类似的优化尝试:多网卡:同时通过Wi-Fi与蜂窝网连接目标服务器,提升数据传输速度。其技术原理与MTCP不一样,但也是想在上层起到类似作用:通过多路连接,提升数据交换带宽。 业界也有类似的产品,例如华为的 LinkTurbo。

3.5 HTTP/3

HTTP/3是下一代HTTP协议,它是构建在新的QUIC传输协议之上,QUIC协议内建了对TLS1.3的支持,并提供了与HTTP/2一样的多路复用功能,并进一步减少了队头阻塞的发生,让单个请求或相应的丢失不影响到其他请求。使用QUIC的HTTP/3还具有较高的保真度信息,以提供改进的拥塞控制和丢包恢复。同时也包括内建的移动性支持,这样网络切换不会导致正在进行的操作失败,可以无缝在不同网络之间切换。不过HTTP/3目前还处于草案阶段,iOS 14和MacOS Big Sur包括了一个对使用URLSession的HTTP/3的实验预览支持,这个功能可以在开发者设置中开启。同时Safari的HTTP/3支持也可在开发者设置中开启。

截屏2020-06-30 上午12.48.15.png

在手淘中,我们的QUIC应用应该会早于苹果系统先行支持,目前已经在灰度中。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发专家 无宸。
更多精彩内容可关注【淘系技术】公众号。)

——————————————————————————————————————————————————

手淘客户端团队正在进行社招招聘,岗位有iOS Android客户端开发工程师等,欢迎推荐。

简历投递:junzhan.yzw@taobao.com

查看原文

赞 0 收藏 0 评论 0

阿里巴巴淘系技术 发布了文章 · 7月23日

Apple Widget:下一个顶级流量入口?

0x00 前言

2020 年 6 月 22 日,苹果召开了第一次线上的开发者大会 - WWDC20。这可谓是一次可以载入史册的发布会,宣布了 ARM 架构 Mac 芯片、软硬件的生态大统一、iOS 14 系统界面大改等一系列激动人心的消息。

当然,最让我感兴趣的就是让 iOS 界面大改的 Widget 了。过去几年,iOS 的桌面交互体验可谓是一言难尽,Widget 的加入无疑是一次比较大的破局。在看发布会的时候,我的脑海里就浮现出一个问题:“这会是下一个互联网公司竞争的流量入口吗?”

先不抛结论,让我们先看一下 WWDC20 介绍了哪些关于 Widget 的新东西。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,高级无线开发工程师柘剑。
更多精彩内容可关注【淘系技术】公众号。)

0x01 什么是 Widget?

Widget 不是一个小型的 App,它是一种新的桌面内容展现形式,主要是用于弥补主应用程序无法及时展示用户所关心的数据。如下图所示:

image.png

一个优秀的 Widget 需要有三个特点:简单明了(Glanceable)恰当展示(Relevant)个性化定制(Personalized)

简单明了(Glanceable)

Widget 不是一个小型的 App,这句话被反复提起。一般用户每天进入主屏幕的次数超过 90 次,但停留的总时长不过几分钟。通常来说用户只会在主屏幕上停留片刻时间,就会跳转到其他地方,所以并不需要任何复杂的交互设计来增强 Widget 的作用,也不需要复杂的样式来丰富 Widget 的内容,简单明了的内容才是 Widget 的关键。

和安卓的 Widget 不太一样,苹果设计的 Widget 并不支持任何交互行为,也不建议大家设计过于复杂的样式来呈现内容,这也非常符合苹果对于主屏幕的改进一直保持克制的特点。

恰当展示(Relevant)

苹果期望 Widget 可以和正在执行或者考虑的事情紧密的结合。比如,早上起床,用户最关心天气怎么样,Widget 可以展示一下天气情况;起床后,用户就要了解一下一天的行程,Widget 可以展示一下 Reminders 中的内容;等到一天忙完了,准备睡觉的时候,可以用 Widget 打开音乐稍微放松一下。为此,苹果系统提供了一个叫智能叠放(Smart Stacks)的功能,智能叠放是一个 Widgets 的集合。系统会根据每个人的习惯,借助端智能的能力,自动的显示准确的 Widget 在最顶部。

image.png

当然,苹果也考虑到了一些特殊的场景,比如 Widget Gallery 浏览时,提供了 Snapshot 的能力给到开发者可以定制展示样式,当加载内容的时候提供了 Placeholder UI API 而不是单调的 loading 加载框来避免过多的白屏的尴尬局面。这些设计的目的只有一个,苹果期望 Widget 可以在任何特定的场景都可以展示合理的样式。

个性化定制(Personalized)

Widget 需要一定的定制能力,比如当我添加一个天气 Widget,我只需要关心杭州的天气怎么样。为了实现这个能力,苹果给 Widget 提供了 Configuration 的能力。顾名思义,就是可配置。一共有两种配置类型:

image.png

  • StaticConfiguration,也就是用户无需配置,展示的内容只和用户信息有关系。
  • IntentConfiguration,支持用户配置及用户意图的推测功能。

IntentConfiguration 的实现是基于 Intents.framework,开发过 SiriKit 和 Shortcuts 一定知道 Intents API 是用于了解用户意图的。其实就是一个智能的表单系统,开发者创建一个 SiriKit Intent Definition File 之后,只需要简单的配置,Xcode 会自动帮你生成对应的代码和类型。

image.png

当开发者编写完配置之后,会借助 Intents.framework 的能力,在运行的时候直接绘制出一个配置页面(如下图所示),开发者并不需要关心如果编写这个页面。

image.png

0x02 Widget 的刷新方式


Widget 的刷新方式是很特别的,相当的克制。在展开讲刷新方式之前,要讲一个概念,叫 Timeline。顾名思义,就是时间线,下面的图就是一条 Timeline。

image.png

当系统的 WidgetKit 调用 Reload Timeline API 之后,会要求 Widget Extension 的 Timeline Provider 提供一组 TimelineEntry 和 ReloadPolicy,用来后续刷新页面。

这里的概念比较多,我们一个一个来解释。

首先,Widget 的刷新完全由 WidgetCenter 控制。开发者无法通过任何 API 去主动刷新 Widget 的页面,只能告知 WidgetCenter,Timeline 需要刷新了。

系统提供了两种方式来驱动 Timeline 的 Reload。System Reloads 和 App-Driven Reloads。

System Reloads: 这个行为由系统主动发起,会调用一次 Reload Timeline 向 Widget 请求下一阶段刷新的数据。系统除了会按时发起 System Reloads 之外,还会借助端智能的能力,动态决策每个不同的 TimeLine 的 System Reloads 的频次。例如被查看次数很大程度上直接决定了 System Reloads 的频率。当然还有一些由于设备环境变化触发的行为也会触发 System Reloads,比如设备时间进行了变更。

App-Driven Reloads:指的是 App 请求 Widget 下一阶段刷新的数据。这里也要分两种场景,应用在前台运行和应用在后台运行。当应用在前台运行的时候,App 可以直接请求 WidgetCenter 的 API 来触发 Reload Timeline;而当应用处于后台时,后台推送(Background Notification)也可以触发 Reload Timeline。

image.png

注意,前面所提到的 Reload Timeline 并不是直接刷新 Widget,而是 WidgetCenter 重新向 Widget 请求下一阶段的数据。而 Timeline Provider 就是提供这个数据的对象。

而 Timeline Provider 提供的数据有两部分,一部分是 TimelineEntry,另外一部分是 ReloadPolicy。

TimelineEntry 是某个时间节点下 Widget 需要呈现的视图信息和时间点。

而 ReloadPolicy 则是接下来这段时间 Timeline 的刷新策略,一共有三种:

  • atEnd: 是指 Timeline 执行到最后一个时间片的时候再刷新。
  • atAfter: 是指在某个时间以后有规律的刷新。
  • never:是指以后不需要刷新了。什么时候需要重新刷新需要 App 重新告知 Widget。

当 Timeline Provider 提供完下一阶段的数据之后,就会停止运行。系统也会根据 entry 的信息,到点对 Widget 的展示内容进行刷新。值得一提的是,WidgetKit 会把 Timelines 所定义的 Entries 对应的 Views 结构信息缓存到磁盘,然后在刷新的时候才通过 JIT 的方式来渲染。这使得系统可以在极低电量开销下为众多 Widgets 处理 Timelines 信息。

简而言之,苹果对 Widget 的刷新相当的克制。开发者无法直接决定 Widget 刷新,只能提供刷新策略。具体的时间和节奏全部由系统来控制。苹果这么做,大概率是为了提高主屏幕的性能和减少电量开销上的考虑。

0x03 Widget 和 SwiftUI

Widget 只能用 SwiftUI 来进行开发,确切的说,Widget 的本质是一个随着时间线而更新的 SwiftUI 视图

image.png

当我最开始知道这个限制的时候,说实话是相当震惊的。众所周知,SwiftUI 是一个去年才发布的新技术,而且最开始的时候 SwiftUI 是相当不稳定的,以至于苹果自己都是建议开发者暂时不要用到生产环境上,Widget 作为系统主屏幕的功能,强制使用这么新的技术,会不会太激进了?

显然是不会。苹果要求 Widget 只能使用 SwiftUI 主要是基于几点考虑:

  1. SwiftUI 经过一年的发展,有了很大的提升,不仅可以使用 SwiftUI 来构建整个应用程序,而且在一些方面已经优于基于 UIKit 的开发方式了。具体的内容,大家可以看一下 《详解 WWDC 20 SwiftUI 的重大改变及核心优势》
  2. 苹果正在布局跨平台,大统一的策略。Widget 作为系统的核心功能,使用 SwiftUI 是唯一的选择。SwiftUI 精美的 DSL 设计,使得开发者使用一套代码在 iOS、iPadOS、macOS、watchOS 和 tvOS 等多个平台展示不同的样式可以轻松的实现。(Widget 只会在 iOS、iPadOS 以及 macOS 上展示)
  3. 使用了 SwiftUI 使得 Dynamic Type 和 Dark Mode 等问题适配起来成本很低。
  4. 只有使用 SwiftUI 才能达到很多对于 Widget 的限制。倘若可以使用 UIKit 开发者可能有无数种办法绕过苹果的限制。比如开发无法使用 UIViewRepresentable 来桥接 UIKit,只要使用任何 UIKit 的元素会直接 Crash。
  5. 将 Swift 语言和 SwiftUI 的重要程度提升了一大截。

0x04 Widget 的展示形式

一个 App 可以对应多个 Widget Extension

你可以使用 WidgetBundle 来进行组装。苹果并没有对 Widget Extension 有数量上的限制。所以为了避免大家开发过多的 Widget Extension 导致搜索起来麻烦,在 Widget Gallery 中只能看到一个条目。

normal-video.gif

一个 Widget Extension 一共只有三种尺寸。

考虑到简单明了的特点以及手机屏幕的空间有限的问题。苹果只提供了三种样式可以选择,systemSmall(2 * 2 icon 区域)、systemMedium(2*4 icon 区域)、systemLarge(4 * 4 icon 区域)

image.png

同一种 Widget 可以被多次添加到主屏幕中

而且对于每一个 Widget 来说,都有其对应的独立 TimeLine,相互独立,互不干扰。

image.png

开发者无法开发智能叠放(Smart Stacks)

开发者无法开发一个 Widget 的集合。智能叠放(Smart Stacks)是一个系统特有的能力,对于开发者来说,唯一可以做的就是主动提供相关性信息。前文提到了 Timeline 的数据又一组 TimelineEntry 组成,而每个 TimelineEntry 除了包含时间点和视图信息以外,还可以包含一个 TimelineEntryRelevance 对象,用来表示这个 entry 的相关性。

不可交互,只可点击

Widget 的 UI 是无状态的,不支持滚动,也不支持像 Switch 一样的互动元素。唯一开放的能力只有通过点击和DeepLink 来唤起主 App。

苹果提供了两种 API 给到开发者,第一种是 SwiftUI widgetURL API),代码如下所示:

image.png

而 widgetURL 的可点击区域如下:

image.png

对于 systemSmall 类型来说,只支持 widgetURL 的方式,但是 systemMediumsystemLarge 还可以使用 SwiftUI Link API,代码如下所示:

image.png

而 Link 的可点击区域如下:

image.png

同时,为了性能和耗电量的考虑。Widget 不能展示视频和动态图像。所以期待通过动效吸引用户眼球的方式可以暂时息熄火了~

0x03 总结与展望

Widget 的出现,让 iOS 系统的桌面有了破局,一定会有很多产品都期待借助 Widget 来丰富自己产品的内容表达。

但是,Widget 设计的初衷是简单明了的在恰当的时机展示一些带有个性化定制的内容,为了不让主屏幕的整体使用体验变得复杂,Widget 从技术上就做的很克制,限制了很多很多的能力。因此我认为Widget 不会成为下一个互联网公司竞争的流量入口,它会成为 App 提高用户体验的利器。

从技术角度看,SwiftUI Only 这种看似“激进”的策略其实也是一种信号,其实也是在告诉大家苹果对于 Swift 以及 SwiftUI 的重视程度。

虽然,从目前来看 Pure SwiftUI 的设计,可以做的事情真的很少,但是我也相信,苹果会不断优化 Pure SwiftUI 的能力。让开发者可以以最低的开发成本,适配更多的平台。

最后,也期待大家可以好好研究一下 Widget,结合自己的产品,给到用户极致的用户体验。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,高级无线开发工程师柘剑。
更多精彩内容可关注【淘系技术】公众号。)

参考

iOS 14 Preview: https://www.apple.com.cn/ios/ios-14-preview/

Widgets code-along: https://developer.apple.com/news/?id=yv6so7ie

Meet WidgetKit: https://developer.apple.com/videos/play/wwdc2020/10028/

What's new in SwiftUI: https://developer.apple.com/videos/play/wwdc2020/10041/

Add configuration and intelligence to your widgets:https://developer.apple.com/videos/play/wwdc2020/10194/

Build SwiftUI views for widgets: https://developer.apple.com/videos/play/wwdc2020/10033/

Creating a Widget Extension: https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension

Building Widgets Using WidgetKit and SwiftUI:https://developer.apple.com/documentation/widgetkit/building_widgets_using_widgetkit_and_swiftui

Making a Configurable Widget: https://developer.apple.com/documentation/widgetkit/making-a-configurable-widget

Keeping a Widget Up To Date: https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date

团队招人

负责手淘移动端的基础PaaS及平台技术。涉及移动网关、网络加速、长连通道、图片体验等基础技术,以及海量消息推送、浮层搭投全域触达等平台型技术,并对移动端系统进行前沿探索,打造了全站IPv6、iOS用户态网络栈、Android最小核、自适应线程调度等高性能技术和架构。

在这里,你会面临超级App在性能、体验、安全等方面的极致追求;在这里,你会站在业务和数据视角针对目标进行充分了解和深入优化;在这里,你会与业界各领域大牛并肩作战、快速成长。

我们期待有技术、有理想的你加入,与我们共享积极、透明、开放的团队氛围,伴随着各种干货满满的分享培训以及业务和技术挑战,我们将一同在技术领域不断攻坚、推陈出新,共同驶向属于我们的星辰大海。

职位:iOS 开发、Android 开发、C++开发、Java 服务端开发、前端开发、数据工程师、算法工程师

感兴趣的同学可将简历发送到:zhejian.wzj@alibaba-inc.com,获取优先内推资格!

查看原文

赞 4 收藏 1 评论 0

阿里巴巴淘系技术 发布了文章 · 7月21日

Swift 5.3 又更新了什么新奇爽快的语法?

Swift 发展里程碑

Swift 在 WWDC14 正式发布到 2019,经过 5 年的不断迭代,这其中经历了标准库变动,语法的增减。首先使用 Swift 作为开发语言的开发者们都苦不堪言,戏称《Swift 从入门到重学》,几乎每一年 Swift 都会迎来比较大的改动,甚至 API 都发生了变化。

WWDC 19 苹果发布了 Swift 5.0,苹果终于宣布 Swift 的 ABI 稳定。这标志着 Swift 这门语言已经趋于稳定,在 2019 至 2020 的迭代中,Swift 5.2 也做到了模块稳定,之前的大修大改已经不会在出现了。

image.png

有意思的是,在 WWDC16 中有一页 PPT 写下了 Goals for Swift 3:

  • Develop an open community
  • Portability to new platforms
  • Get the fundamentals right
  • Optimize for awesomenss

如今已经 2020 年,再回头看这些目标,Swift 5.3 几乎完全实现了。Swift 可谓一直不忘初心,朝着认为正确的方向不断的努力。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师星志。
更多精彩内容可关注【淘系技术】公众号。)

语法的不断成熟

每年 WWDC 比较期待的一个点就是看看 Swift 又加了一些什么新奇爽快的语法。我先列举一下 Swift 5.3 新增的语法:

  • [SE-0249] KeyPath as Function
  • [SE-0279] Multiple trailing closure
  • [SE-0281] Type-based program entry point (@main))
  • [SE-0266] Synthesized comparable conformation for enum types
  • [SE-0269] Increased availability of implicit self in closure
  • [SE-0276] Multi-pattern catch clauses
  • [SE-0280] Enum cases as protocol witnesses
  • [SE-0267] Where clauses on contextually generic declarations
  • [SE-0270] Collection operations on noncontiguous elements
  • [SE-0264] Standard library preview package
  • [SE-0253] Callable values of user-defined nominal types
  • [SE-0263] String initializer with access to uninitialized storage

上面列举的 12 个语法改动,有兴趣的同学可以到 swift-evolution 去查看详细的内容。其中比较有意思的几个改动就是 [SE-279],[SE-281]和[SE-0269],我们来细细评味一下。

Design for SwiftUI

[SE-279] Multiple trailing closure 多重尾闭包这个新特性算是一个非常大的改动。这个特性的出现影响了 Swift 非常重要的地方,API 设计。先来几个官方的例子:

屏幕快照 2020-07-21 下午3.36.44.png

上面的代码中 2 的情况是经常出现的,尾闭包的含义就不够明确,以前最佳的方式应该为 3,但是两个闭包被套在一个小括号里,使得括号多重嵌套,可读性下降。为了解决这个问题,苹果使用了第 4 中方法--多重尾闭包。可以从代码看出可读性得到了很大的提升。

这一看似优雅的设计其实引入了很多语言的复杂度,有了这个特性你甚至可以写出类似下面的代码,看上去就像是创造了一个 if-else 语句,但其实它是一个函数。

屏幕快照 2020-07-21 下午3.49.07.png

这就对 SDK 的开发者提出了更高的要求,需要小心的使用这个特性来设计 API,防止这个特性被滥用导致代码的可读性下降,甚至造成歧义。苹果在 WWDC20 中也强调了这一点。

还有两个特性其实很简单,[SE-0281] 是 @main 来标记程序入口,[SE-0269] 是让开发者在特定的情况下不需要再写多余的 self.

苹果推出了这几个语言特性,就是为了让战略性的项目 SwiftUI 的 API 更加简洁明了。可以看下面的例子:

屏幕快照 2020-07-21 下午3.49.44.png

苹果也不是第一次为了 SwiftUI 改 Swift 的语法,[SE-0255] Implicit returns from single-expression functions 就是为了让 SwiftUI 的 body 不用写 return,强化 DSL 风格。

苹果为了 SwiftUI,推出了 functionBuilder 来实现 DSL 形式的代码;为了 SwiftUI,推出了许多让它更漂亮的语法特性;为了 SwiftUI,不惜为语言引入更多的复杂度。

下限低,上限高

Swift 的最初的设计方向就导致了它是一门下限很低上限很高,入门容易精通难,使用容易设计难的语言。它一系列的语法糖和语法设计,包括类型推断系统,都是让它成为十分亲民的语言,而它的一系列语法特性,让它在设计 API、SDK实现的时候其复杂程度也不亚于其他语言。

Swift is a general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. for iOS, iPadOS, macOS, watchOS, tvOS, and Linux.

---- Wikipedia

维基百科的后半部分可能有些局限了,但是前半部分说明了它是一门多编程范式的语言,Swift 可以支持 面向对象编程(OOP),面向协议编程(OPP),声明式编程(DP),函数式编程(FP),泛型编程(GP)。

Objective-C 已经发展了这么多年,如此成熟,为什么现在苹果要开始抛开它?Objective-C 本来就是生于一个面向对象编程范式起飞的一年,与 C++ 一样为了拓展 C 命令式编程范式而诞生的语言。当时 C 语言虽然也可以实现 OOP,但是语法设计成为了限制。在当代计算机编程语言研究演进下,出现了很多编程范式的新理论,如函数式编程,元编程等等,同样 OC 可以通过它的方式来实现,但是语言的冗杂和 OOP 的设计已经不能更好的表达这些概念,就犹如纯 C 来表达OOP 一样。

苹果推出 Swift 就是为了摆脱 OC 的束缚,让它能更好的践行现代的编程理论,所以才会诞生出 SwiftUI,才会有 Combine、map/filter/reduce 等这些库和 API。类型推断和元编程的理论也让 Swift 在保留强类型的环境下还能保持如此简洁优雅,可读性强的代码。而这些是 OC 无法做到的。尝试使用 OC 对这些现代概念做表达的 SDK 都会显得十分冗杂。

现在 Swift 语法已经不会再大变,有如此现代、安全、稳定、富有想象力的语言,有什么理由不真香呢?

土壤已经肥沃

我们先通过下面的脑图感受一下 Swift 更迭到 5.3 已经取得的成就。

image.png

现在 Swift 生态环境已经自成一派,有一套完整的工具链保证开发,有更独立的标准库让它可以自由迁移,包管理让丰富了它的 SDK,同时还具有 Native 语言的各种优势。在这么多年的发展中,它的能力已经触及到了 AI、Server、Mobile Device、FaaS,强大的标准库让它甚至可以当脚本语言使用。

Swift 如今已经不再孤立无援,开源让 Swift 变得生机勃勃,合理优雅的设计和开放的态度让全球的开发者们都在不断的完善它。

在 Swift 的大生态中,包管理工具是最值得一说的。一门语言它的能力,取决于它是否有强有力的 SDK,还有就是获取他们的途径。基础的 Swift 的能力都由工具链和标准库提供,而强有力的 SDK 最好的方式就是通过包管理工具快速获取。Swift Package Manager 就是 Swift 的军械库。

Swift Package Manager

看一下 Swift Package Manager(SPM) 的发展历程,SPM 从 Swift 3.0 时就发布,当时只支持 Git 远端仓库,支持支源码发布。WWDC 19,Xcode 引入了一个新的架构 XCFramework,一个旨在能打包多个平台 framework 的文件结构。WWDC20 SPM 宣布正式支持发布二进制 framework。

WWDC20 SPM 走出的这一步标志着功能的完善。为什么这么说,因为在 iOS 届,解决了 Xcode 无包管理工具难题,让众多优秀的开源库能被快速获取的包管理工具 -- Cocoapods。在 SPM 出现之前,Cocoapods 的功能已经非常完善,打败了当时另外的一款包管理工具 Carthage。

Cocoapods 作为基于 Xcode 开发的第三方包管理工具,通过修改 Xcode 的工程信息来实现处理各个包的依赖问题。它支持依赖的二进制分发、源代码分发,基于 framework 良好的资源管理。现在许多公司的大型 App 也是用 Cocoapods 做模块化组件分离,通过二进制依赖的方式来提高打包速度。

然而比较可惜的是它工作流是脱离 Xcode 的,Podfile 更新等操作都是在工程之外。语言使用的是 Ruby,虽然使用了一些操作使 Podfile 变成了 DSL,但是对于开发者而言是有一定门槛的,特别是需要编辑发布 SDK 所使用的 podspec 时,对照文档,无代码提示的编写让写正确配置文件都成了难事。Cocoapods 还不得不设计出 podspec lint 来帮组开发者确认这个事情。

对于 Swift PM 这个亲儿子而言,就不存在这个问题,SPM 已经深入的集成到了 Xcode 中,所有的操作都可以利用 Xcode 完成。在编写 Swift Package 时,Xcode 现在已经具备将 Package.swift 作为工程项目打开,并且现在工程模板中已经包含了 Swift Package。强大的 Xcode 自动补全让编写 Package.swift 不再是一件难事。如果脱离 Xcode,利用 swift-lsp 结合现在热门的文本编辑器,如 VSCode 等都可以实现相应的功能。SPM 现在已经是独立于 Xcode 的存在,可以为 Swift 提供强有力的支持。

SPM 在功能层面已经不逊于 Cocoapods,在 WWDC20 时,SPM 已经支持以二进制库形式分发 Package,SPM 也可以管理包中的资源和本地化,基本的能力已经与 Cocoapods 差异不大,然而最关键的是,SPM 是纯 Swift ,开源,还有苹果官方支持的包管理工具。

新瓶酿酒酒更香

国外的不少 APP 已经迁移到了 Swift;三方开源库如 AFNetworking 已经用 Swift 重写为 Alamofire,Lottie 已经完全被 Swift 重写替代。苹果也推出了许多 Swift Only 的库。苹果也在利用 Swift 为 UIKit,GCD 等基础库不断提供更具有表现力的 API。

Uber 完成了迁移,收获了 Swift 极强的稳定性。Alamofire,SnapKit 用  Swift 重写,获得了更加具有表现力的 API,开发者更容易接受且喜爱。 Reactive 系列的编程风格在 Swift 上大放异彩。

机会与展望

现在 Swift 发展了这么多年,遍地开花,Objective-C 已经有在逐渐被废弃的趋势。现在很有可能都很难招到认真学习过 OC 的应届生了。

Swift 在集团内部的发展,还有很多的工作要做,这其中充满了挑战。我们也在积极探索 Swift 在手淘的落地,取得了 Swift 5.1 能模块在手淘中正确运行起来的阶段性成就。但是比较遗憾的是还有很多模块是无法让 Swift 正确跑起来的,以现在的工具链来说甚至源码依赖调试都无法做到。

但是这都是暂时的,现在时机已经成熟,Swift的语言特性,SPM,工具链,标准库都已经足够强大。未来,我们会尽快大力升级 Swift 的基建。让 Swift 的花在集团内开起。先定个小目标,希望 Swift 能成为集团 iOS 客户端开发的首选语言。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师星志。
更多精彩内容可关注【淘系技术】公众号。)

参考

  1. SwiftUI 背后那些事儿
  2. WWDC20 What's new in Swift
  3. WWDC19 What's new in Swift
  4. WWDC18 What's new in Swift
  5. WWDC17 What's new in Swift
  6. WWDC16 What's new in Swift)
  7. WWDC20 Swift packages: Resources and localization
  8. WWDC20 What's new in SwiftUI
  9. Swift 5 时代的机遇与挑战到底在哪里?
  10. Swift Evolution

淘宝基础平台团队正在进行社招招聘,岗位有iOS Android客户端开发工程师、欢迎 转岗推荐, 简历投递:junzhan.yzw@taobao.com

查看原文

赞 6 收藏 1 评论 0

阿里巴巴淘系技术 发布了文章 · 7月20日

Metal新特性:大幅度提升iOS端性能

前言

Metal 是一个和 OpenGL ES 类似的面向底层的图形编程接口,通过使用相关的 api 可以直接操作 GPU ,最早在 2014 年的 WWDC 的时候发布。Metal 是 iOS 平台独有的,意味着它不能像 OpenGL ES 那样支持跨平台,但是它能最大的挖掘苹果移动设备的 GPU 能力,进行复杂的运算,像 Unity 等游戏引擎都通过 Metal 对 3D 能力进行了优化, App Store 还有相应的运用 Metal 技术的游戏专题。

阿里巴巴淘系技术部的闲鱼团队是比较早在客户端侧选择Flutter方案的技术团队,当前的闲鱼工程里也是一个较为复杂的Native-Flutter混合工程。作为一个2C的应用,性能和用户体验一直是闲鱼技术团队在开发中比较关注的点。而Metal这样的直接操作GPU的底层接口无疑会给闲鱼技术团队突破性能瓶颈提供一些新的思路。

下面会详细阐述一下这次大会Metal相关的新特性,以及对于闲鱼技术和整个淘系技术来说,这些新特性带来了哪些技术启发与思考。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师岑彧。
更多精彩内容可关注【淘系技术】公众号。)

Metal相关新特性

1.Harness Apple GPUs with Metal

这一章其实主要介绍的是Apple GPU的在图形渲染上的原理和工作流,是一些比较底层的硬件原理。当我们使用Metal进行App或者是游戏的构建的时候,Metal会利用GPU的tile-based deferred rendering (TBDR)架构给应用和游戏带来非常可观的性能提升。这一章主要就是介绍GPU的的架构和能力,以及TBDR架构进行图像渲染的原理和流程。总之就是号召开发者们使用Metal来构建应用和游戏。因为这个session没有涉及到上层的软件开发,就不对视频的具体内容进行赘述了。详情可见:Harness Apple GPUs with Metal

2.Optimize Metal apps and games with GPU counters

这一章主要介绍了Xcode中的GPU性能分析工具Instrument,这个工具现在已经支持了GPU的性能分析。然后从多个方面分析了GPU的性能瓶颈,以及性能瓶颈出现时的优化点。总体来说就是通过性能分析工具来优化我们的App或者游戏,让整个画面更加流畅。整个章节主要分为五个部分:

1.总体介绍

这个环节主要是快速回顾了一下Apple的GPU的架构和渲染流程。然后因为很多渲染任务都需要在不同的硬件单元上进行,例如ALU和TPU。他们对不同的吞吐量有着不同的度量。有很多GPU的性能指标需要被考虑,所以推出了GPU性能计数器。这个计数器可能测量到GPU的利用率,过高和过低都会造成我们的渲染性能瓶颈。关于计数器的具体使用,参考官方的video效果会更好:Optimize Metal apps and games with GPU counters(6:37~9:57),主要使用了Instrument工具,关于工具的全面详细的使用可以参考WWDC19的session videoGetting Started with Instruments

2.性能瓶颈分析

这一章主要介绍了造成GPU性能瓶颈的各个方面以及它们的优化点。主要分为六个方面,如下图所示:

1.Arithmetic(运算能力)

GPU中通常通过ALU(Arithmetic Logic Unit)来处理各种运算,例如位操作,关系操作等。他是着色器核心的一部分。在这里一些复杂的操作或者是高精度的浮点运算都会造成一些性能瓶颈,所以给出以下建议来进行优化:

如上图所示,我们可以使用近似或者是查找表的方式来替换复杂的运算。此外,我们可以将全精度的浮点数替换为半精度的浮点数。尽量避免隐式转换,避免32位浮点数的输入。以及确保所有的着色器都使用Metal的“-ffast-math”来进行编译。

2.Texture Read and Write

GPU通过Texture Processing Unit来处理纹理的读写操作。当然在读写的过程中也会遇到一些性能瓶颈问题。这里从读和写两个部分分别来给出优化点:

1.Read

如上图所示,我们可以尝试使用mipmaps。此外,可以考虑更改过滤选项。例如,使用双线性代替三线性,降低像素大小。确保使用了纹理压缩,对Asset使用块压缩(如ASTC),对运行时生成的纹理使用无损纹理压缩。

2.Write

如上图所示,我们应该注意到像素的大小,以及每个像素中唯一MSAA样本的数量。此外,可以尝试一些优化一些逻辑写法。

3.Tile Memory Load and Store

图块内存是一组存储Thread Group和ImageBlock数据的高性能内存。当从ImageBlock或是Threadgroup读取或写入像素数据时,比如在使用Tile着色器时或者是计算分派时,可以访问到Tile内存。那当使用GPU性能计数器发现这个方面的性能瓶颈时,我们可以如下图所示进行优化。

考虑减少threadgroup的并行,或者是SIMD/Quadgroup操作。此外,确保将线程组的内存分配和访问对齐到16字节。最后,可以考虑重新排序内存访问模式。

4.Buffer Read and Write

在Metal中,缓冲区只被着色器核心访问。在这个地方发现了性能瓶颈。我们可以如下图所示进行优化:

可以更大力度的压缩打包数据,例如使用例如packed_half3这样小的类型。此外,可以尝试向量化加载和存储。例如使用SIMD类型。避免寄存器溢出,以及可以使用纹理来平衡工作负载。

5.GPU Last Level Cache

如果在这个方面,我们的GPU性能计数器显示一个过高的值。我们可以如下图这样优化:

如果纹理或者是缓存区也同样显示一个过高的值,我们可以把这个优化放到第一优先级。我们可以考虑减小工作集的大小。如果Shader正在使用Device Atomics,我们可以尝试重构我们的代码来使用Threadgroup Atomics。

6.Fragment Input Interpolation

分段输入插值。分段输入在渲染阶段由着色器核心进行插值。着色器核心有一个专用的分段输入插值器。这个是比较固定和高精度的功能。我们能优化的点不多,如下图所示:

尽可能的移除传递给分段着色器的顶点属性。

3.内存带宽

内存带宽也是影响我们GPU性能的一个重要因素。如果在GPU性能计数器的内存带宽模块看到一个很高的值。我们就应该如下图所示来进行优化:

如果纹理和缓存区也同样显示比较高的值,那优化优先级应该排到第一位。优化方案也是较少Working Set的大小。此外,我们应该只加载当前渲染过程需要的数据,只存储未来渲染过程需要的数据。然后就是确保使用纹理压缩。

4.Occupancy

如果我们看到整体利用率比较低,这意味着Shader可能已经耗尽了一些内部资源,比如tile或者threadgroup内存。也可能是线程完成执行的速度比GPU创建新线程的速度快。

5.避免重复绘制

我们通过GPU计数器可以统计到重复绘制的区域,我们应该高校使用HSR来避免这样的重绘。我们可以如图所示的顺序来进行绘制。

3.Build GPU binaries with Metal

这一章主要给开发者们介绍了一种使用Metal的编程工作流,可以通过优化Metal的渲染编译模型来增强渲染管线,这个优化可以在应用程序启动,特别是首次启动时大大减少PSO(管线状态对象)的加载时间。可以让我们的图形渲染更加的高效。整个章节主要分为四个部分:

1.Metal的Shader编译模型概述

众所周知,Metal Shading Language是Apple为开发者提供的Shader编程语言,Metal会将编程语言编译成为一个叫做AIR的中间产物,然后AIR会在设备上进一步编译,生成每个GPU所需的特定的机器码。整个过程如下图所示:

上述过程在每个管线的生命周期中都会发生,当前Apple为了加速管线的重新编译和重新创建流程,会缓存一些Metal的方法变体,但是这个过程还是会造成屏幕的加载耗时过长。而且在当前的这个编译模型中,应用程序不能在不同的PSO(管线状态对象)中重用之前生成的机器码子程序。
所以我们需要一种方法来减少这个整个管线编译(即源代码->AIR->GPU二进制代码)的时间成本,还需要一种机制来支持不同PSO之间共享子程序和方法,这样就不需要将相同的代码多次编译或者是多次加载到内存中。这样开发者们就可以使用这套工具来优化App首次的启动体验。

2.Metal二进制文件介绍

Metal二进制文件就是解决上述需求的方法之一,现在开发者们可以直接使用Metal为二进制文件来控制PSO的缓存。开发者可以收集已编译的PSO,然后将它们存储到设备中,甚至可以分发到其他兼容的设备中(同样的GPU和同样的操作系统),这种二进制文件可以看做一种Asset。下面是一些例程和示意图:

屏幕快照 2020-07-20 上午9.53.14.png

屏幕快照 2020-07-20 上午9.53.53.png

屏幕快照 2020-07-20 上午9.53.53.png

屏幕快照 2020-07-20 上午9.54.31.png

总的来说就是这个Metal二进制文件可以提供开发者手动管理管线缓存的方法,这样就可以从一个设备中获取这些文件并部署到其他兼容的设备上,在iOS环境下,极大地减少了第一次安装游戏或应用以及设备重启后的管道创建时间。可以优化应用的首次启动体验和冷启动体验。

3.Metal对动态库的支持

动态库将允许开发者编写可重用的库代码,却可以减少重新编译程序的时间和内存成本,这个特性将会允许开发者将计算着色器和程序库动态链接。而且和二进制文件一样,动态库也是可序列化和可转移的。这也是解决上述需求的方案之一。
在PSO生成的时候,每个应用程序都需要为程序library生成机器码,而且使用相同的程序库编译多个管线会导致生成重复的机器码。由于大量的编译和内存的增加,这个可能会导致更长的管线加载时间。而动态库就可以解决这个问题。
Metal Dynamic Library允许开发者以机器码的形式动态链接,加载和共享工具方法。代码可以在多个计算管线中重用,消除了重复编译和多个相同子程序的存储。而且这个 MTLDynamicLibrary是可序列化的,可以作为应用程序的Asset使用。MTLDynamicLibrary其实就是多个计算管线调用的导出方法的集合。
大致的工作流程如下:我们首先创建一个MTLLibrary作为我们指定的动态库,这个可以将我们的metal代码编译为AIR。然后我们调用方法makeDynamicLibrary,这个方法需要指定一个唯一的installname,在管线创建时,linker将会使用这个名字来加载动态库。这个方法可以将我们的动态库编译成为机器码。这就完成了动态库的创建。
对于动态库的使用来说:通过设置MTLCompileOptions里的libraries参数,就可以完成动态库的加载和使用了。代码如下:

屏幕快照 2020-07-20 上午10.04.56.png

4.开发工具介绍

这个部分主要介绍了构建Metal二进制文件和构建动态库的具体工具和方法。以视频的形式可能会更好的表现,详情可见:Build GPU binaries with Metal (从22:51开始)

4.Debug GPU-side errors in Metal

这一章主要介绍的是GPU侧的bug,当前如果我们的应用程序出现了GPU侧的bug,他的错误日志常常都不能让开发者很直观的定位到错误的代码范围和调用栈。所以在最新的Xcode中,增强了关于GPU侧的debug机制。可以像在代码侧发成的错误一样不但能定位到错误原因,还有错误的调用堆栈和各种信息都可以详细的查看到。让开发者能更好的修复代码造成的GPU侧的渲染错误。

1.Enhanced Command Buffer Errors

这是当前的错误日志上报,我们可以看到GPU侧的错误日志不像Api的错误日志一样可以让开发者很快的定位到错误原因和错误的代码位置。

而最新的Metal debugging工具就增强了这方面的能力,让Shader的code也可以像Api代码一样提供错误定位和分类能力。

我们通过以下代码便可以启用增强版的commandbuffer错误机制

屏幕快照 2020-07-20 上午10.05.27.png

错误一共有五种状态:

我们也可以通过以下代码来打印error:

屏幕快照 2020-07-20 上午10.06.00.png

开发者可以在开发时和测试时启用优化版的错误机制

2.Shader Validation

如上图所示,这个功能可以在GPU侧发生渲染错误时自动定位和catch到错误并定位到代码,以及获取回溯栈帧。

我们可以在Xcode中按照以下流程来开启这个功能:

1.开启Metal中的两个Validation选项

2.开启issue自动断点开关并配置类型和分类等选项

Video中用了一个demo来展示整个工作流,具体参见Debug GPU-side errors in Metal(11:25~14:45)大致流程如下图所示:

这是一个Demo应用程序,很明显它在渲染上出现了一些异常,但是因为是GPU侧的问题,所以开发者很难定位。但是通过上述的工作流开启Shader Validation之后。

Xcode会自动断点到发生异常的地方,并展示出异常信息,这样就可以极大的提升开发者的错误修复效率。

5.Gain insights into your Metal app with Xcode 12

这一章主要讲的是Xcode12给Metal App提供了更多调试和分析的新工具。大致如下图所示:

主要分为两个部分:

1.Metal Debugger

这个工具可以让开发者在App运行时,获取到想分析和调试的任何一帧,然后再进入Xcode提供的各种分析界面,总体情况,依赖情况,内存,带宽,GPU,Shader等各种具体的界面来对这一帧进行更加详细的分析和调试。整个过程使用视频的方式可能会更加高效,所以这里不会进行详细的赘述和分析。详情可以参见Gain insights into your Metal app with Xcode 12

2.Metal System Trace

整个工具跟之前提到过的Debugger相比,他的功能主要是让开发者可以随着时间的推移来捕获应用程序的各种信息和特征,可以让开发者很好的调试一些例如终端,帧丢失,内存泄漏等问题。而Debugger主要是对某一帧进行调试和分析。
他提供了一个叫做编码时间线的工具,可以让开发者查看到GPU在应用运行中的运行各种命令缓冲的情况。然后提供了一个叫做着色器时间线的工具,可以让开发者查看到各种着色器在代码运行期间运行的过程。然后还有GPU计数器的工具,这个工具我们在前文进行了详细的分析,主要是用于解决GPU的绘制性能问题的工具。然后最后一个工具就是内存分配跟踪工具,可以让开发者查看到应用程序运行过程中各种内存的分配和释放,可以帮助开发者解决内存泄漏问题或者是降低应用内存占用。

技术启发与思考

WWDC 20关于Metal的Session中,比较重要的就是官方提供了很多可供开发者进行GPU级别的调试工具以及性能分析工具。给比较成熟庞大而复杂的工程突破性能瓶颈,提供更加优秀的用户体验提供了一些思路。

闲鱼作为一个电商类App,随着功能和增多和以及工程的复杂化,在所难免的会遇到性能瓶颈,而闲鱼团队当前面对挑战的方式是从工程级别来进行优化。从Flutter的角度来看,WWDC 20 对于Metal的调试工具和性能分析工具的完善,无疑提供了更多的优化思路。这为未来运行在iOS上的应用的调优和突破性能瓶颈带来了新的思路和可能性。

对于跨平台框架,Apple有自家的SwiftUI,这也是此次大会的重点项目。不过无论是Flutter,还是SwiftUI,大家最后对应用的性能瓶颈突破和优化一定是殊途同归的,也就是深入到GPU级别来进行开发和调试以及性能分析。对于未来的客户端开发人员,理解GPU和进行GPU级别的编程肯定是不可或缺的技能点之一。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师岑彧。
更多精彩内容可关注【淘系技术】公众号。)

查看原文

赞 4 收藏 1 评论 0

阿里巴巴淘系技术 赞了文章 · 7月16日

Twitter 帐户遭到比特币骗局攻击,比尔盖茨、马斯克、奥巴马等账号悉数被窃取

clipboard.png
技术编辑:徐九丨发自 思否编辑部

“在接下来的 30 分钟内,只要你往这个数字钱包地址打钱,我就返给你双倍金额。大家都让我回报社会,现在时候到了!”

今天凌晨,比尔盖茨、埃隆·马斯克、杰夫·贝佐斯、巴拉克·奥巴马、乔·拜登、坎耶·韦斯特、苹果官方账号等等大佬的推特,不约而同的发了类似内容的 Twitter,真的如推特内容所言,早起的鸟儿有虫吃?大佬们要回馈社会了么?

答案当然是否定的,这是一起黑客入侵事件,背后是一场比特币骗局。

Twitter 安全漏洞

这些推文内容都是由黑客在窃取了目标账号之后,批量发布的。业内安全专家表示,这次的事件问题是由 Twitter 服务的安全漏洞引起的,而不是由目标人群自身的风险行为导致。

Facebook 前首席安全官亚历克斯·斯塔莫斯说,研究人员目前普遍认可的一个理论是,黑客已经获得了该系统的加密密钥,从而使他们能够从本质上窃取授予个人帐户访问权限的“令牌”。他认为所有理论都表明,黑客是进入了 Twitter 的系统,而不是窃取单个用户的密码。

这些推文在发布几分钟后便被删除,Twitter 官方也表示采取了特殊的设置,限制了很多蓝V账号的发推权限。但据社交媒体显示,大部分账号仍然被发布推文,并且无法重置账号密码。

根据公开可用的区块链记录,目标账户推文中显示的链接已经收到了数百笔捐款,总计超过 100,000 美元(80,000 英镑)。

网络安全公司 CrowdStrike 的联合创始人德米特里·阿尔佩罗维奇在媒体采访中表示:“这似乎是社交媒体平台上最糟糕的一次黑客攻击。”

比尔·盖茨的发言人也表示:“这似乎是 Twitter 面临的更大问题的一部分。”

Twitter 首席执行官杰克·多尔西则表示,“这对我们来说是「艰难的一天」。我们都感到这件事发生的可怕。我们正在诊断,并会在我们对发生的事情有更全面的了解后分享我们所能提供的一切。”

黑客利用 Twitter 控制面板盗取账户

据两位接近地下黑客社区的消息人士称,黑客是利用了 Twitter 员工与用户账户进行交互的控制面板盗取了这些账户并发布了诈骗信息。

witter 员工与用户账户进行交互的控制面板

目前,Twitter 已经删除了流传出去的控制面板截图,并以内容违反公司规则的原因封禁了传播这张图片的用户。

code面板对被​​黑帐户之一BINANCE的访问/code

知名人士 Twitter 账户被盗取也引起了美国政府方面的重视,事件发生仅一小时后,共和党参议员 Josh Hawley 就致信 Twitter 首席执行官 Jack Dorsey 询问黑客攻击是否影响了美国总统特朗普的账户,并要求 Twitter 提供此次黑客攻击事件的更多信息,包括黑客攻击的方式、信息泄露的用户数量等。

对此,Jack Dorsey 表示,“正在评估黑客入侵情况,将在可能的情况下公布更多信息。”

此前也发生过类似的事件

“翻倍返还比特币”的骗局操作,多年来 Twitter 上时有发生,但类似这次大量公众人物账号被劫持的事件是前所未有的。

去年,Twitter 首席执行官杰克·多尔西(Jack Dorsey)的帐户就曾被黑客入侵,但该公司表示已修复了使他的帐户容易受到攻击的漏洞。

此次众多不同用户同时遭到入侵的事实表明,Twitter 平台本身可能仍然存在很大的问题。

万幸的是这次黑客并没有利用他们的访问权瞄准任何重要的机构或基础设施,而是索要比特币。但此次事件表明,他们有能力造成更大的破坏。

据业内专家表示,目前没有证据表明是谁发动了袭击。但根据美国情报机构进行的初步评估,认为这很可能是单个黑客的工作,而不是某个国家的政治行为。

clipboard.png

查看原文

赞 4 收藏 0 评论 0

阿里巴巴淘系技术 发布了文章 · 7月16日

iOS14 隐私适配及部分解决方案

背景

Trust is built over time, and starting out by showing respect for users data by asking for access to as little as possible is a great first step.
  • 在刚刚结束的线上 WWDC 2020 发布会上苹果向我们展示了新的 iOS14 系统。
  • iOS14 的适配,很重要的一环就集中在用户隐私和安全方面。在 iOS13 及以前,当用户首次访问应用程序时,会被要求开放大量权限,比如相册、定位、联系人,实际上该应用可能仅仅需要一个选择图片功能,却被要求开放整个照片库的权限,这确实是不合理的。对于相册,在 iOS14 中引入了 “Limited Photos Library” 的概念,用户可以授予应用访问其一部分的照片,对于应用来说,仅能读取到用户选择让应用来读取的照片,让我们看到了 Apple 对于用户隐私的尊重。
  • 这仅仅是一部分,在 iOS14 中,可以看到诸多类似的保护用户隐私的措施,也需要我们升级适配。
  • 最近在调研 iOS14 的适配方案,本文主要分享一下 iOS14 上对于隐私授权的变更和部分适配方案,欢迎补充指正。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师岚遥。
更多精彩内容可关注【淘系技术】公众号。)

适配点

相册

  • iOS14 新增了“Limited Photo Library Access” 模式,在授权弹窗中增加了 Select Photo 选项。用户可以在 App 请求调用相册时选择部分照片让 App 读取。从 App 的视角来看,你的相册里就只有这几张照片,App 无法得知其它照片的存在。
  • iOS14 中当用户选择“PHAuthorizationStatusLimited” 时,如果未进行适配,有可能会在每次触发相册功能时都进行弹窗询问用户是否需要修改照片权限。
  • 对于这种情况可通过在 Info.plist 中设置 “PHPhotoLibraryPreventAutomaticLimitedAccessAlert” 的值为 YES  来阻止该弹窗反复弹出,并且可通过下面这个 API 来主动控制何时弹出 PHPickerViewController 进行照片选择。

屏幕快照 2020-07-16 下午2.42.21.png

  • 在 iOS14 中官方推荐使用  PHPicker 来替代原 API 进行图片选择。PHPicker 为独立进程,会在视图最顶层进行展示,应用内无法对其进行截图也无法直接访问到其内的数据。
  • UIImagePickerController  -> PHPickerViewController, UIImagePickerViewController 功能受限,每次只能选择一张图片,将逐渐被废弃。
  • PHPicker 支持多选,支持搜索,支持按 image,video,livePhotos 等进行选择。
  • 新API及迁移demo:

屏幕快照 2020-07-16 下午2.43.54.png
屏幕快照 2020-07-16 下午2.44.06.png

  • 需要注意的是,在 limit Photo 模式下,AssetsLibrary 访问相册会失败;在 writeOnly 模式下,AssetLibrary 也会有显示问题。建议还在使用 AssetsLibrary 的同学尽快迁移到新 API。
  • 授权相关:旧 API 废弃,增加 PHAccessLevel 参数。如果再使用以前的API来获取权限状态,PHAuthorizationStatusLimited 状态下也会返回 PHAuthorizationStatusAuthorized

屏幕快照 2020-07-16 下午2.45.53.png
屏幕快照 2020-07-16 下午2.46.01.png

定位

  • 在 iOS13 及以前,App 请求用户定位授权时为如下形态:一旦用户同意应用获取定位信息,当前应用就可以获取到用户的精确定位。
  • iOS14 新增用户大致位置选项可供用户选择,原因是大多数 App 实际上并不需要获取用户到用户最准确的定位信息。iOS14 授权弹窗新增的 Precise的开关默认会选中精确位置。用户通过这个开关可以进行更改,当把这个值设为 On 时,地图上会显示精确位置;切换为Off时,将显示用户的大致位置。
  • 对于对用户位置敏感度不高的 App 来说,这个似乎无影响,但是对于强依赖精确位置的 App 适配工作就显得非常重要了。可以通过用户在 “隐私设置” 中设置来开启精确定位,但是可能用户宁可放弃使用这个应用也不愿意开启。这个时候,iOS14 在 CLLocationManager 新增两个方法可用于向用户申请临时开启一次精确位置权限。
    使用方式也很简单,需要首先在 Info.plist 中配置“NSLocationTemporaryUsageDescriptionDictionary”字典中需要配置 key 和 value 表明使用位置的原因,以及具体的描述。
    在本例中,key 即为获取用户权限时传的 "purposeKey",最终呈现给用户的就是左图,右图为当App主动关闭精确定位权限申请。
  • 对于地理位置不敏感的App 来说,iOS14 也可以通过直接在 info.plist 中添加 NSLocationDefaultAccuracyReduced  为 true 默认请求大概位置。
  • 这样设置之后,即使用户想要为该 App 开启精确定位权限,也无法开启。
  • 也可以直接通过API来根据不同的需求设置不同的定位精确度。
  • 需要注意的是,当 App 在 Background 模式下,如果并未获得精确位置授权,那么 Beacon 及其他位置敏感功能都将受到限制。

Local Network

  • iOS14 当 App 要使用 Bonjour 服务时或者访问本地局域网,使用 mDNS 服务等,都需要授权,开发者需要在 Info.plist 中详细描述使用的为哪种服务以及用途。下图为需要无需申请权限与需要授权的服务:
  • 在 "隐私设置" 中也可以查看和修改具体有哪些 App 正在使用 LocalNetwork  
  • 如果应用中需要使用 LocalNetwork 需要在 Info.plist 中配置两个选项,详细描述为什么需要使用该权限,以及需要列出具体使用 LocalNetwork 的服务列表。
  • 对于使用了下列包含 Bonjour 的 framework,都需要更新描述

Wi-Fi Address

  • iOS8 - iOS13 ,用户在不同的网络间切换和接入时,mac 地址都不会改变,这也就使得网络运营商还是可以通过 mac 地址对用户进行匹配和用户信息收集,生成完整的用户信息。iOS14 提供 Wifi 加密服务,每次接入不同的 WiFi 使用的 mac 地址都不同。每过 24 小时,mac 地址还会更新一次。需要关注是否有使用用户网络 mac 地址的服务。
  • 下图为 iOS13 及之前用户接入网络时 mac 地址并不会进行改变
  • 下图为 iOS14 用户接入 Wi-Fi 时 mac 地址的变化情况
  • 并且用户也可以自行选择是否开启 private Wi-Fi address

剪切板

  • 在 iOS14 中,读取用户剪切板的数据会弹出提示。
  • 弹出提示的原因是使用 UIPasteboard 访问用户数据,访问以下数据都会弹出 toast 提示。
  • 兼容方案:如果应用访问剪切板仅仅用于判断是否为URL格式,则 iOS14 新增了两个 API 可以用于规避该提示。如果应用想直接访问剪切板的数据,暂时可能无法做到规避该提示。 iOS14 新增两种 UIPasteboardDetectionPattern。
  • 上面的两个 API 可用于规避提示,但只能用于判断剪切板中是否有 URL,并不是真正的访问剪贴板数据,也拿不到剪切板的真实数据。下面两个 API 可以获得具体的 URL 信息,但是会触发剪切板提示。并且实测当用户剪切板中包含多个 URL 时只会返回第一个。
  • 使用示例

屏幕快照 2020-07-16 下午2.47.30.png

相机和麦克风

  • iOS14 中 App 使用相机和麦克风时会有图标提示以及绿点和黄点提示,并且会显示当前是哪个 App 在使用此功能。我们无法控制是否显示该提示。
  • 会触发录音小黄点的代码示例:

屏幕快照 2020-07-16 下午2.48.07.png

  • 触发相机小绿点的代码示例:

屏幕快照 2020-07-16 下午2.48.14.png

IDFA

  • IDFA 全称为 Identity for Advertisers ,即广告标识符。用来标记用户,目前最广泛的用途是用于投放广告、个性化推荐等。
  • 在 iOS13 及以前,系统会默认为用户开启允许追踪设置,我们可以简单的通过代码来获取到用户的 IDFA 标识符。

屏幕快照 2020-07-16 下午2.49.28.png

  • 但是在 iOS14 中,这个判断用户是否允许被追踪的方法已经废弃。
  • iOS14 中,系统会默认为用户关闭广告追踪权限。
  • 对于这种情况,我们需要去请求用户权限。首先需要在 Info.plist 中配置" NSUserTrackingUsageDescription " 及描述文案,接着使用 AppTrackingTransparency 框架中的 ATTrackingManager 中的 requestTrackingAuthorizationWithCompletionHandler 请求用户权限,在用户授权后再去访问 IDFA 才能够获取到正确信息。

屏幕快照 2020-07-16 下午2.49.40.png

上传 AppStore

  • 更加严格的隐私审核,可以让用户在下载 App 之前就知道此 App 将会需要哪些权限。目前苹果商店要求所有应用在上架时都必须提供一份隐私政策。如果引入了第三方收集用户信息等SDK,都需要向苹果说明是这些信息的用途。

总结

  • 对于这次 iOS14 的隐私权限大升级和新尝试,体现了苹果对于用户隐私的尊重。
  • 从用户角度来说,近年来越来越精准的广告投放让我们越来越感觉自己被”监视“着,此次升级后,我们有了更多保护自己隐私的方式以及避免广告骚扰的方法,苹果此举无疑会加大我们对其的好感度和信任感。
  • 但从另一个角度来说,对于 IDFA 的限制,可能会导致之前许多依靠广告投放收入的免费 App 难以继续维持生计,也可能也会导致免费 App 的数量有所降低。从开发者的角度来说,除了对 iOS14 隐私升级的积极适配外,也让我们感受到了 iOS14 中对于用户隐私的重视无疑会提高获取用户行为信息的成本。
  • 冲击最大的应该就是广告行业,对于目前的推荐算法和用户拉新都会受到影响,如何在充分尊重用户隐私的前提下进行广告的精准投放对于开发者和广告商来说都是一个不小的机遇和挑战。

参考资料

  • WWDC 2020 Apple Developer
  • Developer Documentation

广告

欢迎大家加入手淘客户端的小程序与跨平台技术部!我们是支撑小程序、小游戏、Flutter 等跨平台技术的核心团队,有技术广度和也有技术深度,我们需要 iOS、Android、C++、Flutter、Canvas、游戏引擎、WebGL 等各方面的人才。如果你善于学习,这是一个很好的接触跨领域知识的机会。如果你是个对技术有追求对小伙伴,请别犹豫,立刻联系我!lanya.sly@alibaba-inc.com

更多有关手淘的技术内容分享敬请关注VX公众号【淘系技术】

查看原文

赞 11 收藏 2 评论 0

认证与成就

  • 获得 41 次点赞
  • 获得 0 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 0 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 6月11日
个人主页被 2.5k 人浏览