当前位置: 首页 > 科技观察

iOS9适配肯定会遇到的大坑大集合

时间:2023-03-23 10:31:11 科技观察

本篇主要说说iOS9适配中出现的一些坑。如果你只是想简单了解iOS9的新特性,可以看看iOS开发者需要了解的9SDK新特性。9月17日凌晨,苹果向用户推送了iOS9正式版。随着部分用户升级到iOS9,一系列的问题也逐渐浮出水面。作者也在抓紧适配自己维护的App。有些坑基本都是亲身体验过的。1、NSAppTransportSecurityiOS9允许所有HTTP默认使用HTTPS,将原来的HTTP协议传输改为TLS1.2协议传输。直接的结果就是App发送请求的时候,弹出网络无法连接。解决方法是在项目的info.plist文件中加入如下节点:NSAppTransportSecurity-NSAllowsArbitraryLoads这个子节点的意思是:是否允许任意加载?!将其设置为YES将禁用AppTransportSecurity并改用用户定义的设置,从而解决问题。上面说了苹果对HTTP协议进行了限制,但并不代表所有的HTTPS都能完美适配iOS9。例如,webView从应用程序中加载https网页。新建一个项目,写几行网页代码-(void)loadView{UIWebView*web=[[UIWebViewalloc]initWithFrame:[UIScreenmainScreen].bounds];self.view=web;}-(void)viewDidLoad{[superviewDidLoad];UIWebView*web=(UIWebView*)self.view;//董伯然NSURL*url=[NSURURRLWithString:@"https://github.com/"];NSURLRequest*request=[NSURLRequestrequestWithURL:url];[webloadRequest:request];}中间的url就是我们要加载的https地址。分别用https://baidu.com/和https://github.com/试试。结果不同。github网页可以打开,百度网页可以打开不行,下面打印一行logNSURLSession/NSURLConnectionHTTPloadfailed(kCFStreamErrorDomainSSL,-9802)。原因是苹果官方的资料说必须首先基于TLS1.2协议。然后证书的加密算法需要达到SHA256或更高的RSA密钥或ECC密钥,否则请求将被中断并返回nil。您可以直接在浏览器中查看本网站的加密算法,先点击绿色锁头,再点击证书信息。从右边两张图可以看出,github的RSA加密的SHA-256满足Apple的要求,所以可以显示。对于百度,可以在info.plist中配置如下。如果有很多网站引用,应该为每个网站配置。NSAppTransportSecurity,NSExceptionDomains,NSIncludesSubdomains,NSExceptionRequiresForwardSecrecy,NSExceptionAllowInsecureHTTPLoads写在下面以便于复制。其中ForwardSecrecy被理解为一种高级密码保护算法,官方资料中有写到,一共有11种。配置后百度就可以访问了。2、对Bitcode的理解bitcode应该是一种编译程序的过渡代码,然后Apple将过渡代码编译成可执行程序。Bitcode还允许Apple在后期对我们程序的二进制文件进行重新优化,类似于app瘦身的思路。使用xcode7编译器编译之前没有问题的工程,可能会出现如下错误。XXXX'不包含位码。你必须重新构建它并启用位码(Xcode设置ENABLE_BITCODE),从供应商处获取更新的库,或者为此目标禁用位码。对于架构arm64,问题的原因是某些第三方库尚不支持位码。要么等待库的开发人员升级此功能,然后我们更新库,要么禁用此位码。禁用的方法是找到下面的配置,选择NO。(iOS中的bitcode默认为YES,watchOS中的bitcodes必须为YES,不允许更改。)3.设置trust此项只与企业级应用或inhose相关,与AppStore渠道应用无关。在iOS8中只是弹窗询问是否需要让手机信任这个应用,而在iOS9中是直接禁止的。如果你真的想要信任,你需要自己手动打开它。类似在Mac系统上从不知名开发商下载的dmg无法直接打开,需要在系统偏好设置的安全和隐私设置中手动打开。下图左边是iOS8,右边是iOS9。用户需要到设置---“通用---”描述文件中自行添加信任。处理这类问题的方法有两种:1.提前知道暂时不要升级iOS9。2、多为公司员工使用的企业级应用,发群指导邮件。4、字体在iOS8中,字体为Helvetica,中文字体有点类似于“ChineseThinBlack”。只是苹果手机自带渲染图,所以看起来可能比普通的中国细黑好看。在iOS9中,中文系统字体改为了专为中国设计的“萍芳”,有点类似于“悠远”的文字字体。字体有轻微的粗体效果,最重要的是字体空隙变大了!因此,很多有死宽的标签可能会出现“...”。上面两张图也可以直观的看到相同的界面,相同的标签变化。所以,为了不让界面显示出错,即使是定长文本,也建议使用sizetofit或者ios四舍五入ceilf()或者计算CGSizesize=[titlesizeWithAttributes:@{NSFontAttributeName:[UIFontsystemFontOfSize:14.0f]}];CGSizeadjustedSize=CGSizeMake(ceilf(size.width),ceilf(size.height));5.URLschemeURLscheme一般在应用有分享或跳转到其他平台授权,分享或授权后跳转回来的功能时使用。iOS8没有太多的限制,但是iOS9需要把你要对外调用的URLscheme加入白名单,才能完成跳转。如果iOS9不适配,会报如下错误canOpenURL:failedforURL:"mqzone://qqapp"-error:"Thisappisnotallowedtoqueryforschememqzone"具体解决方法是将info.plist中的LSApplicationQueriesSchemes类型设置为数组,将所有的您在下面使用的方案。不会有问题的。<错误>:CGContextSaveGState:invalidcontext0x0。如果要查看回溯,请设置CG_CONTEXT_SHOW_BACKTRACE环境变量。以前为了能够实时控制顶部statusbar的样式,我们可能喜欢用[[UIApplicationsharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent][[UIApplicationsharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent]但是在YApplicationshared之前;需要将info.plist中的Viewcontroller-basedstatusbarappearanceBOOL值添加为NO,即禁用controller控制状态栏的权限,使用UIApplication来控制。但是在iOS9中不推荐这种方式。建议我们使用它,将BOOL值设置为YES,然后使用controller方法来管理状态栏,例如。-(UIStatusBarStyle)preferredStatusBarStyle{returnUIStatusBarStyleLightContent;}点进头文件验证刚才说的:@property(readwrite,nonatomic,getter=isStatusBarHidden)BOOLstatusBarHiddenNS_DEPRECATED_IOS(2_0,9_0,"Use-[UIViewControllerprefersFinishWishBardenifrunning]);当报如下错误时,说明你的didFinishLaunchingWithOptions写错了*****Assertionfailurein-[UIApplication_runWithMainScene:transitionContext:completion:],/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m:3294**iOS9不允许在didFinishLaunchingWithOptions结束后设置窗口的rootViewController。可能xcode7编译器本身不支持吧。解决办法当然是先初始化一个值,然后给它赋值来代替UIWindow*window=[[UIWindowalloc]initWithFrame:[UIScreenmainScreen].bounds];window.rootViewController=[[UIViewControlleralloc]init];正式版已经推送了,但是当你使用iOS9的时候,还是会觉得App比以前更卡了。拖动tableView时,冻结最为明显。而且我之前遇到过一个bug,本来好好的项目是用xcode7编译的,tableView的刷新有问题,[tableViewreloadData]无效,有一行cells改变了但是无法刷新。感觉这个方法可能和一些新增加的特性有冲突。可能是reloadData的操作被推迟到下一次RunLoop执行最后失败了。解决方法是注释掉[tableViewreloadData],改用局部刷新,其实问题就解决了。[self.tableViewreloadSections:[NSIndexSetindexSetWithIndex:0]withRowAnimation:UITableViewRowAnimationNone];如果您没有在董伯然博客园阅读本文,请点击查看原文。暂时遇到这些问题,感觉iOS9的出现让所有的iOS开发都变成了菊花。我希望Apple能够做出重大改变。特立独行的风格开发出来后,不会和政府发生冲突,然后公司倒闭,开发商就会失业。也许是我想多了。希望所有的iOS版本都能及时适配和修正,所有的问题都会在下个版本上线时得到解决。