查看原文
其他

苹果强制要求更换启动方式的解决方案

花椒iOS 花椒技术 2022-09-07

苹果要求:2020年June 30之前必须将启动方式通过storyboard进行加载。具体参考官方文档(https://developer.apple.com/news/?id=03262020b)。或者可以直接看下面的截图。

注意:启动图如果设置的不正确,那么会影响自己App的主页内容。可能会产生拉伸等问题,这个会在后面详细说明。


准备工作

1. 关于LaunchImage和LaunchScreen.storyboard技术背景

LaunchImageLaunchScreen.storyboard都是加载启动图的一种方式,但是二者有很大区别:

  • LaunchImage出现的要比LaunchScreen.storyboard早些, iOS8以后开始支持LaunchScreen.storyboard
  • LaunchScreen.storyboard的默认优先级高于LaunchImage
  • LaunchScreen.storyboard适配的更灵活些,类似于新做一个界面。LaunchImage只是固定加载image set中的几个图。二种方式尽量不要混用,会有很多不可预知的问题

2. 替换前的一些准备工作

在真正替换之前需要做些准备工作,这里不涉及设计那边的工作,只说一下我们技术相关的。

a) 删除settiing中旧的LaunchImage加载方式设置

删除旧的LaunchImage加载方式

b)删除Asset中旧的启动图

删除Asset中旧的启动图

这些旧的启动图都要删掉,这样也可以减少包的体积,以后这些都用不上了,另外需要说一下这里的图片最大的也是375 * 812的,这样的对于打手机例如414 * 896的,其实主页会有一定的拉伸,最直观的感受就是UI不一样了,这个后面会详细叙述。

c)工程配置新的storyboard启动方式

下面就是在工程设置中设置新的启动方式。

设置新的storyboard启动方式

d)代码层面

其实代码层面我们开发人员可以做的已经很少或者说没有了,因为在进入app程序willFinishLaunchingWithOptions的时候,启动图已经出来了,应该就是iOS系统对App启动图的缓存。目的就是立即显示,增强用户的体验。

是否要新加代码清除缓存,这个就看自己了,有的兄弟公司就是没加任何清除缓存的代码,我这里就清除了下/Library/SplashBoard/Library/Caches/Snapshots目录里的缓存。策略就是检测版本号不同的时候启动就清除下。


几种技术方案

这里首先是要新建一个storyboard,直接新建就行,用苹果给提供的启动页面的storyboard模板。

启动图的storyboard可以当做普通页面去处理了,拖进去控件并设置约束。

下面就是处理新建的启动图的storyboard,有几种处理方案。

1. 只放一张图

这个有人这么做,就是放一张图,按比例进行填充aspect fill。好处就是资源文件只有一张图很省空间,缺点就是不同屏幕的尺寸由于比例扩张和收缩,那么会有部分信息显示不全。

2. 加图片集多张图

这个是新建一个图片集image set里面放各种尺寸的iphoneipad的图片。

这个方案可以很完美不会有任何拉伸问题,而且做起来开发者的工期也不需要,直接就是图片的替换。缺点就是以后机器尺寸多了就要多放图,图都是高清的,即使进行了压缩,那包的体积也会加大很多。

3. 将素材进行分割加载,当成普通的storyboard文件进行处理

这个想法就是将启动图中的元素,包括logo,还有文字等单独切出来,然后像普通页面那样加载控件(UILabel、UIImageView)等。

这解决了不同尺寸屏幕的适配问题以及包资源体积增大的问题。好处就是包体积小了适配各种机型更灵活(但是背景图还是不可避免的要失去部分显示效果),不好的地方就是以后要是换开屏图,那么就要开发者有一定的工作量进行处理。

综述,看上面三个方案,对比研究觉得最后这种方案是最靠谱的并进行了实践,这个也是苹果公司推荐的方案。


几个问题

1. 部分机型适配问题

个别流海屏手机,比如xsmax 12系统机型,使用launchScreen.storyboard 加载启动图,启动图都是正常的,但是到了主页,看见了主页被拉伸,底部的tabBar延伸到了下面的底部,到了安全区。而且亲测在某些xsmax13系统的机型就是正常的。

具体如下图所示:

xsmax 12系统超过安全区

想了很多,为什么启动图正常,但是主页为什么冲出去安全区了呢?而且xsmax 13系统正常,但是只是个别的xsmax 12系统就不正常。

查了很多资料也不知道为什么,一开始一直怀疑是启动图做的launchScreen.storyboard哪里做的不符合苹果的需求。但是找了很久也没发现哪里不对,况且在别的机型也是正常的。

所以有一种猜想,可能是我们自己的代码出问题了。

然后我就找了我们自定义的UITabBarController那里的代码。

发现了一处代码:

- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];

if (!Is375x812hScreen()) {
self.tabBar.frame = CGRectMake(0, KScreenHeight - kDSTabBarHeight, CGRectGetWidth(self.tabBar.frame), kDSTabBarHeight);
}
}

#define Is375x812hScreen() (ABS((double)[[UIScreen mainScreen] bounds].size.height - 812.f) < DBL_EPSILON || ABS((double)[[UIScreen mainScreen] bounds].size.width - 812.f) < DBL_EPSILON) //iphoneX

这里,Is375x812hScreen()17iphoneX出来的时候加的宏,后来xsmax896高的屏幕出来了,进行了更改,改宏就用来定义流海屏了,但是我用真机跑代码的时候,我发现xsmax 12系统的手机进入了if判断语句里面,也就是说被认为了不是流海屏,而用同事的手机xsmax 13系统手机就不会进入if语句,就可以正确被判定是流海屏。我猜想应该就是启动图加载方式变了,所以导致了流程哪里发生了改变,从而使用个别机型系统宏判断出现了错误。

于是,我就修改了下宏,如下所示:

#define Is375x812hScreen() (ABS((double)[[UIScreen mainScreen] bounds].size.height - 812.f) < DBL_EPSILON || ABS((double)[[UIScreen mainScreen] bounds].size.width - 812.f) < DBL_EPSILON || ABS((double)[[UIScreen mainScreen] bounds].size.height - 896.f) < DBL_EPSILON || ABS((double)[[UIScreen mainScreen] bounds].size.width - 896.f) < DBL_EPSILON)

宏修改成这样,xsmax 12系统的手机就被正确认定为流海屏,主页就显示正常了,主页就不冲出安全区了。

具体如下所示:

xsmax 12系统修改后

可以看见下面的安全区留出来了。

同样检查可以看见直播间还有群组页面个别机型也是显示异常了,都需要进行特殊处理和适配,难度不大就是需要心细。

同时,替换后个人中心页面的显示正常没那么拉伸了。

替换前
替换后

2. 黑屏问题

其实关于黑屏可以分解成下面二个详细的小问题:

  • 1) 第一个问题就是和QA模拟版本迭代升级换启动图,发现的问题,就是升级版本号换启动图都正常,但是如果降低版本号,换启动图就是黑屏了。
  • 2) 给背景图UIImageView设置backgroundColor保护色,图片加载不出来的时候保护色不出来的问题。

说实话这二个问题,我们开发者可以活动或者解决的余地不是很大了。

先说第一个小问题。

  • 1) 也许有人会问,用户都是升级,哪里来的降级呢,确实一般都是升级,但是也存在内测,升级版本,然后从store下载版本这种降版本的情况。当然这个是极特殊情况。

这个黑屏问题我真的尝试了不知道多少方法了,但是都不管用:

  • 资源从asset和根目录来回换
  • 用兄弟公司App的启动图尝试
  • 图片命名尽量别用launch开头
  • 清除沙盒里面splashBoard还有cache/snapshot等目录缓存
  • 图片都打开或者关闭alpha通道

等等试了很多方法还是黑屏。只要是升高版本再降低版本,更换的启动图就不会生效,屏幕变黑。

但是这个问题真的自己无解了,毕竟我们程序员可以做的很少了,都是工程配置和一个自建立的storyboardstoryboard里毕竟只是imageViewautolayout

所以这个问题暂时就是搁置了,只能暂时保证升级没问题就行。

下面说下第二个问题

  • 2) 想着降低版本的话,图片image找不到的话,那就给imageView添加个保护色吧,这样不至于黑屏看着难受,可是问题出来了,如果设置了图片,图片没加载出来,imageViewbackgroundColor是不生效的,还是黑色的;但是如果不设置图片名字,run一下就可以看见imageView的背景保护色了。

这个问题我们也是无解的,这个像是什么呢?有点像iOS找不到图片默认给了个黑色的image,所以后面的imageView的背景保护色也是出不来的。

关于这个启动图的更换,想着很简单,但是却碰到了苹果的坑,在stackOverflow上搜索,很多老外以前也遇到了这个问题。也是无解。这里其实有个解决办法,就是卸载App然后重启手机,在下载就都正常了,但是这个操作对于用户操作和体验却是致命的,不过还好版本号升级是没有问题的。猜测是苹果的缓存机制影响到的,这个需要苹果来完善了。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存