iOS12、iOS11、iOS10、iOS9常见适配

栏目: IOS · 发布时间: 5年前

内容简介:Xcode10是默认选中的最新的把删除其他info.plist文件。

Xcode10是默认选中的最新的 New Build System(Default) ,在这个编译系统的环境下,不允许多个info.plist

解决办法一:(推荐)

build system 切换到 Legacy Build System ,换言之就是切换成老的编译系统,就OK了。 Xcode->File->Project Settings-> Build System -> Legacy Build System.

iOS12、iOS11、iOS10、iOS9常见适配
iOS12、iOS11、iOS10、iOS9常见适配

解决办法二:

删除其他info.plist文件。

iOS 12移除了libstdc++, 用libc++替代

Xcode10中libstdc++相关的3个库(libstdc++、libstdc++.6、libstdc++6.0.9)应该都是被彻底废弃了,如果你使用的三方库中有依赖,请尽快和提供方沟通,告知他们迁移吧。如果自己开发使用,也尽快考虑迁移的事宜吧。

1.2、iPhone XR不支持3D-Touch

OC检测代码

if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {

}
复制代码

swift检测代码

self.traitCollection.forceTouchCapability == .availible
复制代码

二、iOS11(Xcode9)

2.1、安全区域(SafeArea)

iOS11为 UIViewControllerUIView 增加了两个新的属性 safeAreaInsetssafeAreaLayoutGuide

  • safeAreaInsets 适用于手动计算.
  • safeAreaLayoutGuide 适用于自动布局.
UIViewController中新增:
- (void)viewSafeAreaInsetsDidChange;
UIView中新增:
- (void)viewSafeAreaInsetsDidChange;
复制代码

Storyboard 使用 Safe Area 最低只支持 iOS9iOS8 的用户就要放弃了

iOS12、iOS11、iOS10、iOS9常见适配

UIViewController 调用 - (void)viewDidLoad 时它的所有子视图的 safeAreaInsets 属性都等于 UIEdgeInsetsZero

viewSafeAreaInsetsDidChange 的调用时机如下:

  • 1、 viewDidLoad
  • 2、 viewWillAppear
  • 3、 viewSafeAreaInsetsDidChange
  • 4、 viewWillLayoutSubviews
  • 5、 viewDidAppear

只有在调用 viewSafeAreaInsetsDidChange 后,才能获得 view 以及 viewControllerSafeArea(UIEdgeInsets) 。因此在 viewDidload 中根据 SafeArea 设置界面会有问题。

iPhone X:有导航栏的时候可以+44

竖屏 safeAreaInsets = ( top = 44, left = 0, bottom = 34, right = 0)

横屏 safeAreaInsets = ( top = 0, left = 44, bottom = 21, right = 44)

#import "Adaptive11VC.h"
static inline UIEdgeInsets sgm_safeAreaInset(UIView *view) {
    if (@available(iOS 11.0, *)) {
        return view.safeAreaInsets;
    }
    return UIEdgeInsetsZero;
}

@interface Adaptive11VC ()
@end
@implementation Adaptive11VC
- (void)viewDidLoad {
    [super viewDidLoad];
}
- (void)testSafeArea {
    UIEdgeInsets safeAreaInsets = sgm_safeAreaInset(self.view);
    NSLog(@"safeAreaInsets = %@", NSStringFromUIEdgeInsets(safeAreaInsets));
}
- (void)viewSafeAreaInsetsDidChange {
    [super viewSafeAreaInsetsDidChange];
    [self testSafeArea];
}
@end
复制代码

2.2、UIScrollView

iOS 11废弃了 UIViewControllerautomaticallyAdjustsScrollViewInsets 属性,新增了 contentInsetAdjustmentBehavior 属性,所以当超出安全区域时系统自动调整了 SafeAreaInsets ,进而影响了 adjustedContentInset ,在iOS11中决定 tableView 内容与边缘距离的是 adjustedContentInset ,所以需要设置 UIScrollViewcontentInsetAdjustmentBehavior 属性。

// 方式一:(不推荐)修改额外的安全区域
if (@available(iOS 11.0, *)) {
    self.additionalSafeAreaInsets = UIEdgeInsetsMake(-44, 0, 0, 0);
}
else {
    // Fallback on earlier versions
}
// 方式二:(推荐)设置为不自动调整
if (@available(iOS 11.0, *)) {
    // 作用于指定的UIScrollView
    self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    // 作用与所有的UIScrollView
    UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
else {
    self.automaticallyAdjustsScrollViewInsets = NO;
}
复制代码

2.3、tableview问题

iOS11开始 UITableView 开启了 自动估算行高estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight 三个高度估算属性由默认的0变成了 UITableViewAutomaticDimension ,如果不实现 -tableView: viewForFooterInSection:-tableView: viewForHeaderInSection: ,那么 estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight 三个高度估算属性由默认的0变成了 UITableViewAutomaticDimension ,导致高度计算不对,会产生空白。解决方法是实现对应方法或吧这三个属性设为0。

2.4、LocalAuthentication 本地认证

本地认证框架提供了从具有指定安全策略(密码或生物学特征)的用户请求身份验证的功能。例如,要求用户仅使用Face ID或Touch ID进行身份验证,可使用以下代码:

#import <LocalAuthentication/LocalAuthentication.h>
/**
 检测TouchID是否可用
 */
- (void)checkBiometrics {
    LAContext *context = [[LAContext alloc] init];
    BOOL success = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
                                        error:nil];
    if ( success ) {
        NSLog(@"can use");
    }
    else {
        NSLog(@"can`t use ");
    }
}
/**
 在验证TouchID可用的情况下使用
 */
- (void)excuteBiometrics {
    LAContext *context = [[LAContext alloc] init];
    context.localizedFallbackTitle = @"自定义标题";
    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
            localizedReason:@"为什么使用TouchID写这里"
                      reply:^(BOOL success, NSError * _Nullable error) {
        if ( success ) {
            // 指纹验证成功
        }
        else {
            switch (error.code) {
                case LAErrorUserFallback:{
                    NSLog(@"用户选择输入密码");
                    break;
                }
                case LAErrorAuthenticationFailed:{
                    NSLog(@"验证失败");
                    break;
                }
                case LAErrorUserCancel:{
                    NSLog(@"用户取消");
                    break;
                }
                case LAErrorSystemCancel:{
                    NSLog(@"系统取消");
                    break;
                }
                // 以下三种情况如果提前检测TouchID是否可用就不会出现
                case LAErrorPasscodeNotSet:{
                    break;
                }
                case LAErrorTouchIDNotAvailable:{
                    break;
                }
                case LAErrorTouchIDNotEnrolled:{
                    break;
                }
                default:
                    break;
            }
        }
    }];
}
复制代码

2.5、启动图的适配

方法一:通过LaunchScreen.storyboard方式启动

方法二:使用Assets中的LaunchImage

iOS12、iOS11、iOS10、iOS9常见适配
  • 给Brand Assets添加一张1125*2436大小的图片
    • 打开Assets.xcassets文件夹,找到Brand Assets
    • 右键Show in Finder
    • 添加一张1125*2436大小的图片
  • 修改Contents.json文件,添加如下内容
{
	"extent" : "full-screen",
	"idiom" : "iphone",
	"subtype" : "2436h",
	"filename" : "1125_2436.png",
	"minimum-system-version" : "11.0",
	"orientation" : "portrait",
	"scale" : "3x"
}
复制代码

2.6、定位相关

在 iOS 11 中必须支持 When In Use 授权模式( NSLocationWhenInUseUsageDescription ),在 iOS 11 中, 为了避免开发者只提供请求 Always 授权模式这种情况 ,加入此限制,如果不提供 When In Use 授权模式,那么 Always 相关授权模式也无法正常使用。

如果要支持老版本,即 iOS 11 以下系统版本,那么建议在 info.plist 中配置所有的 Key(即使 NSLocationAlwaysUsageDescription 在 iOS 11及以上版本不再使用):

NSLocationWhenInUseUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription  // 为 iOS 11 中新引入的一个 Key。
复制代码

三、iOS10(Xcode8)

3.1、(Why?Safe!)插件取消

Xcode8取消了三方插件(很多优秀的插件,本来可以显著提高效率)的功能,使用Extension代替 Xcode 8 Extension 推荐

3.2、证书问题

为了方便用户来管理,提供 Automatically manage signing 。需要输入开发者账号!如果没有账号也没关系,在下面也可以选择 DebugRealeaseinHouse 模式下对应的证书也可以!

3.3、隐私数据访问问题

iOS10,苹果加强了对隐私数据的保护,要对隐私数据权限做一个适配,iOS10调用相机,访问通讯录,访问相册等都要在info.plist中加入权限访问描述,不然之前你们的项目涉及到这些权限的地方就会直接crash掉。

解决办法:只需要在 info.plist 添加 NSContactsUsageDescriptionkey , value 自己随意填写就可以,这里列举出对应的key(Source Code模式下):

<key>NSPhotoLibraryUsageDescription</key><string>App需要您的同意,才能访问相册</string>

<key>NSCameraUsageDescription</key><string>App需要您的同意,才能访问相机</string>

<key>NSMicrophoneUsageDescription</key><string>App需要您的同意,才能访问麦克风</string>

<key>NSLocationUsageDescription</key><string>App需要您的同意,才能访问位置</string>

<key>NSLocationWhenInUseUsageDescription</key><string>App需要您的同意,才能在使用期间访问位置</string>

<key>NSLocationAlwaysUsageDescription</key><string>App需要您的同意,才能始终访问位置</string>

<key>NSCalendarsUsageDescription</key><string>App需要您的同意,才能访问日历</string>

<key>NSRemindersUsageDescription</key><string>App需要您的同意,才能访问提醒事项</string>

<key>NSMotionUsageDescription</key><string>App需要您的同意,才能访问运动与健身</string>

<key>NSHealthUpdateUsageDescription</key><string>App需要您的同意,才能访问健康更新 </string>

<key>NSHealthShareUsageDescription</key><string>App需要您的同意,才能访问健康分享</string>

<key>NSBluetoothPeripheralUsageDescription</key><string>App需要您的同意,才能访问蓝牙</string>

<key>NSAppleMusicUsageDescription</key><string>App需要您的同意,才能访问媒体资料库</string>
复制代码
隐私数据 对应key值
相册 NSPhotoLibraryUsageDescription
相机 NSCameraUsageDescription
麦克风 NSMicrophoneUsageDescription
位置 NSLocationUsageDescription
在使用期间访问位置 NSLocationWhenInUseUsageDescription
始终访问位置 NSLocationAlwaysUsageDescription
日历 NSCalendarsUsageDescription
提醒事项 NSRemindersUsageDescription
运动与健身 NSMotionUsageDescription
健康更新 NSHealthUpdateUsageDescription
健康分享 NSHealthShareUsageDescription
蓝牙 NSBluetoothPeripheralUsageDescription
媒体资料库 NSAppleMusicUsageDescription

3.4、跳转到app内的隐私数据设置页面

iOS 10 干掉了所有系统设置的 URL Scheme,这意味着你再也不可能直接跳转到系统设置页面(比如 WiFi、蜂窝数据、定位等)。

跳转方式

方式一:prefs:root=某项服务 适用于 小于 iOS10的系统; NSURL *url = [NSURL URLWithString:@"prefs:root=WIFI"];

方式二:prefs:root=bundleID 适用于 大于等于iOS8系统,小于iOS10的系统 NSURL *url = [NSURL URLWithString:@"prefs:root=bundleID"];

方式三:UIApplicationOpenSettingsURLString 适用于 大于等于iOS8的系统 NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];

// iOS系统版本 >= 10.0
{
    NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url];
    }
}
return;
// iOS系统版本 >= 10.0
// But! 不建议这样做哦,官方文档中说过:
// `URL is now considered a private API and use will result in app rejection`.
// 虽然是有可能躲过苹果的检测,但是苹果如果发现你这样用了,app上架是有被拒的风险的.
{
    NSURL *url = [NSURL URLWithString:@"APP-Prefs:root=WIFI"];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        if (@available(iOS 10.0, *)) {
            [[UIApplication sharedApplication] openURL:url 
								               options:@{} 
								     completionHandler:nil];
        } else {
            // Fallback on earlier versions
        }
    }
}
// iOS系统版本 < 10.0
{
    NSURL *url = [NSURL URLWithString:@"prefs:root=WIFI"];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url];
    }
}
复制代码

跳转目的地

  • iOS系统版本 <= iOS7 , 只能跳转到 系统设置页面
  • iOS系统版本 >= iOS8 ,支持跳转到第三方应用的设置界面中。使用 prefs:root=bundleID ,bundleID 是你第三方应用工程的唯一ID
  • iOS系统版本 >= iOS10 ,支持跳转到自己应用设置,不支持跳转到系统设置

3.5、字体变化

苹果的默认字体会随着iOS系统版本的不同而不同,iOS10中字体变大了。导致了原来的显示有问题,会造成...的出现。暂时没有好的解决办法,需要自己在一个个适配一下!

3.6、UICollectionViewCell的的优化

  • 在iOS 10 之前,cell只能从重用队列里面取出,再走一遍生命周期,并调用cellForItemAtIndexPath创建或者生成一个cell.

  • 在iOS 10 中,系统会cell保存一段时间,也就是说当用户把cell滑出屏幕以后,如果又滑动回来,cell不用再走一遍生命周期了,只需要调用willDisplayCell方法就可以重新出现在屏幕中了.

  • iOS 10 中,系统是一个一个加载cell的,二以前是一行一行加载的,这样就可以提升很多性能;

  • iOS 10 新增加的Pre-Fetching预加载

3.7、UIRefreshControl

在iOS 10 中, UIRefreshControl可以直接在UICollectionView和UITableView中使用,并且脱离了UITableViewController.现在RefreshControl是UIScrollView的一个属性.

3.8、UserNotifications(用户通知)

  • iOS 10所有相关通知被统一到了UserNotifications.framework框架中。增加了撤销、更新、中途还可以修改通知的内容。通知不在是简单的文本了,可以加入视频、图片,自定义通知的展示等等。

  • iOS 10相对之前的通知来说更加好用易于管理,并且进行了大规模优化,对于开发者来说是一件好事。

  • iOS 10开始对于权限问题进行了优化,申请权限就比较简单了(本地与远程通知集成在一个方法中)。

四、iOS9(Xcode7)

4.1、Bitcode

Xcode7 默认启用 Bitcode,但是如果我们用到的第三方库编译时还没启用 Bitcode,主工程就会编译不过。Bitcode 是苹果 App Thinning 的机制之一,可以减少安装包的大小。App store 会将这个 Bitcode 编译为可执行的64位或32位程序。

解决办法一: 最简单的解决办法是先把 Bitcode 关掉:把 Build settings - Build Options - Enable Bitcode 改为 NO。

iOS12、iOS11、iOS10、iOS9常见适配

解决办法二: 移除不支持BitCode的平台SDK,或者寻找支持BitCode的替代品,或者联系SDK方支持BitCode。

4.2、HTTP 请求失败

iOS9 默认不支持 HTTP 请求,需要改用更安全的 HTTPS(默认用 TLS 1.2)。苹果还提供了配置,使得所有安全性更低的网络请求也能使用,解决方案就是在 info.plist 里面增加以下配置:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
复制代码

如果复杂一些,还可以指定白名单域名,声明所支持 TLS 的最低版本。另外需要注意的是,即使写了上述配置,在 HTTPS 页面中,HTTP 的 javascript 或 css 不会被加载,因为苹果认为这降低了页面的安全性。

4.3、canOpenUrl 限制

canOpenUrl 可以用来判断用户是否安装了某个 APP。也许是出于用户隐私的考虑,iOS9 上对 canOpenUrl 做了限制,最多只能对 50 个 scheme 做判断。如果是用 Xcode7 编译,需要在 plist 里面声明这些 scheme,没有声明的会直接返回 NO:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>weixin</string>
    <string>wechat</string>
</array>
复制代码

4.4、UIStatusBar的问题

iOS9中废弃的方法

// 修改状态栏的样式为白色
// 'setStatusBarStyle(_:animated:)' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle]
UIApplication.shared.setStatusBarStyle(.lightContent, animated: true)
// 隐藏状态栏
// 'setStatusBarHidden(_:with:)' was deprecated in iOS 9.0: Use -[UIViewController prefersStatusBarHidden]
UIApplication.shared.setStatusBarHidden(true, with: .fade)
复制代码

用下面两个方法替换

-[UIViewController preferredStatusBarstyle]
-[UIViewController preferredStatusBarHidden]
复制代码

以上所述就是小编给大家介绍的《iOS12、iOS11、iOS10、iOS9常见适配》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Node.js in Action

Node.js in Action

Mike Cantelon、Marc Harter、TJ Holowaychuk、Nathan Rajlich / Manning Publications / 2013-11-25 / USD 44.99

* Simplifies web application development * Outlines valuable online resources * Teaches Node.js from the ground up Node.js is an elegant server-side JavaScript development environment perfect for scal......一起来看看 《Node.js in Action》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具