11 dns优先级 ios

2018-01-02 16:49:00 weixin_33991727 阅读数 270

  iOS开发中,一般都是通过AFN搭建一个简易的网络模块来进行与服务器的通信,这一模块要优化好没那么简单,需要花费很多时间与精力,仅仅根据这几年来的填坑经验,总结下这一块的需要注意的地方,也是给自己梳理下知识。

  之前写的博客提到了DNS优化、请求数据大小的优化(http://www.cnblogs.com/ziyi--caolu/p/8058577.html)。这里主要想理一理合理的并发数以及网络请求可靠性的保障。

  优化的理论之前,先建立代码样例,假设我们有这样两个类:  

@interface ZYRequest : NSObject<NSCopying>

@end

@interface ZYRequestManager : NSObject

@end

   ZYRequest类用来处理公共的逻辑,Manager负责管理Request。在iOS开发中,很多时候会遇到多个Request集中发送的情况,比如说第一次进入App首页,需要请求骨架文件、首页Banner图片、展示Cell数据等等,如果这时候并发数太少,那些需要优先展示的数据请求可能会被次要的数据请求“阻塞”住。如果并发数太大,带宽有限的场景下,会增加请求的整体延迟。一般而言,在实际开发中,让请求的并发数限制在3~~5即可(也可以给每个请求设计优先级,然后在调度队列里面让优先级高的请求先出队列)。

  请求的可靠性保障是个很容易被忽视的问题,见过的很多App的网络请求都是只进行一次请求,失败后直接给用户提示网络错误。比较好的做法,是将Request按业务分类:

    第一类,关键核心业务,期望在任何条件下能百分百送达服务器。

    第二类,重要的内容请求、数据展示,需要较高的成功率。

    第三类,一般性内容请求,对成功率无要求。

  理论上来说,需要我们应该尽量让每个请求的成功率都达到最高,但是客户端流量、带宽、电量、服务器压力等都是有限的资源,所以只能采取将关键性请求做高强度的可靠性保证。

    

    代码Github地址:https://github.com/wzpziyi1/iOSNetwork

    

  一、代码结构分析

    其中Storage文件夹里面,主要是处理将NSData数据缓存到沙盒的,实际我将它们的调用封装在ZYRequestCache文件里面,关于数据存储到沙盒、数据库,从沙盒取出数据、从数据库取出数据,删除、查询等等所有操作,都是封装在ZYRequestCache里面,直接调用它的接口即可。

    数据库采用的是realm数据库,并且实现了在子线程进行数据的存取,不占用主线程的资源,以免造成卡顿。由于是第一次使用realm,踩了很多坑。所有的关于数据库的操作,都封装在ZYRequestRealm文件里面,里面也有许多操作realm时踩过的坑的提示,最需要注意的一点是,在realm数据库的使用中,对同一份数据的读、写、查询后使用,都必须是在同一线程,在编码时由于将除查询操作外的其他数据库操作放在子线程中,造成了各种线程错误的崩溃。

    YQDHttpClinetCore文件是基于AFN的封装,在里面设置了超时时间为5s,主要是因为我设置的重发请求次数是3次,那么真正交互的超时时间会是15s,如果有需要可以自行进行调整。

    ZYRequest文件里面是所有发送一次请求所需要的数据,例如url\params\method\type等。

    ZYRequestManager文件里面是进行request调度的主题逻辑,也没有进行复杂的算法,不按照优先级别,只是一个先入先出队列来进行调用的。里面有两个dispatch_queue:

//这个串行队列用来控制任务有序的执行
@property (nonatomic, strong) dispatch_queue_t taskQueue;

//添加、删除队列,维护添加与删除request在同一个线程
@property (nonatomic, strong) dispatch_queue_t addDelQueue;

    taskQueue主要是用来处理调度队列的,也就是requestQueue,让它在子线程进行循环查询、处理request,然后再并发进行网络请求,这样可以防止请求很多的情况下,卡住主线程。

    addDelQeueu主要是用来处理requestQueue里面的requset增加与删除的。在添加和删除的时候,采用的方案都是串行+同步,主要是避免数据竞争。(因为在AFN发送request要删除requestQueue里面的request的时候,是并发状态)

    在处理最大并发数的时候,我使用的是dispatch_semaphore_t(信号量),设置最大并发数是4。

    逻辑并不复杂,需要注意的是,如何避免数据竞争,如何尽可能的不消耗主线程资源。 

 

  二、针对百分百送达服务器的请求  

    根据业务来说,这类请求应用的地方很多。类似于我们发微信发消息时,消息数据一旦从数据框中发出,从用户的角度感知这条消息是一定会到达对方的;在小说阅读App的书架收藏功能,理论上来说户收藏一本书时,在用户感知角度,这本书一定会被收藏进入书架的等业务。如果网络环境差,网络模块会在后台悄悄重试,一段时间仍然无法成功的话,就直接通知用户发送失败了,但是即使失败,请求数据也会保存在本地,以便用户重新触发此条请求数据的发送。

    对于这类请求的处理,第一步并不是直接发送,而是存入本地数据库中,一旦存入了数据库,即使是杀掉进程、断电、重启等极端操作,请求数据也依旧存在,我们只需要在App重启或者进入该业务界面时,还原请求数据到内存中,重新进行发送即可。代码阐释:

    

#import <Foundation/Foundation.h>
#import "ZYRequestMacro.h"
#import <Realm/Realm.h>



typedef NS_ENUM(NSInteger, ZYRequestReliability){

    //如果没有发送成功,就放入调度队列再次发送
    ZYRequestReliabilityRetry,
    
    //必须要成功的请求,如果不成功就存入DB,然后在网络好的情况下继续发送,类似微信发消息
    //需要注意的是,这类请求不需要回调的
    //类似于发微信成功与否
    //就是必定成功的请求,只需要在有网的状态下,必定成功
    ZYRequestReliabilityStoreToDB,
    
    //普通请求,成不成功不影响业务,不需要重新发送
    //类似统计、后台拉取本地已有的配置之类的请求
    ZYRequestReliabilityNormal
};


@interface ZYRequest : RLMObject<NSCopying>

//存入数据库的唯一标示
@property (nonatomic, assign) int requestId;

/**请求参数对*/
@property (nonatomic, strong) NSDictionary *params;


/**
 请求的url
 */
@property (nonatomic, copy) NSString *urlStr;

/**
 请求重复策略,默认重发
 */
@property (nonatomic, assign) ZYRequestReliability reliability;

/**
 请求方法,默认get请求
 */
@property (nonatomic, assign) YQDRequestType method;


/**
 是否需要缓存响应的数据,如果cacheKey为nil,就不会缓存响应的数据
 */
@property (nonatomic, copy) NSString *cacheKey;

/**
 请求没发送成功,重新发送的次数
 */
@property (nonatomic, assign, readonly) int retryCount;


/**
 realm不支持NSDictionary,所以params直接转化为字符串存储
 只在请求需要存入数据库中,此参数才有相应的作用
 ZYRequestReliabilityStoreToDB这种类型下
 */
@property (nonatomic, copy, readonly) NSString *paramStr;


- (void)reduceRetryCount;
@end

     第一类请求就是ZYRequestReliabilityStoreToDB,requestId是它存入数据库的唯一标示,下面是请求的发送流程:

    

- (void)sendRequest:(ZYRequest *)request successBlock:(SuccessBlock)successBlock failureBlock:(FailedBlock)failedBlock
{
    //如果是ZYRequestReliabilityStoreToDB类型
    //第一时间先存储到数据库,然后再发送该请求,如果成功再从数据库中移除
    //不成功再出发某机制从数据库中取出重新发送
    if (request.reliability == ZYRequestReliabilityStoreToDB)
    {
        [[ZYRequestCache sharedInstance] saveRequestToRealm:request];
    }
    
    [self queueAddRequest:request successBlock:successBlock failureBlock:failedBlock];
    [self dealRequestQueue];
}


//在成功的时候移除realm数据库中的缓存
 if (request.reliability == ZYRequestReliabilityStoreToDB)
{
    [[ZYRequestCache sharedInstance] deleteRequestFromRealmWithRequestId:request.requestId];
}

//请求失败之后,根据约定的错误码判断是否需要再次请求
                //这里,-1001是AFN的超时error
 if (error.code == -1001 &&request.retryCount > 0)
{
    [request reduceRetryCount];
    [self queueAddRequest:request successBlock:successBlock failureBlock:failedBlock];
    [self dealRequestQueue];
}
else  //处理错误信息
{
    failedBlock(error);
}

     如果是ZYRequestReliabilityStoreToDB请求,第一步是存入数据库。

    第二步,将请求添加到调度队列里面,让调度队列调用AFN去处理该请求。在AFN的成功block里面,判断状态码,如果是真的成功状态,那么将数据库里面的请求移除掉,如果是失败状态,将重新请求的次数递减,再添加到调度队列末尾重新排队请求。

    我设计的是,最多重发三次请求。另外还有一个定时器,这个定时器会每隔60s,从数据库查询需要所有存储的请求,然后将它们尝试加入调度队列再次发送。这样的设计,即使App被kill,再次重启60s之后,也会把数据库中的请求拿出来进行发送。(只是一种思路,实际开发中会进入到具体业务才讲请求拿出来发送)

    通过上面的几个步骤,基本上可以极大的提高请求的可靠性,但是真的100%是无法实现的,如果用户卸载App,再下载,相关数据就无法恢复了。

 

  三、失败重发

    第二类请求的可靠性为ZYRequestReliabilityRetry,这类请求的例子可以是我们App启动时用户看到的首页,首页的内容从服务器获取,如果第一次请求就失败体验较差,这种场景下我们应该允许请求有机会多试几次,增加一个retryCount即可。

/**
 请求没发送成功,重新发送的次数
 */
@property (nonatomic, assign, readonly) int retryCount;

     在Manager里面,有一个调度队列:

@property (nonatomic, strong) NSMutableArray *requestQueue;

     每次将请求加入这个队列,然后在AFN发送完成回调之后,如果失败就进行重发,实际开发时,需要自行处理失败重发的错误码判断:

//请求失败之后,根据约定的错误码判断是否需要再次请求
//这里,-1001是AFN的超时error
if (error.code == -1001 &&request.retryCount > 0)
{
    [request reduceRetryCount];
    [self queueAddRequest:request successBlock:successBlock failureBlock:failedBlock];
    [self dealRequestQueue];
}

     在这里,是设置如果超时才进行重发请求,也可以将这个判断去掉,只要retryCount大于0即进行重发。一般开发的时候会和后台确定一些错误码,根据错误码的类型判断是否需要重发会更合理些。

    一般3次的重试基本可以排除网络抖动的情况。三次失败之后即可认为请求失败,通过产品交互告知用户。

    第三类请求的重要性最低,比如进入Controller的UV采集打点、收集数据等。这类请求只需要做一次,即使失败也不会对App体验产生什么负面影响。

 

  四、设计思路

    这是某天在开发群里群友发出来的一道面试题,当一个复杂界面上的数据要根据n个请求返回的数据进行更新的时候,要求设计一个架构来发送这些请求。

    当时简单的和群友聊了聊,趁着最近有时间就自己撸了一套这样的机制,首先是疑问:

    1、为什么需要设计框架?所有请求直接利用AFN并发发送不行么?(不行,因为网络带宽是有限的,这样做会导致数据返回整体慢上很多,而且,一个网络请求的超时时间是一定的,一次性并发很可能造成本来可以发送成功的请求超时)

    2、基于问题1,架构如何设计?(个人认为,面试官主要是想考察对平时写代码对于封装、设计模式、网络回调的理解,如果仅仅只是一个最大并发的限制,明显不会是理想答案,那么需要注意的点?除开最大并发,开发中网络错误时,都有错误码返回,对这一块应该做好处理。当请求失败时,需不需要进行重发?请求之间需不需要设置依赖?需要不要有优先级等等)

 

    这一次的设计,并没有依赖、优先级等,只进行了重发、最大并发设计。思路是一样的,无非就是一个调度队列进行request的处理,这个队列的出队规则可以是按优先级高低来进行,当然得自己封装优先队列的算法。这里是最简单的先进先出队列,每次请求失败,要进行重发的话,就把请求丢到队列末尾。额,理论上来说,请求无限多的情况下,调度队列会是个死循环,这样会造成主线程卡顿,所以把它放到子线程来处理。在并发发送请求之下,不做处理的话,会并发的删除调度队列里面的request,那么如何避免数据竞争?在代码里面都有解答,以上。

 

2019-04-23 10:40:26 weixin_34259559 阅读数 35

最近对网络优化进行了一些研究,好些都没有去实践,所以做一个整理,以后慢慢研究

HTTP2.0

HTTP2.0新特性

  • 二进制分帧
  • 首部压缩
  • 多路复用
  • 服务器推送
  • 请求优先级

HTTP/2 新特性浅析
HTTP2.0原理详细分析
什么是HTTP2.0协议:HTTP2.0协议详解
HTTP 2.0 协议详解
HTTP/2 头部压缩技术介绍
HTTP/2笔记之帧
HTTP 1.1学习笔记

网络深度优化的点

  • NSCache缓存、Last-Modified、ETag
  • 失败重发、缓存请求有网发送
  • DNS解析
  • 数据压缩:protobuf,WebP
  • 弱网:2G、3G、4G、wifi下设置不同的超时时间
  • TCP对头阻塞:GOOGLE提出QUIC协议,相当于在UDP协议之上再定义一套可靠传输协议

NSCache缓存、Last-Modified、ETag
iOS网络缓存扫盲篇--使用两行代码就能完成80%的缓存需求

失败重发、缓存请求有网发送
iOS网络模块优化(失败重发、缓存请求有网发送)

DNS解析
HTTPDNS 在 iOS 中的实践
APP端的网络优化(DNS优化,HTTP优化)
iOS网络请求优化之DNS映射
可能是最全的iOS端HttpDns集成方案
NSURLProtocol 配hosts(内含例子)
Swift - 拦截Alamofire的网络请求(缓存请求结果,从缓存中读取数据)
移动解析HTTPDNS在App开发中实践总结
AFNetworking 原作者都无法解决的问题: 如何使用ip直接访问https网站?

弱网优化
海量之道系列文章之弱联网优化 (一)
海量之道系列文章之弱联网优化 (二)
海量之道系列文章之弱联网优化 (三)
海量之道系列文章之弱联网优化 (四)
海量之道系列文章之弱联网优化 (五)
海量之道系列文章之弱联网优化 (六)
海量之道系列文章之弱联网优化 (七)
移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”
移动端IM开发者必读(二):史上最全移动弱网络优化方法总结
弱网下移动端网络连接处理策略
iOS开发——实时监控网速

深度优化概述
携程App的网络性能优化实践
移动 APP 网络优化概述
深度优化iOS网络模块 iOS网络请求优化
《携程移动APP架构优化之旅》-陈浩然
移动端网络常见问题及优化对策
美团点评移动网络优化实践
无线性能优化:域名收敛 iOS网络优化
携程移动端架构演进与优化之路
App的网络测试中性能优化方案
URLSession如何动态控制并发数?
传输速度优化方案
58 同城 iOS 客户端网络框架的演进之路
IM 即时通讯技术在多应用场景下的技术实现,以及性能调优(iOS视角)
网络请求优化之取消请求
谈谈 iOS 网络层设计 百度App网络深度优化系列《一》DNS优化
百度App网络深度优化系列《二》连接优化 新 Uber 司机端是如何克服网络延迟问题 网络优化

2019-03-27 14:45:51 kaoa000 阅读数 2038

QoS优先级映射

  (2018-06-04 14:45:45)

不同的报文使用不同的QoS优先级,例如VLAN报文使用802.1p,IP报文使用DSCP,MPLS报文使用EXP。为了保证不同报文的服务质量,在报文进设备时,需要将报文携带的QoS优先级统一映射到设备内部的服务等级Service Class(也叫做调度优先级PHB)和丢弃优先级(也叫颜色Color),在设备内部,根据报文的服务等级进行拥塞管理,根据报文的颜色进行拥塞避免;在报文出设备时,需要将内部的服务等级和颜色映射为QoS优先级,以便后续网络设备能够根据QoS优先级提供相应的服务质量。QoS优先级映射

将QoS优先级映射到服务等级和颜色是在报文上行方向进行,而服务等级和颜色映射为QoS优先级则是在下行方向进行。

图1 QoS优先级映射QoS优先级映射
 

Service Class

Service Class是指报文在设备内部的服务等级,支持8种取值,优先级从高到低依次为CS7、CS6、EF、AF4、AF3、AF2、AF1、BE。Service Class决定了报文在设备内部所属的队列类型。

服务等级的高低取决于具体的队列调度算法配置:

  • 如果8种类型的队列都配置为PQ调度,则CS7>CS6>EF>AF4>AF3>AF2>AF1>BE;
  • 如果BE配置为PQ调度(一般不会这么配置),其余7种类型的队列配置为WFQ调度,则BE的优先级比其余7个都高;
  • 如果8种类型的队列都配置成WFQ调度,则相互之间无优先级高低之分。

 说明:

关于队列调度,请参见本文后面的介绍。

Color

Color是指报文在设备内部的丢弃优先级,用于实现同一个队列内部,当队列发生拥塞时报文丢弃顺序。Color支持3种取值,IEEE定义的优先级从低到高依次为Green、Yellow、Red。

丢弃优先级的高低实际取决于对应参数的配置,例如:配置Green最大只能使用50%缓存,Red最大可以使用100%缓存,则Green的丢弃优先级比Red高。

端口信任

在“流分类与流动作”中介绍流分类时提到:“当报文在DiffServ域边界被分类之后,网络的中间节点可以根据分类结果对不同类别的流量给予差别服务。下游节点可以选择使用上游节点的分类结果,也可以按照自己的分类标准对数据流重新进行分类”。那么,如果选择使用上游节点的分类结果,则表示该节点信任上游节点的分类结果,即信任(trust)从连接上游节点的端口接收的报文所携带的QoS标记。因此,设备在实现QoS优先级映射时,可以选择信任端口的上行报文携带的优先级标记(包括DSCP、IP Precedence、802.1p、MPLS Exp),这种模式称为端口信任模式。

NE40E缺省情况下不信任接口,即不关心报文携带的优先级信息,统统将报文的服务等级标记为BE,报文颜色标记为Green。

DS域与优先级映射表

在NE40E上,设备根据优先级映射表实现QoS优先级映射。而在DiffServ模型中,不同DS域允许有不同的PHB映射关系,以实现不同的服务提供策略,因此设备需要允许管理员定义DS域并针对不同的DS域设定不同的优先级关系。

NE40E允许管理员自定义DS域,同时系统预定义了如下域:

  • Default域:描述了缺省情况下IP报文、VLAN报文、MPLS报文的外部优先级和服务等级、颜色之间的映射关系。
  • 5p3d域:描述了VLAN报文802.1p优先级和设备内部服务等级、颜色之间的映射关系,应用于仅支持5种服务等级(Service Class)和3种丢弃优先级的802.1ad局域网。 说明:

    IEEE定义了8种调度优先级的PHB(CS7、CS6、EF、AF4~AF1、BE),对于AF4~AF1又定义了3种丢弃优先级的PHB。因此,PHB数量是4 + 4*3 = 16种。

    而DSCP有64个取值,可以涵盖这16种PHB。但VLAN优先级的802.1p只有8个取值,无法涵盖这16种PHB。通常是将VLAN的8个值与8个调度优先级对应。但IEEE 802.1ad协议定义的STAG格式与CTAG不同,STAG支持DEI(Drop Eligible Indicator)但CTAG不支持DEI。为此IEEE 802.1ad同时提供了对CTAG和STAG都适用的一种利用3Bit的PCP(Priority Code Point)来进行Priority和丢弃优先级(Drop Eligibility)的设定,即要求一个802.1p值能同时表达调度优先级+丢弃优先级的含义,因此诞生了8p0d、7p1d、6p2d和5p3d的概念。其中的“p”是指服务等级(Service Class),“d”是指丢弃优先级。5p3d含义是支持5种服务等级(Service Class)和3种丢弃优先级。

这两个域默认存在,不允许删除。允许用户对Default域中的映射关系进行修改,5p3d域的映射关系不允许修改。

Default域的默认优先级映射表

在NE40E上,默认的外部优先级和内部优先级之间的映射关系如下。

表1 DSCP到服务等级的缺省映射表
DSCP Service Color DSCP Service Color
0~7 BE Green 28 AF3 Yellow
8 AF1 29 BE Green
9 BE 30 AF3 Red
10 AF1 31 BE Green
11 BE 32 AF4
12 AF1 Yellow 33 BE
13 BE Green 34 AF4
14 AF1 Red 35 BE
15 BE Green 36 AF4 Yellow
16 AF2 37 BE Green
17 BE 38 AF4 Red
18 AF2 39 BE Green
19 BE 40 EF
20 AF2 Yellow 41~45 BE
21 BE Green 46 EF
22 AF2 Red 47 BE
23 BE Green 48 CS6
24 AF3 49~55 BE
25 BE 56 CS7
26 AF3 57~63 BE
27 BE
表2 服务等级到DSCP的缺省映射表
Service Color DSCP
BE Green 0
AF1 Green 10
AF1 Yellow 12
AF1 Red 14
AF2 Green 18
AF2 Yellow 20
AF2 Red 22
AF3 Green 26
AF3 Yellow 28
AF3 Red 30
AF4 Green 34
AF4 Yellow 36
AF4 Red 38
EF Green 46
CS6 Green 48
CS7 Green 56
表3 IP Precedence/MPLS EXP/802.1p到服务等级的缺省映射表
IP Precedence/MPLS EXP/802.1p Service Color
0 BE Green
1 AF1 Green
2 AF2 Green
3 AF3 Green
4 AF4 Green
5 EF Green
6 CS6 Green
7 CS7 Green
表4 服务等级到IP Precedence/MPLS EXP/802.1p的缺省映射表
Service Color IP Precedence/MPLS EXP/802.1p
BE Green、Yellow、Red 0
AF1 Green、Yellow、Red 1
AF2 Green、Yellow、Red 2
AF3 Green、Yellow、Red 3
AF4 Green、Yellow、Red 4
EF Green、Yellow、Red 5
CS6 Green、Yellow、Red 6
CS7 Green、Yellow、Red 7

5p3d域的默认优先级映射表

IEEE 802.1ad中对PCP的定义如下图。

图2 PCP encoding/decoding
 

图2中,数字x(0<=x<=7)表示802.1p Priority为x,drop_eligible为false,即不可设定丢弃优先级;数字+字母形式的xDE表示802.1p Priority为x,drop_eligible为true,即可设定丢弃优先级。

NE40E的5p3d域默认优先级映射表遵从IEEE 802.1ad协议的定义,其与IEEE 802.1ad协议的对应关系如下:

表5 NE40E5p3d域与IEEE 802.1ad协议的对应关系
802.1p到Color的映射 从Color到802.1p的映射
IEEE 802.1ad的drop_eligible NE40E报文颜色 NE40E报文颜色 IEEE 802.1ad的drop_eligible
false Green Green false
true Yellow Yellow、Red true

NE40E的5p3d域优先级映射关系如下。

表6 802.1p到服务等级的映射表
802.1p Service Color
0 BE Yellow
1 BE Green
2 AF2 Yellow
3 AF2 Green
4 AF4 Yellow
5 AF4 Green
6 CS6 Green
7 CS7 Green

 说明:

从802.1p到内部服务等级的正向映射时(表6),入接口可能处于非5p3d域而出接口处于5p3d域,非5p3d域可能有8种优先级,因此映射前的802.1p有8种可能的取值,映射入5p3d域只能有五种优先级,因此映射到的内部Service只有BE、AF2、AF4、CS6和CS7五种;

从内部服务等级到802.1p的反向映射时(表7),入接口可能是根据DSCP/Exp/IP preference或者是非5p3d域的802.1p做的正向映射,因此可能出现8种服务等级。而出接口可能处于非5p3d域,因此映射后的802.1p可能有8种取值。

表7 服务等级到802.1p的映射表
Service Color 802.1p
BE Green 1
BE Yellow 0
BE Red 0
AF1 Green 1
AF1 Yellow 0
AF1 Red 0
AF2 Green 3
AF2 Yellow 2
AF2 Red 2
AF3 Green 3
AF3 Yellow 2
AF3 Red 2
AF4 Green 5
AF4 Yellow 4
AF4 Red 4
EF Green 5
EF Yellow 4
EF Red 4
CS6 Green、Yellow、Red 6
CS7 Green、Yellow、Red 7

IETF RFC的建议

IETF的相关标准根据业务属性和对服务质量的要求,将业务分为12类(表8),并给出了这12类业务到DSCP的映射建议(表9)。

表8 业务分类建议(摘自RFC4594 - Figure 2)
业务分类 业务特征 QoS指标
时延容忍度 抖动容忍度 丢包率容忍度
Network Control 网络控制平面的业务流,如路由协议、VRRP、RSVP-TE Low Low Yes
Telephony VoIP电话业务(G.711、G.729等语音流) Very Low Very Low Very Low
Signaling IP语音和视频业务的信令流。如SIP, SIP-T, H.323, H.248 Low Low Yes
Multimedia Conferencing 桌面多媒体会议(仅包括语音和视频,其数据归到Low-Latency Data类)

Low

-

Medium

Very Low Low
Real-Time Interactive 视频会议(仅包括语音和视频,其数据归到Low-Latency Data类)、高清视频、交互式游戏(使用RTP/UDP) Low Very Low Low
Multimedia Streaming VoD视频点播

Low

-

Medium

Medium Yes
Broadcast Video 广播电视、实时视频监控业务 Very Low Medium Low
Low-Latency Data 交互式的重要数据业务,要求响应时间短,如VCX IP消息业务、ERP、CRM、DB。 Low

Low

-

Medium

Yes
OAM 网络运维、维护和管理业务,例如SNMP、Syslog、SSH Low Medium Yes
High-Throughput Data 非交互性的背景业务,其用户不着急等待业务响应,如E-mail、FTP。 Low

Medium

-

High

Yes
Standard 默认的Internet业务(Best-Effort业务)。如果业务没有标记优先级,可将其归为此类。 Not Specified
Low-Priority Data 非实时的弹性的业务,如娱乐视频流量。当网络拥塞,这类业务首先被丢弃。 High High Yes

表9 业务类型到DSCP的映射(摘自RFC4594 - Figure 3)
业务类型 DSCP Name DSCP Value Application Examples
Network Control CS6 110000(48) Network routing
Telephony EF 101110(46) IP Telephony bearer
Signaling CS5 101000(40) IP Telephony signaling
Multimedia Conferencing

AF41

AF42

AF43

100010(34)

100100(36)

100110(38)

H.323/V2 video conferencing (adaptive)
Real-Time Interactive CS4 100000(32) Video conferencing and Interactive gaming
Multimedia Streaming

AF31

AF32

AF33

011010(26)

011100(28)

011110(30)

Streaming video and audio on demand
Broadcast Video CS3 011000(24) Broadcast TV & live events
Low-Latency Data

AF21

AF22

AF23

010010(18)

010100(20)

010110(22)

Client/server transactions Web-based ordering
OAM CS2 010000(16) OAM & P
High-Throughput Data

AF11

AF12

AF13

001010(10)

001100(12)

001110(14)

Store and forward applications
Standard CS0 000000(0) Undifferentiated applications
Low-Priority Data CS1 001000(8) Any flow that has no BW assurance

3GPP的流分类建议

3GPP TS23.203协议将无线业务分成9类,并定义了对应的QCI(QoS class identifier)。每个QCI指示每类业务的资源类型、优先级、时延、丢包率等质量要求。QCI标准化了业务的QoS要求。EPS按照QCI来控制QoS。QCI在EPS中各个网元中传递,避免了协商和传递大量具体的QoS参数。QCI只作用于无线网元,对承载层面不可见。

3GPP的建议

表10 3GPP的流分类建议(摘自3GPP TS23.203 - Table 6.1.7)
QCI 资源类型 优先级 数据包时延 数据包错误率&丢失率 典型业务
1 GBR 2 100 ms 10-2 会话语音
2 4 150 ms 10-3 会话视频(实时体)
3 3 50 ms 10-3 实时游戏
4 5 300 ms 10-6 非会话视频 (缓冲流)
5 Non-GBR 1 100 ms 10-6 IMS信令
6 6 300 ms 10-6 视频(缓冲流)、基于TCP的应用(例如,WWW、电子邮件、聊天、FTP、p2p文件共享、逐行扫描视频等)
7 7 100 ms 10-3 语音、视频(实时流)、交互式游戏
8 8 300 ms 10-6 视频 (缓冲流)、基于TCP的应用(例如WWW上网、电子邮件、聊天、FTP、p2p文件共享、逐行扫描视频等)
9 9

3GPP没有给出QCI与DSCP之间的映射关系。华为的建议请参见表11

表11 LTE业务优先级映射建议
业务类型 QCI 资源类型 典型业务 DSCP 802.1p/MPLS EXP PHB
User Plane 1 GBR 会话语音 0x2E(46) 5 EF
2 会话视频 0x1A(26) 3 AF31
3 实时游戏 0x22(34) 4 AF41
4 非会话视频 0x1A(26) 3 AF31
5 non-GBR IMS信令 0x30(48) 5 EF
6 视频(缓冲流)、基于TCP的应用(例如,WWW、电子邮件、聊天、FTP、p2p文件共享、逐行扫描视频等) 0x12(18) 2 AF21
7 语音、视频(实时流)、交互式游戏 0x12(18) 2 AF21
8 视频(缓冲流)、基于TCP的应用(例如,WWW、电子邮件、聊天、FTP、p2p文件共享、逐行扫描视频等) 0x0A(10) 1 AF11
9 0x00(00) 0 BE
Control Plane -   SCTP 0x2E(46) 5 EF
OM -   MML(Man-Machine Language,人机交互语言) 0x2E(46) 5 EF
-   FTP 0x0E(14) 1 AF11
IP Clock -     0x2E(46) 5 EF

GSMA的流分类建议

GSMA将流量分为四类:会话类、流媒体、交互类和背景类。GSMA推荐将这4种类型映射为IETF推荐的6类DSCP值,见表12表13

表12 流量类型与DSCP值的映射(摘自GSMA IR34 - table6)
流量类型 QoS信息
THP(Traffic Handing Priority) PHB DSCP
会话类 N/A EF 101110 (46)
流媒体 N/A AF41 100010 (34)
交互类 1 AF31 011010 (26)
2 AF21 010010 (18)
3 AF11 001010 (10)
背景类 N/A BE 000000 (0)

表13 业务应用与DSCP值的映射(摘自GSMA IR34 - table7)
业务应用 Diffserv PHB 流量类型
视频共享 EF 会话类
VoIP EF 会话类
即按即说(Push-to-Talk) AF4 流媒体
视频流 AF4 流媒体
无法识别的GTP流量 AF3 交互类
DNS AF3 交互类
在线游戏 AF3 交互类
网页浏览(Browsing) AF2 交互类
即时消息(Instant Message) AF1 交互类
远程连接 AF1 交互类
Email, MMS BE 背景类

IEEE 802.1的流分类建议

IEEE 802.1标准(包括802.1D、802.1Q和802.1ad)利用VLAN Tag的PCP字段(3Bit)定义了以下8种流量类型。

表14 IEEE 802.1的分类建议
流量类型 优先级 协议举例 业务特征
Network Control 7 BGP, PIM, SNMP 网络维护与管理报文的可靠传输,要求低丢包率
Internet Work Control 6 STP, OSPF, RIP 大型网络中区分于普通流量的网络协议控制报文
Voice 5 SIP, MGCP 适用于语音业务,一般要求时延小于10 ms
Video 4 RTP 适用于视频业务,一般要求时延小于 100 ms
Critical Applications 3 NFS, SMB, RPC 适用于要求确保最小带宽的业务
Excellent Effort 2 SQL 用于一般的信息组织向最重要的客户发送信息
Best Effort 0(default) HTTP, IM, X11 缺省业务类型,只要求"尽力而为"的服务质量
Background 1 FTP, SMTP 适用于不影响用户或关键应用的批量传输业务

MEF的流分类建议

MEF23.1标准根据以太二层传输的业务特征和QoS需求,将业务分为高(H)、中(M)、低(L)3类优先级,使用COS Label标记,并使用DEI (drop eligibility identifier)标记丢弃优先级,请参见表15

MEF23.1同时也给出了COS Label和DSCP之间的映射关系建议,请参见表16表17

表15 业务优先级划分(摘自MEF 23.1 - Table 36)
业务类型 COS Label
VoIP H
VoIP & videoconf signaling M
Videoconf data M
IPTV data M
IPTV control M
Streaming media L
Interactive gaming H/M
SANs synch replication M
SANs asynch replication M
Network attached storage L
Text & graphics terminals L
T.38 fax over IP M
Database hot standby M
Database WAN replication M
Database client/server L
Financial/Trading H
CCTV H
Telepresence H
Circuit Emulation H
Mobile BH H H
Mobile BH M M
Mobile BH L L

表16 COS ID类型仅为EVC或OVC EP时的Color ID值(摘自MEF23.1的Table 3)
CoS标签 CoS ID类型 Color标识
C-Tag PCP PHB (DSCP)
Color Green Color Yellow Color Green Color Yellow
H EVC or OVC EP 5, 3 or 1 N/S in Phase 2 EF or AF (10, 26 or 46) N/S in Phase 2
M EVC or OVC EP 5, 3 or 1 2 or 0 EF or AF (10, 26 or 46) AF (0, 12, 14, 28 or 30)
L EVC or OVC EP 5, 3 or 1 2 or 0 EF or AF (10, 26 or 46) AF (0, 12, 14, 28 or 30)

表17 CoS标识和Color标识 (摘自MEF23.1的Table 4)
CoS标签 CoS和Color标识
C-Tag PCP PHB (DSCP) S-Tag PCP(不支持DEI) S-Tag PCP
Color Green Color Yellow Color Green Color Yellow Color Green Color Yellow 支持DEI
H 5 N/S in phase 2 EF(46) N/S in phase 2 5 N/S in phase 2 5
M 3 2 AF31(26) AF32(28) 3 2 3
AF33(30)
L 1 0 AF11(10) AF12(12) 1 0 1
AF13(14)
DF(0)

ITU-T的建议

ITU-T的Y.1541根据IPTD(传输时延)、IPDV(时延变化)、IPLR(丢包率)、IPER(错误率)四个参数,将业务分为Class0~5,共6类(见表18),同时给出了IP QoS分类指导(见表19图3)。

表18 IP网络QoS类型定义及网络性能指标(摘自ITU-T Y.1541 - Table 1)
网络性能参数 网络性能目标值 QoS类别
Class 0 Class 1 Class 2 Class 3 Class 4 Class 5 Unspecified
IPTD 平均IPTD的上限值 100 ms 400 ms 100 ms 400 ms 1 s 不要求
IPDV IPTD×(1-10-3)-IPTD的最小值 50 ms 50 ms 不要求 不要求 不要求 不要求
IPLR IPLR的上限值 1 × 10–3 1 × 10–3 1 × 10–3 1 × 10–3 1 × 10–3 不要求
IPER IPER的上限值 1 × 10–4 不要求

表19 IP QoS分类指导(摘自ITU-T Y.1541 - Table 2)
QoS分类 应用 网络节点机制 技术
0 实时性、抖动敏感、高交互性的业务(如VoIP、VTC) 独立队列,高服务优先级、traffic grooming 约束
1 实时性、抖动敏感、交互性的业务( 如VoIP、VTC) 对其路由和距离有一定的约束
2 事务(办理)数据、高交互性的业务(如信令) 独立队列、低丢包率 约束其路由和距离
3 事务(办理)数据、交互性的业务 对其路由和距离有一定的约束
4 仅要求低丢包率的业务(如 (简短的事务(办理、批量数据、视频流) 长队列、低丢包率 任意路由/路径
5 IP网络缺省的传统应用 独立队列(服务优先级最低) 任意路由/路径

图3 用较少QoS类型对多业务的分类原则 (摘自ITU-T Y.1541 - Figure 2)

MPLS DiffSev

由于MPLS网络使用Exp标示业务优先级,Exp最多只能标示8种优先级。如果业务类型超过8种,则需要将多个类型聚合到同一个PHB中。

标准协议将业务重新分为四种,并给出了对应的DSCP和Exp推荐值,见表20

表20 "Treatment Aggregate and MPLS EXP Field Usage"(摘自RFC5127 -Figure 2和Figure 3)
业务类型 PHB DSCP 四大类型 QoS指标 Exp
二进制(十进制) 时延容忍度 抖动容忍度 丢包率容忍度 二进制(十进制)
Network Control CS6 110000(48) Network Control Low Low Yes 110(6)
Telephony EF 101110(46) Real-Time Very Low Very Low Very Low 100(4)
CS5 101000(40)
AF41 100010(34)
Signaling AF42 100100(36)
Multimedia Conferencing AF43 100110(38)
Real-Time Interactive CS4 100000(32)
Broadcast Video CS3 011000(24)
Multimedia Streaming CS2 010000(16) Assured Elastic Low Low – Medium Yes 010(2)
AF31 011010(26)
AF21 010010(18)
Low-Latency Data AF11 001010(10)
OAM AF32 011100(28) 011(3)
AF22 010100(20)
AF12 001100(12)
AF33 011110(30)
AF23 010110(22)
High-Throughput Data AF13 010110(14)
Standard Default(CS0) 000000(0) Elastic Not Specified 000(0)
Low-Priority Data CS1 001000(8) 001(1)
2017-10-18 17:05:40 clovejq 阅读数 1560

iOS9 特性

关键字参考 2015 Objective-C 新特性

1.关键字 :

这些是纯编译器的语法支持(llvm 7.0),没有借助任何 objc runtime 的升级,也就是说,这个新语法在 Xcode 7 上可以使用且完全向下兼容(更低的 iOS 版本)

  • nullable (_Nullable、__nullabel setter 和 getter 可以为空)
  • nonnull(_Nonnull、__nonnull setter 和 getter 不能为空)
  • null_resettable(_Null_resettabel、__null_resettable setter 可以为空,getter 不能为空)
  • __covariant: 协变, 用于数据强制转换类型(子类可以转变父类)
  • __contravariant: 逆变, 用于数据强制转换类型(父类可以转变子类)
  • kindof : 表示当前类, 或者它的子类(kindof使用: 放在类型前面, 表示修饰此类型)
  • Foundation 还提供了一对儿宏,包在里面的对象默认加 nonnull 修饰符,只需要把 nullable 的指出来就行 NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END

关键字只能修饰对象, 不能修饰基本数据类型, 可以用在属性, 方法的参数, 方法的返回值使用, 在默认情况下, 不加nullable, setter 和 getter 都是可以为nil, 以下是nullable使用方法,nonnull、null_resettable 同理

@property (nonatomic, strong, nullable) NSArray *array;
@property (nonatomic, strong) NSArray * __nullable array;
@property (nonatomic, strong) NSArray * _Nullable array;
2.Contacts.framework/ContactsUI.framework

iOS 9引入联系人框架(Contacts.framework和ContactsUI.framework),它为通讯簿和通讯录UI框架提供了更加面向对象替代。要了解更多信息,请参阅官方文档联系人框架参考
联系人选择封装

3.UIKit框架(UIKit.framework)
  • UIStackView类,它可以帮助您管理一组子视图,可以垂直或水平排列堆叠。
  • 新的布局锚点UIView(如leadingAnchor和widthAnchor)NSLayoutAnchor,和NSLayoutDimension所有这些有助于使布局容易。新的布局指南,可帮助您采用可读的内容页边距,并定义视图中内容应绘制的位置。有关更多信息,请参阅UILayoutGuide
  • 对UIKit Dynamics的增强功能,例如支持非矩形碰撞界限,新UIFieldBehavior类,除了可定制之外还支持各种字段类型,还有其他附件类型UIAttachmentBehavior。
4.废弃的API
  • AddressBook/AddressBookUI.frameworks废弃,使用Contacts/ContactsUI.frameworks替代.
  • NSURLConnection废弃,使用 NSURLSession 替代

iOS 10 特性

兼容iOS 10 资料整理笔记
活久见的重构 - iOS 10
开发者所需要知道的 iOS 10 SDK 新特性

1.通知框架(UserNotifications.framework)
  • iOS 10引入了通知框架(UserNotifications.framework),它支持本地和远程通知的传递和处理。您可以使用此框架的类根据特定条件(如时间或位置)安排本地通知的传递。应用程序和应用程序扩展可以使用此框架在本地和远程通知传递到用户的设备时接收并潜在地进行修改。
  • 在iOS 10中也引入了UserNotificationsUI.framework,您可以在用户设备上显示本地和远程通知时自定义外观。您可以使用此框架定义一个应用程序扩展,它接收通知数据并提供相应的可视化表示。您的扩展程序还可以响应与这些通知相关联的自定义操作。
2.语音识别框架 (Speech.framework)
  • iOS 10引入了一个新的API,支持连续语音识别,并帮助您构建可识别语音并将其转录成文本的应用程序。使用Speech框架(Speech.framework)中的API ,您可以执行实时和录制音频的语音转录。例如,您可以使用以下代码获取语音识别器并开始简单的语音识别:
let recognizer = SFSpeechRecognizer()

let request = SFSpeechURLRecognitionRequest(url: audioFileURL)

recognizer?.recognitionTask(with: request, resultHandler: { (result, error) in

     print (result?.bestTranscription.formattedString)

})

与访问其他类型的受保护数据(如日历和照片数据)一样,执行语音识别需要用户的许可(有关访问受保护的数据类的更多信息,请参阅安全和隐私增强)。在语音识别的情况下,需要许可,因为数据被传输并临时存储在苹果的服务器上,以提高识别的准确性。要请求用户的许可,您必须将NSSpeechRecognitionUsageDescription键添加到应用程序的Info.plist文件中,并提供描述应用程序使用情况的内容。
当您在应用程序中采用语音识别时,请务必向用户说明他们的演讲是否被识别,以避免在当时发出敏感的话语。

3.Foundation框架(Foundation.framework)

Foundation框架(Foundation.framework)包含许多增强功能,如:

  • 新NSDateInterval类定义了一个用于计算时间间隔持续时间的程序接口,并确定一个日期是否在其中,以及比较日期间隔和检查它们是否相交。
  • 在NSLocale类定义了许多,你可以用它来获得有关语言环境,以及如何可以显示信息的新属性。
  • 新NSMeasurement课程帮助您将测量值转换为不同的单位,并计算两次测量之间的总和或差值。NSMeasurementFormatter当向用户显示单位数量时,新类可帮助您创建测量的本地化表示。
  • 新的NSUnit类和具体NSDimension子类可以帮助您表示具体的度量单位。
4.UIKit框架(UIKit.framework)

UIKit框架(UIKit.framework)包括许多增强功能,如:

  • 新的基于对象的完全交互式和可中断的动画支持,可让您保留对动画的控制,并将其与基于手势的交互链接。要了解更多信息,请参阅UIViewAnimating Protocol ReferenceUIViewPropertyAnimator类参考UITimingCurveProvider协议参考UICubicTimingParameters类引用UISpringTimingParameters类参考
  • 新的UIPreviewInteraction类和UIPreviewInteractionDelegate协议,让您提供与预览相关的自定义用户界面。
  • UIPasteboardAPI可以自动声明普通类实例的兼容内容类型和限制粘贴板上对象生命周期。
  • 新的preferredFontForTextStyle:compatibleWithTraitCollection: UIFont方法,它允许您添加对标签,文本字段和其他文本区域中的动态类型的支持。
    该UIContentSizeCategoryAdjusting协议提供了adjustsFontForContentSizeCategory可用于确定在设备UIContentSizeCategory更改时采用元素是否应更新其字体的属性。
    额外控制标签栏项目上徽章的外观,如背景颜色和文本属性。
    支持所有滚动视图和滚动视图子类中的刷新控件,例如UICollectionView。
  • 新UIApplication方法openURL:options:completionHandler:是异步执行的,并在主队列中调用指定的完成处理程序(此方法替换openURL:)。
  • 新的UICloudSharingController类和UICloudSharingControllerDelegate协议,可帮助您启动CloudKit共享操作,并显示视图控制器,让用户查看和修改参与者并启动和停止共享。
  • 增强功能UICollectionView和新UICollectionViewDataSourcePrefetching协议,可帮助您利用单元格的自动预取来改善滚动体验。UICollectionView新特性
5. WebKit框架(WebKit.framework)

WebKit框架(WebKit.framework)在WKWebView对象中引入增强的预览和弹出支持。在iOS 10中,您可以使用该webView:shouldPreviewElement:方法来确定指定的Web视图是否应显示预览。

iOS11 特性

WWDC 17: 开发者的最初观感
开发者所需要知道的 iOS 11 SDK 新特性

1. General
  • 支持二进制(非文本)条形码。
    为AV Foundation,Core Image和SiriKit添加了API,以支持检测,解码和创建具有二进制内容的条形码。CIBarcodeDescriptor为Core Image 添加了一个新的条形码描述符对象,以提供与AV Foundation和Vision API的互操作性。

  • MusicKit
    MusicKit可让您的应用访问完整的Apple Music目录以及用户的图书馆。
    StoreKit中增加和更新了功能,用于检索客户端令牌和店面标识符. 在Media Player中添加和更新功能以启用播放。在Apple Music订户设置流程中添加了自定义消息的显示。

2.App Frameworks
  • 支持拖放功能。
    在iOS中拖放可让用户将项目从一个位置拖动到另一个位置; 在单个应用程序或不同的应用程序中。
    功能增加,将视图识别为拖动源和目的地。
    添加了可定制的预览和定制动画。
  • 新增 - 浏览本地和iCloud文档。
    添加了视图控制器,用于浏览存储在本地和云中的文档。有关更多信息,请
    添加了UIDocumentBrowserAction一个用于为文档浏览器创建自定义操作的对象。
    添加了FileProvider和FileProviderUI框架,用于添加第三方存储服务。
  • 改进了动态类型支持。
    添加了UIFontMetrics一个用于创建根据当前选定的文本大小进行缩放的自定义字体的对象。
    更新自动布局,以便在基准锚点是使用系统间距的约束的一部分时,根据字体大小动态调整间距。
    添加了一个属性来保存PDF资源的矢量数据,以实现平滑缩放。这可以用于显示较大版本的条形条和分段控制项,以及调整图像大小以匹配用户的文字大小。在资产目录中,为PDF选择“保留矢量数据”以启用缩放。
    添加UIAccessibilityContentSizeCategoryImageAdjusting了一种用于缩放辅助功能文本大小的图像的协议。
  • 改进了动态类型的自动布局支持。
    更新NSLayoutXAxisAnchor并NSLayoutYAxisAnchor提供使用两个锚之间的系统间距创建约束的工厂方法。以前,创建这样的约束的唯一方法是使用-Visual Format语言中的dash()。
    添加了一个选项,NSLayoutFormatOptions用于创建使用基线到基线间距的Visual Format语言字符串。
    更新UIStackView以实现系统间距和定制间距。
  • 更新的文本内容可以与App Password自动填充一起使用。
    添加username和password属性UITextContentType。
  • 对键盘扩展的更新。
    已添加selectedText,该属性UITextDocumentProxy返回文档中当前选定的文本。
    已添加documentIdentifier,其属性UITextDocumentProxy指定用户是否导航到新的文本小部件。
    添加hasFullAccess了UIInputViewController检查键盘权限的属性。
    添加needsInputModeSwitchKey了UIInputViewController控制输入 模式切换键显示的属性。
    在“设置”中添加新的系统权限,以便应用程序访问附加的键盘扩展。
  • 改进的可用存储空间API。
    URL为不同的使用场景添加了新的键。
    volumeAvailableCapacityForImportantUsageKey 返回用户明确要求的操作的总字节数,或者是您的应用程序正常运行所必需的。
    volumeAvailableCapacityForOpportunisticUsageKey 返回可用于存储非必需项目的总字节数,例如预先下载的用于用户可能使用或可能不会被使用的性能的内容。
3.Graphics and Games
  • 支持增强现实。
    添加了ARKit.framework,结合了设备运动跟踪,摄像头场景捕获,高级场景处理和显示便利,简化了建立AR体验的任务。
  • 高性能图像分析。
    添加了用于检测面部,条形码,文本,图像水平和矩形区域的Vision框架。
    与Core ML集成以在图像上运行自定义模型。
    跟踪视频中的对象。
    包括对图像注册的支持。
  • 为Core Image编写自定义图像混合内核。
    新增CIBlendKernel,一种特殊类型的CIColorKernel混和两个图像(通过支持CIRenderDestination和CIImageAccumulator)。
    添加init(functionName:fromMetalLibraryData:)到CIKernel使用Metal编写内核以从现代语言功能和减少的编译时间中受益。
  • 轻量级渲染目标。
    添加了CIRenderDestination一个对象,用于创建在工作发出后返回给调用者的渲染器。功能包括为不同目的地指定渲染器的所有目标属性IOSurface,包括CVPixelBuffer,GL纹理,金属纹理和内存。
  • 扩展ReplayKit.framework
    更新RPScreenRecorder了屏幕捕获和后置摄像头支持。
  • 增加了新的核心图像过滤器CITextImageGenerator,CIColorCurves,CILabDeltaE,CIBokehBlur,CIMinMaxRed,和CIBicubicScaleTransform。
4.App Services
  • 支持机器学习模式。
    添加了CoreML.framework,轻松将机器学习模型集成到应用程序中。
  • SiriKit支持视觉代码。
    向Sirkit 添加了视觉代码域,以支持显示交换付款和联系信息的视觉代码。
  • SiriKit支持笔记和待办事项列表。
    向SiriKit 添加了列表和Notes域,以支持使用Siri添加备注,与待办事项列表进行交互,以及与提醒进行交互。
  • 在SiriKit域中增加了意图。
    将骑行取消和反馈添加到骑行预订域。
    增加了汇款和搜索帐户到付款域。
  • 查找设备的标题。
    添加heading到CMDeviceMotion,返回相对于的方位角度的属性CMAttitudeReferenceFrame。返回的值是以度为单位的标题double。当参考帧为xArbitraryZVertical或时,返回负值xArbitraryCorrectedZVertical。
  • 多路径TCP。
    增加了对使用多个接口(如Wi-Fi和Cellular)的URLSessionConfiguration支持,通过扩展支持IETF RFC 6824中定义的多路径TCP传输单个数据流。有关更多信息,请参阅URLSessionConfiguration.MultipathServiceType
  • DNS代理。
    向网络扩展框架添加了新的DNS代理应用程序扩展类型。
  • Apple Pay中增强的最终用户交易流程。
    添加PKPaymentError到PassKit,用于详细报告用户运输和付款信息中的错误以及授权错误的结构。开发人员可以使用该信息来提供自定义的错误字符串。
    更新处理程序方法PKPaymentAuthorizationControllerDelegate以接收PKPaymentError。
    更新PKPaymentRequest使用PKContactField的联系信息。
    添加supportedCountries到PKPaymentRequest用于指定支持的交易的国家/地区。
    即使电子钱包中没有支持付款方式,您也可以提供付款按钮。Apple Pay现在提供付款而不离开您的应用程序,然后返回结帐。
  • 在App Store上推广应用内购买。
    开发人员可以在App Store产品页面上宣传多达20个应用内购买。客户可以在App Store上开始购买,然后被带到应用程序来完成交易。
    增加paymentQueue(_:shouldAddStore:for:)了一种SKPaymentTransactionObserver促进应用内购买的新方法。应用程序需要支持此代理,以便在App Store上显示促销的应用内购买。
  • 实时消息。
    添加MSMessageLiveLayout了一个新的消息布局,用于显示可以显示动态内容的实时消息,如游戏。每个实时消息都有自己的MSMessagesAppViewController,并且可以在屏幕上同时存在多个活动的实时消息。以下代码显示将消息流添加到消息流中,包括不支持实时消息的设备的备用布局。
    guard let conversation = activeConversation else {
       fatalError("No active conversation")
}

let alternateLayout = MSMessageTemplateLayout()
alternateLayout.image = UIImage(named: "SuperSweetGameImage")
alternateLayout.caption = "$(\(conversation.localParticipantIdentifier)) wants to play a game!"
let layout = MSMessageLiveLayout(alternateLayout: alternateLayout)

let message = MSMessage()
message.layout = layout

conversation.insert(message, completionHandler: nil)
  • HomeKit的增强触发器。
    增强触发器的基于时间的条件。HMSignificantTimeEvent指定日出和日落的偏移量。HMCalendarEvent指定日期和时间。HMDurationEvent指定时间间隔。
    添加HMCharacteristicThresholdRangeEvent以支持跟踪一个范围内的配件的状态,例如当温度在68和72度之间时运行自动化。
    添加HMPresenceEvent用于添加基于用户的存在或不存在的条件。
    更新HMEventTrigger以启用多次重复的事件。
  • 通过实施来接收家庭中心状态的更新home:didUpdateHomeHubState:。
  • 更新了MapKit,以更清楚地显示开发人员数据。
    添加mutedStandard了一种强调开发人员数据的新地图显示模式。
    添加属性以自定义注释在碰撞发生时的行为。开发人员使用的组合displayPriority,collisionMode以及clusteringIdentifier对影响哪个注解持续显示在地图上。
4.Media and Web
  • 支持高效率视频编码(HEVC)。
    高效率视频编码(HEVC)是视频编码的新标准,在相同的视觉质量水平下,提供比H.264更好的压缩效果。
    使用AV基金会播放包含HEVC编码曲目的电影,并捕获和导出视频。
    VideoToolbox 客户端可以对HEVC视频比特流进行编码和解码。
  • 支持高效图像格式(HEIF)。
    高效图像格式(HEIF)是一种新的图像压缩标准,可将相同级别图像质量的当前数据压缩比加倍。
    添加了照片和核心图像框架的功能,以显示,编码和导出HEIF图像。
  • 支持捕获和操作深度数据,以及增强的照片捕获。
    向AVFoundation添加了对象,用于捕获和表示深度数据。欲了解更多信息,请参见AVCaptureDepthDataOutput,AVDepthData以及相关的API。
    添加了AVCapturePhoto一个封装捕获的照片的信息并支持HEVC和HEIC编码图像的对象。
    更新AVCapturePhotoOutput以提供更多信息。
  • 自动存储管理。
    增加了HTTP实时流资源的自动存储管理AVAssetDownloadTask。当需要空间时,系统可以自动清除过期或不必要的下载。使用优先级来影响清除策略。
  • AirPlay 2。
    AV基础中某些音频播放界面改善了AirPlay的可靠性。要利用增加的可靠性,播放音频AVPlayer或新的AVSampleBufferAudioRenderer对象。
    为AirPlay添加了多个扬声器支持,以支持长形音频,如音乐和播客。要将应用程序标记为呈现长格式音频,请调用该AVAudioSession方法setCategory(_:mode:routeSharingPolicy:options:)并将AVAudioSessionRouteSharingPolicyLongForm其用作参数值。
  • FairPlay流密钥管理。
    改进了功能AVContentKeySession。使用AVContentKeySession启动独立播放或媒体资产的下载的内容密钥请求。符合AVContentKeyRecipient协议的对象(例如AVURLAsset)可被添加为接收者AVContentKeySession以获得对现有内容密钥的访问并发起新的内容密钥请求
  • 增加了更多的实时照片调整。
    添加了一个称为效果的实时照片调整的集合,将实时照片呈现为循环,反弹或长时间曝光。与常规实时照片不同,Loop和Bounce视频将以连续的循环播放。
    添加了playbackStyle一个新的属性,标识如何向PHAsset用户呈现。
5. System
  • 热点配置。
    添加了热点配置的网络扩展。有关更多信息,请参阅NEHotspotConfiguration
  • 更新了核心蓝牙框架。
    增加了对L2CAP频道的支持。
    扩展会话恢复可以在蓝牙复位和设备重新启动时工作。
    更新了核心蓝牙框架,以适应iOS,tvOS,watchOS和macOS,以及基于平台的标记呼叫可用性。
  • 检测NFC标签并读取包含NDEF数据的消息。
    增加了核心NFC,一种用于阅读NFC数据交换格式(NDEF)的近场通信(NFC)标签和数据的新框架。
  • APFS现在是默认文件系统。
    APFS现在对区分大小写的文件系统有不规范化的支持。


作者:boundlessocean
链接:http://www.jianshu.com/p/7d658bea0c56
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2016-10-28 19:44:45 byeweiyang 阅读数 2008

作者简介: 陈宜龙,iOS开发工程师,现任职于LeanCloud,热爱开源与分享,GitHub 获得的Star数过万,其中 《iOS9适配系列教程》 一度成为该领域最有影响力的教程。 StackOverFlow 威望值高达4000。同时也是多个开源项目的维护者: CYLTabBarController、LeanCloud-iOS-SDK、ChatKit 、iOSInterviewQuestions、ParseSourceCodeStudy 等。

DNS出问题的概率其实比大家感觉的要大,首先是DNS被劫持或者失效,2015年初业内比较知名的就有 Apple 内部 DNS 问题导致 App Store、iTunes Connect 账户无法登录;京东因为 CDN 域名付费问题导致服务停摆。

另一个常见问题就是 DNS 解析慢或者失败,例如国内中国运营商网络的 DNS 就很慢,一次 DNS 查询的耗时甚至都能赶上一次连接的耗时,尤其 2G 网络情况下,DNS 解析失败是很常见的。因此如果直接使用 DNS,对于首次网络服务请求耗时和整体服务成功率都有非常大的影响。

DNS 劫持、污染一般是针对递归 DNS 服务器的 DNS 劫持攻击,

DNS 系统中有两种服务角色:递归 DNS 和授权 DNS。本质上来说,授权 DNS 控制网站的解析;递归 DNS 只起缓存的作用。所以跟广大站长关系比较大的是授权 DNS,也就是在域名注册商处填写的 DNS 地址。而网民使用的则是递归 DNS。
见:https://support.dnspod.cn/Kb/showarticle/tsid/186/

现实中的问题:

  • DNS解析时间过长
    像 iOS 系统一般是24小时之后会过期,还有进入飞行模式再切回来,开关机,重置网络设置等也会导致DNS cache的清除。所以一般情况下用户在第二天打开你的app都会经历一次完整的DNS解析请求,网络情况差的时候会明显增加应用请求的总耗时。

  • DNS劫持,不可以被信任的运营商,不可以被信任的 DNS 解析服务。

    DNS 在设计之初是基于 UDP 的,显然这样的设计不能满足当今社会的准确性的需求,于是涌现了如 DNSPod 这样的基于 HTTP 的 DNS 解析服务。但是当时为什么这样设计,实际也很好理解,UDP 效率高,一来一回网络上传输的只有两个包,而 HTTP则需要三次握手三个包,再一拆包,就需要四个包。这是受限于当时整个社会的带宽水平较低,而现在没人会感激 UDP 所节省的流量,所有人都在诟病DNS污染问题。

图为360向大家们示范什么是 DNS 劫持:

运营商 DNS 劫持问题中,中国移动最为严重,

某些地区的中国移动还有个简单粗爆的域名检查系统,包含 av 字样的域名一率返回错误的 IP,

LeanCloud 之前叫做 AVOSCLoud,域名是:https://cn.avoscloud.com,嗯,我们很受伤。

后来我们改名了,域名也切换到了 api.leancloud.cn,我们用户的 DNS 问题已经大大的减少了。

鬼知道我们经历了什么。

虽然这个事件并不典型,但也足以说明,这个一个不可靠的服务,你无法掌控它的拦截规则。

而且黑产与各地运营商的一些“合作”也会导致 DNS 劫持。

原有的解决方法:简单粗暴投诉运营商。

传统的解决方法:投诉

诊断方法步骤:

  • iOS 用户推荐 iNetTools
  • Android 用户推荐 LanDroid

    ping 响应时间,100(单位默认为 ms)以下都是可以接受的,高于 100 ms 会感到缓慢

    移动环境下,向中国移动打 10086 电话投诉,告之受影响的域名及 DNS 服务器的 IP,才能解决问题。
    如果是在无线网络情况下, DNS 异常,则请通过路由器的 DHCP 设置,将默认的 DNS 修改为正常的 DNS(推荐 114.114.114.114),并重启路由器即可。

投诉到中国移动后 48 小时问题仍未解决的话,依据中国相关法律法规规定,可以向工信部申诉,网址是 http://www.chinatcc.gov.cn:8080/cms/shensus/,这里最好是以邮件的方式申诉,将具体细节和截图写在邮件里发送给 accept@chinatcc.gov.cn,工信部的相关同学最早会在第 2 天回电话并催促中国移动。

申诉邮件的内容需要包括两个部分:

  • 一是申诉者的姓名、身份证号码、通信地址、邮编、联系电话、申诉涉及到的电话号码、电子邮件、申诉日期
  • 二是被申诉企业名称、申诉内容(详情)、是否向企业申诉过(一定要先向企业投诉,无效后工信部才能受理,直接找工信部的不受理),最后要承诺「我承诺申诉信息真实有的」

这样显然不是长久之计,下面就介绍下如何用技术手段去解决:

IP 直连在IPv6 环境下的可行性

首先:所有防 DNS 方案都是基于IP直连的方案,那么就要首先介绍 IP 直连这个方案的可行性。

从2016年6月1日起,iOS 应用必须支持 IPv6,否则审核将被拒。IPv6 规则出来后,网上有一种言论称:IP 直连不可行。

其实是 IP 直连,在 IPv6 环境下也是可行的,下面做下说明:

IP或域名在到达服务器前,经历了两个步骤往往会被我们所忽略:

如果你拿一个IPv4的IP或域名进行请求,有两个机制可以保证最终到达 Server 的是一个IPv6地址。

第一个机制是绿色部分,指的是 iOS系统级别的 IPv4 兼容方案,只要你使用了 NSURLSessionCFNetwork, 那么iOS系统会将帮你把它转为IPv6地址。

NSURLSession and CFNetwork automatically synthesize IPv6 addresses from IPv4 literals locally on devices operating on DNS64/NAT64 networks.(如果当前网络是 IPv6 网络,那么会在iOS系统层面转换成 IPv6.)

第二个机制是 DNS 服务的兼容方案,可以是运营商提供的服务,也可以是第三方 DNS 解析机构比如 DNSPod。如果 DNS 解析出来的域名是 IPv4 地址,也会转为 IPv6 地址。

综上所述,IPv6 政策的应对方案可以有下面几种:

  1. 使用高层API,比如 NSURLSession and CFNetwork
  2. 升级服务器,让服务端支持 IPv6。在 APP 中替换 IPv4 的地址。
  3. 如果你的 APP 需要使用了更底层的 API 连接到仅支持 IPv4 的服务器,且不使用 DNS 域名解析,请在APP端使用 getaddrinfo 处理 IPv4 地址串( getaddrinfo 可通过传入一个IPv4或IPv6地址,得到一个 sockaddr 结构链表)。如果当前的网络接口不支持 IPv4,仅支持 IPv6,NAT64和DNS64,这样做可以得到一个合成的IPv6地址。

参考:《iOS支持IPv6 DNS64/NAT64网络》

在 HTTPS 业务场景下的防 DNS 污染方案

防止 DNS 污染的方式有多种:

实现方式大致有两种:

方案一:HTTP 场景 IP 直连

通过IP直接访问网站,可以解决 DNS 劫持问题。如果是 HTTP 请求,使用 ip 地址直接访问接口,配合 header 中 Host 字段带上原来的域名信息即可;

方案二:客户端维护一个 IP 列表

  • 无效映射淘汰机制
  • 使用IP列表避免DNS解析失败或者劫持 (电信、移动、联通,域名异步地去获取)IP地址,请求成功就+1、失败就-1,然后得到优先级列表
  • 根据网络延迟选择服务端IP

参考: 《iOS网络请求优化之DNS映射》

方案三:使用基于 HTTP 的 DNS 解析方案

对于服务器IP经常变的情况,可能需要使用第三方服务,比如DNSPod、httpDNS。

默认的 DNS 是基于 UDP,改用 HTTP 协议进行域名解析,代替现有基于 UDP 的 DNS 协议,域名解析请求直接发送到指定的第三方 DNS 解析服务器,从而绕过运营商的 Local DNS,能够避免 Local DNS 造成的域名劫持问题和调度不精准问题。

绕过运营商直接连可以信任的第三方服务。

enter image description here

那如果这些第三方解析商服务也挂掉了呢?这里有一个折中的方案,你可以两个服务都使用,其中一个作为失败重试的备选项,首选和备选的优先级可以调整。

参考:

  1. 《DNSPod接入指南》
  2. 《腾讯云DNSPod域名解析全面支持IPv6-only》

实现时的问题

发送 HTTPS 请求首先要进行 SSL/TLS 握手,握手过程大致如下:

  1. 客户端发起握手请求,携带随机数、支持算法列表等参数。
  2. 服务端收到请求,选择合适的算法,下发公钥证书和随机数。
  3. 客户端对服务端证书进行校验,并发送随机数信息,该信息使用公钥加密。
  4. 服务端通过私钥获取随机数信息。

最后,双方根据以上交互的信息生成session ticket,用作该连接后续数据传输的加密密钥。

上述过程中,和我们的方案有关的是第3步,客户端需要验证服务端下发的证书,验证过程有以下两个要点:

  • 客户端用本地保存的根证书解开证书链,确认服务端下发的证书是由可信任的机构颁发的。
  • 客户端需要检查证书的domain域和扩展域,看是否包含本次请求的host。

如果上述两点都校验通过,就证明当前的服务端是可信任的,否则就是不可信任,应当中断当前连接。

当客户端使用基于HTTP的第三方解析服务解析域名时,请求URL中的host会被替换成解析出来的IP,所以在证书验证的第2步,会出现domain不匹配的情况,导致SSL/TLS握手不成功。

解决方案:

https 请求,需要 Overriding TLS Chain Validation Correctly;

如果使用第三方网络库:curl, 中有一个 -resolve 方法可以实现使用指定 ip 访问 https 网站,iOS 中集成 curl 库,参考 curl文档 ;它也是支持 IPv6 环境的,只需要你在 build 时添加上 --enable-ipv6 即可。

如果使用AFN,则需要重写AFN里的一些方法,具体步骤是:hook 住 SSL 握手方法,也就是上图中的第2步,对应于下面的方法:

 /*
 * NSURLSession
 */
 - (void)connection:(NSURLConnection *)connectionwillSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
/*
 * NSURLSession
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler

然后将IP直接替换成原来的域名,再执行证书验证。

具体参考:

  1. 《如何使用ip直接访问https网站?》
  2. 《HTTPS业务场景解决方案》

了解最新移动开发、VR/AR 相关信息和技术,请关注 mobilehub 公众微信号(ID: mobilehub)。

IOS编程 浅析

阅读数 17095

阿里iOS三面

阅读数 25677