1.iOS9网络适配_ATS:改用更安全的HTTPS(见Demo1)
i.WHAT(什么是SSL/TLS?跟HTTP和HTTPS有什么关系)
ii.WHY(以前的HTTP不是也能用吗?为什么要用SSL/TLS?Apple是不是又在反人类?)
iii.HOW(如何适配?---弱弱地问下:加班要多久?)
a.第1种情况:HTTPSOnly(只有HTTPS,所有情况下都使用ATS)
b.第2种情况:Mix&Match(混合)
c.第3种情况:OptOut(禁用ATS)
d.第4种情况:OptOutWithExceptions(除特殊情况外,都不使用ATS)
e.CertificateTransparency
iv.Q-A
2.iOS9新特性_更灵活的后台定位(见Demo2)
3.企业级分发
i.iOS9以后,企业级分发ipa包将遭到与Mac上dmg安装包一样的待遇:默认不能安装,也不再出现“信任按钮”
ii.iOS9以后,企业分发时可能存在:下载的ipa包与网页两者的bundleID无法匹配而导致下载失败的情况
4.Bitcode
5.iOS9URLScheme适配_引入白名单概念(见Demo3)
i.常见URLScheme
ii.Q-A
6.iPad适配SlideOver和SplitView
7.字体间隙变大导致UI显示异常
8.升级Xcode7后的崩溃与警告
i.iOS9下使用Masonry会引起崩溃的一种情况
ii.Xcode升级后,旧的状态栏的样式设置方式会引起警告
a.Demo4---navigationController状态栏样式新的设置方法
iii.Xcode7在debug状态下也生成.dSYM文件引起的警告
iv.Xcode7无法使用8.x系统的设备调试,一运行就报错thereisanintenalAPIerror
v.使用了HTML的iframe元素可能导致无法从Safari跳转至App
vi.iOS9锁屏控制台会打印警告
vii.Xcode7上传应用时提示ITMS-90535UnabletopublishiOSappwithxxxSDK的问题
9.Demo5、Demo6---搜索API
10.iOS国际化问题:当前设备语言字符串返回有变化
1.Demo1_iOS9网络适配_ATS:改用更安全的HTTPS
一个符合ATS要求的HTTPS,应该满足如下条件:
TransportLayerSecurity协议版本要求TLS1.2以上
服务的Ciphers配置要求支持ForwardSecrecy等
证书签名算法符合ATS要求等
注:有童鞋反映:服务器已支持TLS1.2SSL,但iOS9上还是不行,还要进行本文提出的适配操作。
那是因为:要注意AppTransportSecurity要求TLS1.2,而且它要求站点使用支持forwardsecrecy协议的密码。证书也要求是符合ATS规格的,ATS只信任知名CA颁发的证书,小公司所使用的selfsignedcertificate,还是会被ATS拦截。。因此慎重检查与你的应用交互的服务器是不是符合ATS的要求非常重要。对此,建议使用下文中给出的NSExceptionDomains,并将你们公司的域名挂在下面。下文也会详细描述该问题。
"CertificatesmustbesignedusingaSHA256orbettersignaturehashalgorithm,witheithera2048bitorgreaterRSAkeyora256bitorgreaterElliptic-Curve(ECC)key.Invalidcertificatesresultinahardfailureandnoconnection"
在讨论之前,跟往常一样,先说下iOS程序猿们最关心的问题:
跟我有毛关系?需要我加班吗?!
这是某社交App上讨论,看来业内还是吐槽声和肯定声同在。
结论是:"跟你很有关系,加班吧,少年!"
书归正传【严肃脸】,我们正式讨论下WHAT,WHY,HOW:
WHAT(什么是SSL/TLS?跟HTTP和HTTPS有什么关系)
WHY(以前的HTTP不是也能用吗?为什么要用SSL/TLS?!Apple是不是又在反人类?)
HOW(如何适配?---弱弱地问下:加班要多久?)
1.WHAT(什么是SSL/TLS?跟HTTP和HTTPS有什么关系)
什么是SSL/TLS?SSL你一定知道,在此不做赘述。主要说下什么是TLS,还有跟HTTP和HTTPS有什么关系。
TLS是SSL新的别称:
“TLS1.0”之于“SSL3.1”,犹“公元2015”之于“民国104”,“一千克”之于“一公斤”:称呼不同,意思相同。
SSL3.0版本之后的迭代版本被重新命名为TLS1.0:TLS1.0=SSL3.1。所以我们平常也经常见到“SSL/TLS”这种说法。
目前,应用最广泛的是TLS1.0,接下来是SSL3.0。目前主流浏览器都已经实现了TLS1.2的支持。
常用的有下面这些:
SSL2.0
SSL3.0
TLS1.0(SSL3.1)
TLS1.1(SSL3.1)
TLS1.2(SSL3.1)
那为什么标题是“使用HTTPS”而没有提及SSL和TLS什么事?“SSL/TLS”跟HTTP和HTTPS有什么关系?
要理解这个,要看下他们之间的关系:
HTTP+SSL/TLS+TCP=HTTPS
或者:HTTPS=“HTTPoverSSL”
也就是说:Apple让你的HTTP采用SSL/TLS协议,就是让你从HTTP转到HTTPS。而这一做法,官方文档称为ATS,全称为AppTransportSecurity。
2.WHY(以前的HTTP不是也能用吗?为什么要用SSL/TLS?Apple是不是又在反人类?)
不使用SSL/TLS的HTTP通信,就是不加密的通信!
不使用SSL/TLS的HTTP通信,所有信息明文传播,带来了三大风险:
窃听风险(eavesdropping):第三方可以获知通信内容。
篡改风险(tampering):第三方可以修改通信内容。
冒充风险(pretending):第三方可以冒充他人身份参与通信。
SSL/TLS协议是为了解决这三大风险而设计的,希望达到:
所有信息都是加密传播,第三方无法窃听。
具有校验机制,一旦被篡改,通信双方会立刻发现。
配备身份证书,防止身份被冒充。
SSL/TLS的作用,打个比方来讲:
如果原来的HTTP是塑料水管,容易被戳破;那么如今新设计的HTTPS就像是在原有的塑料水管之外,再包一层金属水管(SSL/TLS协议)。一来,原有的塑料水管照样运行;二来,用金属加固了之后,不容易被戳破。
3.HOW(如何适配?---弱弱地问下:加班要多久?)
总之:
要么咱们iOS程序猿加班,要么后台加班:
这也是官方文档和WWDC给出的解决方案:
即使你的应用使用的是:你没有权限控制的CDN(ContentDeliveryNetwork),而且它不支持HTTPS!
也别担心,Apple都替你考虑好了:
正如你在上图中看到的:苹果官方提供了一些可选配置项来决定是否开启ATS模式,也就是可以选择开启或者不开启。
开发者可以针对某些确定的URL不使用ATS,这需要在工程中的info.plist中标记NSExceptionDomains。在NSExceptionDomains字典中,可以显式的指定一些不使用ATS的URL。这些你可以使用的例子可以是:
NSIncludesSubdomains
NSExceptionAllowInsecureHTTPLoads
NSExceptionRequiresForwardSecrecy
NSExceptionMinimumTLSVersion
NSThirdPartyExceptionAllowsInsecureHTTPLoads
NSThirdPartyExceptionMinimumTLSVersion
NSThirdPartyExceptionRequiresForwardSecrecy
这些关键字使我们可以更加细致的设置针对不使用ATS的域名情况下禁用ATS或者一些特殊的ATS选项。
你可能注意到一些关键字像是使用了一些其他关键字中的词但是在前面加上了"ThirdParty"字样,比如列表里最后三个:
在功能上,这些关键字与不含有"ThirdParty"的关键字有同样的效果。而且实际运行中所调用的代码将会完全忽略是否使用"ThirdParty"关键字。你应该使用适用于你的场景的关键字而不必过多考虑这些。
关于AppTransportSecurity,每个应用都属于4个大类当中的一类。我们来看看每一个大类都是怎样影响应用的。
下面分别做一下介绍:
1.HTTPSOnly(只有HTTPS,所有情况下都使用ATS)
如果你的应用只基于支持HTTPS的服务器,那么你太幸运了。你的应用不需要做任何改变。
唯一需要做的事情就是使用NSURLSession。如果你的开发目标是iOS9或者OSXEICapitan之后,ATS的最佳实践将会应用到所有基于NSURLSession的网络。
但也有人遇到过这样的疑惑:服务器已支持TLS1.2SSL,但iOS9上还是不行,还要进行本文提出的适配操作。
那是因为:要注意AppTransportSecurity要求TLS1.2,而且它要求站点使用支持forwardsecrecy协议的密码。证书也要求是符合ATS规格的,ATS只信任知名CA颁发的证书,小公司所使用的selfsignedcertificate,还是会被ATS拦截。。因此慎重检查与你的应用交互的服务器是不是符合ATS的要求非常重要。对此,建议使用下文中给出的NSExceptionDomains,并将你们公司的域名挂在下面。
CertificatesmustbesignedusingaSHA256orbettersignaturehashalgorithm,witheithera2048bitorgreaterRSAkeyora256bitorgreaterElliptic-Curve(ECC)key.Invalidcertificatesresultinahardfailureandnoconnection
2.Mix&Match(混合)
你的应用与一个不符合ATS要求的服务器工作是很有可能的,
当你遇到以下三个不符合ATS要求的服务器的域名时:
api.insecuredomain.com
cdn.domain.com
thatotherdomain.com
你可以分别设置如下:
Info.plist配置中的XML源码如下所示:
在plist文件里显示如下:
cdn.domain.comInfo.plist配置中的XML源码如下所示:
很可能你的应用是与一个支持HTTPS传输数据的服务器交互,但是并没有使用TLS1.2或更高。在这种情况下,你定义一个“例外”(Exception),它指明应该使用的最小的TLS的版本。这比完全撤销那个域名的AppTransportSecurity要更好更安全。
如果你的App中同时用到了这三个域名,那么应该是这样:
3.OptOut(禁用ATS)
上面是比较严谨的做法,指定了能访问哪些特定的HTTP。当然也有暴力的做法:彻底倒退回不安全的HTTP网络请求,能任意进行HTTP请求,比如你在开发一款浏览器App,或者你想偷懒,或者后台想偷懒,或者公司不给你升级服务器。。。
你可以在Info.plist配置中改用下面的XML源码:
4.OptOutWithExceptions(除特殊情况外,都不使用ATS)
上面已经介绍了三种情景,还有一种可能你也会遇到:
当你的应用撤消了AppTransportSecurity,,但同时定义了一些“例外”(Exception)。当你的应用从很多的服务器上取数据,但是也要与一个你可控的API交互。在这种情况下,在应用的Info.plist文件中指定任何加载都是被允许的,但是你也指定了一个或多个“例外”(Exception)来表明哪些是必须要求AppTransportSecurity的。下面是Info.plist文件应该会有的内容:
5.CertificateTransparency
虽然ATS大多数安全特性都是默认可用的,CertificateTransparency是必须设置的。如果你有支持CertificateTransparency的证书,你可以检查NSRequiresCertificateTransparency关键字来使用CertificateTransparency。再次强调,如果你的证书不支持CertificateTransparency,此项需要设置为不可用。
如果需要调试一些由于采用了ATS而产生的问题,需要设置CFNETWORK_DIAGNOSTICS为1,这样就会打印出包含被访问的URL和ATS错误在内的NSURLSession错误信息。要确保处理了遇到的所有的错误消息,这样才能使ATS易于提高可靠性和扩展性。
6.Q-A
Q:我用xcode7编译的app,如果不在plist里面加关键字说明,ios9下不能进行网络请求,因为我们服务器并不支持TLS1.2,我要是直接下载appstore上的,什么也没有做,也是能正常网络请求。
A:本文中所罗列的新特性,多数情况下指的是iOS9.X-SDK新特性,AppStore的版本是基于iOS8.X-SDK或iOS7.X-SDK,所以并不受iOS9新特性约束。也就是说:Xcode7给iOS8打设备包可以请求到网络,Xcode7给iOS9设备打的包请求不到网络,Xcode7和iOS9缺一不可,才需要网络适配ATS。
那么,如何确认自己项目所使用的SDK?在Targets->BuildSetting-->Architectures
Q:服务器已支持TLS1.2SSL,但iOS9上还是不行,还要进行本文提出的适配操作。
A:那是因为:要注意AppTransportSecurity要求TLS1.2,而且它要求站点使用支持forwardsecrecy协议的密码。证书也要求是符合ATS规格的,ATS只信任知名CA颁发的证书,小公司所使用的selfsignedcertificate,还是会被ATS拦截。。因此慎重检查与你的应用交互的服务器是不是符合ATS的要求非常重要。对此,建议使用下文中给出的NSExceptionDomains,并将你们公司的域名挂在下面。
Q:我使用的是第三方的网络框架,比如AFNetworking、ASIHTTPRequest、CFSocket等,这个有影响没有?
A:AFNetworking有影响,其它没影响。
ATS是只针对NSURLConnection、CFURL、NSURLSession,如果底层涉及到这三个类就会有影响。
现在的AFNetworking的AFHTTPRequestOperationManager实现是使用的NSURLConnection。
TheresourcecouldnotbeloadedbecausetheAppTransportSecuritypolicyrequirestheuseofasecureconnection.
A:遇到这类问题,90%是出现在“一个Project多Target”的情况下,所以请确保你修改的,确实是你的Target所属的Info.plist!
如何确认?请前往这里,确认你Target所属的Info.plist究竟是哪个:
Project->YourTarget->BuildSettings->Info.plistFile
或者更直截了当一点,直接修改:
Project->YourTarget—>info->CustomiOStargetproperties->添加禁用ATS的属性
还有一种可能性是:禁用ATS的代码粘贴进plist时,位置不对,可以尝试放在diwuhang
Q:我的项目是“一个Project多Target”,按照本文禁用ATS的方法,是不是每个Info.plist都要修改?
A:不需要,用到哪个Target修改哪个的Info.plist,Target是独立的,不受其他Target的影响,也不会影响其他Target。
Q:如何检测我们公司HTTPS是否符合ATS的要求?
A:如果你的App的服务也在升级以适配ATS要求,可以使用如下的方式进行校验:
在OSXEICapitan系统的终端中通过nscurl命令来诊断检查你的HTTPS服务配置是否满足Apple的ATS要求:
当然,你也可以让公司服务端的同事参考Apple提供官方指南AppTransportSecurityTechnote进行服务的升级配置以满足ATS的要求:
2.Demo2_iOS9新特性_更灵活的后台定位
【iOS9在定位的问题上,有一个坏消息一个好消息】坏消息:如果不适配iOS9,就不能偷偷在后台定位(不带蓝条,见图)!好消息:将允许出现这种场景:同一App中的多个locationmanager:一些只能在前台定位,另一些可在后台定位,并可随时开启或者关闭特定locationmanager的后台定位。
如果没有请求后台定位的权限,也是可以在后台定位的,不过会带蓝条:enterimagedescriptionhere
如何偷偷在后台定位:请求后台定位权限:
但是如果照着这种方式尝试,而没有配置Info.plist,100%你的程序会崩溃掉,并报错:
***Assertionfailurein-[CLLocationManagersetAllowsBackgroundLocationUpdates:],/BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreLocationFramework_Sim/CoreLocation-1808.1.5/Framework/CoreLocation/CLLocationManager.m:593
对应的Info.plist的XML源码是:
有两处变化:
iOS9以后,企业级分发ipa包将遭到与Mac上dmg安装包一样的待遇:默认不能安装,也不再出现“信任按钮”
iOS9以后,企业分发时可能存在:下载的ipa包与网页两者的bundleID无法匹配而导致下载失败的情况
1.iOS9以后,企业级分发ipa包将遭到与Mac上dmg安装包一样的待遇:默认不能安装,也不再出现“信任按钮”
iOS9之前,企业级分发十分方便:点击App出现“信任按钮”,
必须让用户进行gif图中的设置:
2.iOS9以后,企业分发时可能存在:下载的ipa包与网页两者的bundleID无法匹配而导致下载失败的情况
iOS9升级后众多企业分发的app已经出现了不能安装的情况,而iOS8或更早的系统不受影响。那是因为从iOS9以后,系统会在ipa包下载完之后,拿ipa包中的bundleID与网页中的plist文件中的bundleID进行比对,不一致不允许安装。
错误提示如下:
而iOS9之前,苹果不会检查这一项,因此iOS9之前可以安装。
导致这一错误的原因除了粗心,还有开发者是故意设置不一致,据开发者说:
当初服务器plist的bundleid上故意做成成不一致。是为了解决一些人安装不上的问题。
如何知道是因为bundleid不一致造成的无法安装?
通过查看设备上的日志信息:有一个itunesstored进程提示安装信息:
其中的这一句很重要:
经过核对,果然是.ipa文件中真实的BundleID和manifest文件中配置的信息不匹配,然后测试发现:
iOS9是校验bundle-identifier值的,而iOS9以下版本是不校验,一旦iOS9发现bundle-identifier不匹配,即使下载成功了,也会Uninstall(日志中提示的)app的。
适配方法:
a.两者的bundleid修改一致
一旦出现iOS9能够安装企业版本APP,iOS9以下版本不能安装,一定先查看安装日志,然后核对每个参数配置。
manifest文件的参考配置。
b.使用fir.im等第三方分发平台:上述“bundleid不一致导致下载失败”这种情况只会出现在企业自己搭建网页分发的情形下,事实证明第三方的分发平台更加专业,已经很好地规避了该情况的发生。
Q-A
Q:企业分发,企业版证书在iOS9上安装应用报Ignoremanifestdownload,alreadyhavebundleID:com.mycom.MyApp只有我的手机无法安装,别人iOS9都可以安装
A:这并非iOS9的问题,iOS8及以前的系统也会出现,和缓存有关系,请尝试关机重启手机,然后就可以安装了。
【前言】未来,Watch应用必须包含bitcode,iOS不强制,MacOS不支持。但最坑的一点是:Xcode7及以上版本会默认开启bitcode。
什么是bitcode?
通俗解释:在线版安卓ART模式。
Bitcodeisanintermediaterepresentationofacompiledprogram.AppsyouuploadtoiTunesConnectthatcontainbitcodewillbecompiledandlinkedontheAppStore.IncludingbitcodewillallowAppletore-optimizeyourappbinaryinthefuturewithouttheneedtosubmitanewversionofyourapptothestore.
翻译过来就是:
bitcode是被编译程序的一种中间形式的代码。包含bitcode配置的程序将会在AppStore上被编译和链接。bitcode允许苹果在后期重新优化我们程序的二进制文件,而不需要我们重新提交一个新的版本到AppStore上。
Bitcode.WhenyouarchiveforsubmissiontotheAppStore,Xcodewillcompileyourappintoanintermediaterepresentation.TheAppStorewillthencompilethebitcodedownintothe64or32bitexecutablesasnecessary.
也就是
当我们提交程序到AppStore上时,Xcode会将程序编译为一个中间表现形式(bitcode)。然后Appstore会再将这个bitcode编译为可执行的64位或32位程序。
再看看这两段描述都是放在AppThinning(App瘦身)一节中,可以看出其与包的优化有关了。
打个比方,没有bitcode的AppStore里所提供的App,类似在新华书店里卖捆绑销售的《四大名著丛书--精装版》,要买只能全买走,有了bitcode就好比这套四大名著每本都可以单卖,顾客就能按需购买。我们开发者在这个过程中扮演的角色是图书出版商的角色,应该照顾那些没钱一次买四本的顾客。(不要做不珍惜用户流量和存储空间的奸商。。)
那为什么第三方的SDK不支持bitcode,我的app也就不能支持?打个比方,《四大名著丛书》只要有一本是可以单卖的,那么你很难再卖捆绑销售款的《四大名著丛书》了,所以干脆全都可以单卖,这大概就是Apple的逻辑。
AppThinning官方文档解释如下:
TheAppStoreandoperatingsystemoptimizetheinstallationofiOSandwatchOSappsbytailoringappdeliverytothecapabilitiesoftheuser’sparticulardevice,withminimalfootprint.Thisoptimization,calledappthinning,letsyoucreateappsthatusethemostdevicefeatures,occupyminimumdiskspace,andaccommodatefutureupdatesthatcanbeappliedbyApple.Fasterdownloadsandmorespaceforotherappsandcontentprovidesabetteruserexperience.
开发者都知道,当前iOSApp的编译打包方式是把适配兼容多个设备的执行文件及资源文件合并一个文件,上传和下载的文件则包含了所有的这些文件,导致占用较多的存储空间。
AppThinning是一个关于节省iOS设备存储空间的功能,它可以让iOS设备在安装、更新及运行App等场景中仅下载所需的资源,减少App的占用空间,从而节省设备的存储空间。
根据Apple官方文档的介绍,AppThinning主要有三个机制:
①Slicing
开发者把App安装包上传到AppStore后,Apple服务会自动对安装包切割为不同的应用变体(Appvariant),当用户下载安装包时,系统会根据设备型号下载安装对应的单个应用变体。
②On-DemandResources
ORD(随需资源)是指开发者对资源添加标签上传后,系统会根据App运行的情况,动态下载并加载所需资源,而在存储空间不足时,自动删除这类资源。
Bitcode开启Bitcode编译后,可以使得开发者上传App时只需上传IntermediateRepresentation(中间件),而非最终的可执行二进制文件。在用户下载App之前,AppStore会自动编译中间件,产生设备所需的执行文件供用户下载安装。
其中,Bitcode的机制可以支持动态的进行AppSlicing,而对于Apple未来进行硬件升级的措施,此机制可以保证在开发者不重新发布版本的情况下而兼容新的设备。
如果你的应用也准备启用Bitcode编译机制,就需要注意以下几点:
Xcode7默认开启Bitcode,如果应用开启Bitcode,那么其集成的其他第三方库也需要是Bitcode编译的包才能真正进行Bitcode编译
开启Bitcode编译后,编译产生的.app体积会变大(中间代码,不是用户下载的包),且.dSYM文件不能用来崩溃日志的符号化(用户下载的包是Apple服务重新编译产生的,有产生新的符号文件)
通过Archive方式上传AppStore的包,可以在Xcode的Organizer工具中下载对应安装包的新的符号文件
如何适配?
在上面的错误提示中,提到了如何处理我们遇到的问题:
Youmustrebuilditwithbitcodeenabled(XcodesettingENABLE_BITCODE),obtainanupdatedlibraryfromthevendor,ordisablebitcodeforthistarget.forarchitecturearm64
正如开头所说的:
未来,Watch应用必须包含Bitcode,iOS不强制,MacOS不支持。但最坑的一点是:Xcode7及以上版本会默认开启Bitcode。
Xcode7+会开启Bitcode。
也就是说,也两种方法适配:
方法一:更新library使包含Bitcode,否则会出现以下中的警告;
(null):URGENT:allbitcodewillbedroppedbecause'/Users/myname/Library/MobileDocuments/com~apple~CloudDocs/foldername/appname/GoogleMobileAds.framework/GoogleMobileAds(GADSlot+AdEvents.o)'wasbuiltwithoutbitcode.Youmustrebuilditwithbitcodeenabled(XcodesettingENABLE_BITCODE),obtainanupdatedlibraryfromthevendor,ordisablebitcodeforthistarget.Note:Thiswillbeanerrorinthefuture.
甚至有的会报错误,无法通过编译:
ld:‘/Users//Framework/SDKs/PolymerPay/Library/mobStat/libSDK.a(**ForSDK.o)’doesnotcontainbitcode.Youmustrebuilditwithbitcodeenabled(XcodesettingENABLE_BITCODE),obtainanupdatedlibraryfromthevendor,ordisablebitcodeforthistarget.forarchitecturearm64
或:
ld:-undefinedand-bitcode_bundle(XcodesettingENABLE_BITCODE=YES)cannotbeusedtogetherclang:error:linkercommandfailedwithexitcode1(use-vtoseeinvocation)
enterimagedescriptionhere
无论是警告还是错误,得到的信息是:我们引入的一个第三方库不包含bitcode。
方法二:关闭Bitcode,方法见下图
我们可以在”BuildSettings”->”EnableBitcode”选项中看到:
用Xcode7+新建一个iOS程序时,bitcode选项默认是设置为YES的。现在需要改成NO。
如果我们开启了bitcode,在提交包时,下面这个界面也会有个bitcode选项:
那么SDK厂商如何支持bitcode呢?答案是只要在Xcode7上重新编译一下就ok了。(请确保默认开启的bitcode没有去主动关闭)
更多信息,请移步
5.Demo3---iOS9URLScheme适配_引入白名单概念
也就是说:在iOS9中,如果使用canOpenURL:方法,该方法所涉及到的URLscheme必须在"Info.plist"中将它们列为白名单,否则不能使用。key叫做LSApplicationQueriesSchemes,键值内容是
白名单上限是50个:
“SoforappsthatarelinkedbeforeiOS9andarerunningoniOS9,theywillbegiven50distinctURLschemes.”--WWDC2015session703PrivacyandYourApp
iOS9中openURL:方法没有什么实质性的变化,仅仅多了一个确认动作:
苹果为什么要这么做?
这也许就是原因。
Demo结构如下:
主要演示的情景是这样的:
(以上只是为了演示,实际开发中,你不仅需要添加“weixin”还需要“wechat”这两个。具体)
Ifyoucallthe“canOpenURL”methodonaURLthatisnotinyourwhitelist,itwillreturn“NO”,evenifthereisanappinstalledthathasregisteredtohandlethisscheme.A“Thisappisnotallowedtoqueryforschemexxx”syslogentrywillappear.
常见URLScheme
plist文件看起来会是这样的:
其他平台可在下面的列表中查询:各平台OpenURL白名单说明:
Q:我用xcode7编译的app,如果不在plist里面加scheme,ios9下qq就会不显示,因为我用了qqsdk里的判断是否安装qq的方法,我要是直接下载appstore上的,没有加scheme,qq也是能显示。
A:本文中所罗列的新特性,多数情况下指的是iOS9.X-SDK新特性,AppStore的版本是基于iOS8.X-SDK或iOS7.X-SDK,所以并不受iOS9新特性约束。也就是说:Xcode7给iOS8打设备包不需要白名单也能调用“canOpenURL”,Xcode7给iOS9设备打的包则不然,Xcode7和iOS9缺一不可,才需要适配URLScheme。
A:白名单策略影响的仅仅是canOpenURL:接口,OpenURL:不受影响,这些大厂只调用openURL:所以不受iOS9的影响。
Q:文中提到了设置白名单的原因,然而,如果这些别有用心的APP在它自己的白名单列出它关心的APP,然后依次调用canOpenURL来检测,照样可以监控用户都安装了哪些APP啊?所以我依然不明白苹果这样做得原因。
A:白名单的数目上限是50个。苹果这样子做,使得最多只能检测50个App。
Q:按照文中的适配方法,error原因就没有了的确没问题了,但是还是会打印如下信息:
A:这个模拟器的一个bug,无论使用iOS9的真机还是模拟器均出现该问题,估计Xcode后续的升级中会修复掉。
那如何判断日志究竟是Xcodebug造成的还是没有适配造成的?看error的值,如果是null,则是bug。(2015-09-21更)
【iPad适配SlideOver和SplitView】若想适配multitasking特性,唯一的建议:弃纯代码,改用storyboard、xib,纵观苹果WWDC所有Demo均是如此:
iOS8中,字体是Helvetica,中文的字体有点类似于“华文细黑”。只是苹果手机自带渲染,所以看上去可能比普通的华文细黑要美观。iOS9中,中文系统字体变为了专为中国设计的“苹方”有点类似于一种word字体“幼圆”。字体有轻微的加粗效果,并且最关键的是字体间隙变大了!
所以很多原本写死了width的label可能会出现“...”的情况:
如果不将label的width写死,仅仅添加左端约束则右端的四个数字会越界
所以为了在界面显示上不出错,就算是固定长度的文字也还是建议使用sizetofit或者ios向上取整ceilf()或者提前计算:
旧版本新浪微博SDK在iOS9上会导致的Crash
appwascompiledwithoptimization-steppingmaybehaveoddly;variablesmaynotbeavailable
打印出来这句话,然后崩溃。多是启动的过程中程序就崩溃。
在iOS9下,新浪微博SDK里面使用的JSONKit在部分机型可能导致崩溃。崩溃信息如下图。
解决:更新新浪微博SDK,新浪的SDK最新版做了对iOS9兼容。
iOS9下使用Masonry会引起崩溃的一种情况
我们在使用时候一直将leading与left划为等号,这样做在iOS8(及以前)上是正常的,但在iOS9上这样的观念可能会引起崩溃,比如:
应该为:
同理mas_training也需要改为right
Xcode升级后,旧的状态栏的样式设置方式会引起警告
出错原因:设置app的状态栏样式的时候,使用了旧的方式,在info.plist里面的Viewcontroller-basedstatusbarappearance默认会为YES,即使不设置也是YES,但一般iOS6的时候为了设置状态栏样式,需要将其设为NO,iOS7,8也兼容,但是到了iOS9就会报警告。
解决办法:
删除原先的设置代码,通常老的设置方式是这样的:
删除的原因见下:
修改方式是在Info.plist文件中做如下修改:
将Viewcontroller-basedstatusbarappearance删除(默认为YES),或设置为YES:
对应的plist里的XML源码:
看起来长这样:
然后使用新的方式来实现状态栏的样式:
比如,你想将状态栏设置为白色,就可以这样写:
记得要clean下或者删除应用程序重新运行。
Demo4---navigationController状态栏样式新的设置方法
如果你按照上面的方法设置了,但还是不行。八成是rootViewController设置的问题,你必须设置rootViewController,编译器才会去rootViewController中重载preferredStatusBarStyle方法。
另外当你在appdelegate中将navigationController设为rootViewController的时候:
因为rootViewController变为了navigationController,你在ViewController里重写preferredStatusBarStyle方法是不会起作用的。所以最好的方法是
如果你还是想重写preferredStatusBarStyle方法来达到作用,那最好使用分类来解决:
.h文件:
.m文件:
我在仓库里给出了navigation的设置方法,见Demo4。
Xcode7在debug状态下也生成.dSYM文件引起的警告
Xcode6的工程升级到Xcode7上来,会报警告:
这是debug编译时导出符号文件出现的告警,然而新建的Xcode7工程不会有该问题。
解决方法是让debug编译的时候不生成符号文件:
Xcode7无法使用8.x系统的设备调试,一运行就报错thereisanintenalAPIerror
Xcode7调试iOS8.x的真机,需要确保项目名改为英文,中间含有中文会报错thereisanintenalAPIerror
按照下面的步骤检查:
bulidsettings->packaging->productname
使用了HTML的iframe元素可能导致无法从Safari跳转至App
这是很可能是因为使用了HTML的iframe元素,并将自定义的链接放进了该元素中
举例说明:
参考链接:
iOS9锁屏控制台会打印警告
加入运行如下示例代码:
应用运行过程中锁屏,总是会出现以下提示:
当应用处于空闲状态时(无网络请求)锁屏对于用户而言并无较大影响,但是当应用在执行某个异步任务时(比如下拉刷新一下列表)锁屏,重新解锁进入就可能会发现异步任务失败,控制台也会提示Error信息:
以上情况不易复现,但确有发生。
在iOS8系统下测试并未发现此问题。
对此并未找到合理的解释和对应的解决办法,如果你有解决方法,欢迎提PR!
导入两个framework,然后像设置tableView的cell一样设置下每一个“搜索元素”,详情见代码。
既然刚才说了搜索元素与tableView的cell非常相似:那么我们就展示一下如何让tableView与CoreSpotlightSearch进行结合:
详见Demo6,Demo6与Demo5的主要差异在于:在点击搜索结果跳转到App后,还会进一步根据搜索的内容push到相应的详情页中:
10.iOS国际化问题:当前设备语言字符串返回有变化。
iOS9之前:以上返回结果:语言字符串代码。例如:"zh-Hans"
iOS9:以上返回结果:语言字符串代码+地区代码。例如:"zh-Hans-US"
备注:
1.请注意判断当前语言类型,不要用以下形式的代码了,不然在iOS9上就会遇到坑。
可以使用:
另外:对于中文,语言有:
简体中文:zh-Hans
繁体中文:zh-Hant
香港中文:zh-HK
澳门中文:zh-MO
台湾中文:zh-TW
新加坡中文:zh-SG
备注:以上iOS9当前语言字符串返回结果:语言字符串代码+地区代码。在某些情况下不是这样,本人手机型号:大陆版电信iPhone5S/A1533/16GB测试结果:zh-HK/zh-TW,在地区为"中国"、"中国香港"、"中国台湾"的时候,显示的还是zh-HK/zh-TW,一旦切换到其它地区,设备语言会自动的切换到中文繁体。请开发人员注意中文的问题!