一iOS12
1.1升级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.
1.2 iOS 12移除了libstdc++, 用libc++替代
Xcode10中libstdc++相关的3个库(libstdc++、libstdc++.6、libstdc++6.0.9)应该都是被彻底废弃了,如果你使用的三方库中有依赖,请尽快和提供方沟通,告知他们迁移吧。如果自己开发使用,也尽快考虑迁移的事宜吧。
1.3、iPhone XR不支持3D-Touch
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
}
二、iOS11(Xcode9)
2.1安全区域(SafeArea)
iOS11为UIViewController和UIView增加了两个新的属性safeAreaInsets和safeAreaLayoutGuide
UIViewController中新增:
- (void)viewSafeAreaInsetsDidChange;
UIView中新增:
- (void)viewSafeAreaInsetsDidChange;
当UIViewController调用- (void)viewDidLoad时它的所有子视图的safeAreaInsets属性都等于UIEdgeInsetsZero。
1、viewDidLoad
2、viewWillAppear
3、viewSafeAreaInsetsDidChange
4、viewWillLayoutSubviews
5、viewDidAppear
只有在调用viewSafeAreaInsetsDidChange后,才能获得view以及viewController的SafeArea(UIEdgeInsets)。因此在viewDidload中根据SafeArea设置界面会有问题。
安全区适配的宏
(屏幕宽度)
#defineWY_ScreenWidth [UIScreen mainScreen].bounds.size.width
(屏幕高度)
#defineWY_ScreenHeight [UIScreen mainScreen].bounds.size.height
是否为iPhoneX
#defineWY_iPhoneX (WY_ScreenWidth == 375.f && WY_ScreenHeight == 812.f ? YES : NO)
//状态栏高度
#defineWY_StatusBarHeight (WY_iPhoneX ? 44.f : 20.f);
//nav的高度
#defineWY_NavigationBarHeight 44.f;
//底部tabbar的高度
#defineWY_TabbarHeight (WY_iPhoneX ? (49.f+34.f) : 49.f)
//底部安全区高度
#defineWY_TabbarSafeBottomMargin (WY_iPhoneX ? 34.f : 0.f)
//nav夹status的高度
#defineWY_StatusBarAndNavigationBarHeight (WY_iPhoneX ? 88.f : 64.f)
//适配安全区域,还有一种写法配置全局
#defineWY_ViewSafeAreInsets(view) ({UIEdgeInsets insets;if(@available(iOS 11.0, *)) {insets = view.safeAreaInsets;}else{insets = UIEdgeInsetsZero;} insets;})
2.2UIScrollView
iOS 11废弃了UIViewController的automaticallyAdjustsScrollViewInsets属性,新增了contentInsetAdjustmentBehavior属性,所以当超出安全区域时系统自动调整了SafeAreaInsets,进而影响了adjustedContentInset,在iOS11中决定tableView内容与边缘距离的是adjustedContentInset,所以需要设置UIScrollView的contentInsetAdjustmentBehavior属性。
if(@available(iOS 11.0, *)) { // 作用于指定的UIScrollView self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; // 作用与所有的UIScrollView UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; }else{ self.automaticallyAdjustsScrollViewInsets = NO; }
2.3tableview问题
iOS11开始UITableView开启了自动估算行高,estimatedRowHeightestimatedSectionHeaderHeightestimatedSectionFooterHeight三个高度估算属性由默认的0变成了UITableViewAutomaticDimension,如果不实现-tableView: viewForFooterInSection:和 -tableView: viewForHeaderInSection:,那么estimatedRowHeightestimatedSectionHeaderHeightestimatedSectionFooterHeight三个高度估算属性由默认的0变成了UITableViewAutomaticDimension,导致高度计算不对,会产生空白。解决方法是实现对应方法或吧这三个属性设为0。
2.4启动图的适配
方法一:通过LaunchScreen.storyboard方式启动
方法二:使用Assets中的LaunchImage
给Brand Assets添加一张1125*2436大小的图片
打开Assets.xcassets文件夹,找到Brand Assets
右键Show in Finder
添加一张1125*2436大小的图片
修改Contents.json文件,添加如下内容
2.5定位相关
在 iOS 11 中必须支持 When In Use授权模式(NSLocationWhenInUseUsageDescription),在 iOS 11 中,为了避免开发者只提供请求 Always 授权模式这种情况,加入此限制,如果不提供When In Use授权模式,那么 Always相关授权模式也无法正常使用。如果要支持老版本,即 iOS 11 以下系统版本,那么建议在 info.plist 中配置所有的 Key
NSLocationWhenInUseUsageDescription NSLocationAlwaysAndWhenInUseUsageDescription NSLocationAlwaysUsageDescription NSLocationAlwaysAndWhenInUseUsageDescription
三、iOS10(Xcode8)
3.1证书问题
为了方便用户来管理,提供Automatically manage signing。需要输入开发者账号!如果没有账号也没关系,在下面也可以选择Debug、Realease、inHouse模式下对应的证书也可以!
3.2隐私数据访问问题
iOS10,苹果加强了对隐私数据的保护,要对隐私数据权限做一个适配,iOS10调用相机,访问通讯录,访问相册等都要在info.plist中加入权限访问描述,不然之前你们的项目涉及到这些权限的地方就会直接crash掉。
解决办法: 只需要在info.plist添加NSContactsUsageDescription的key, value自己随意填写就可以,这里列举出对应的key(Source Code模式下):
3.3跳转到app内的隐私数据设置页面
iOS 10 干掉了所有系统设置的 URL Scheme,这意味着你再也不可能直接跳转到系统设置页面(比如 WiFi、蜂窝数据、定位等)。
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];
3.4字体变化
苹果的默认字体会随着iOS系统版本的不同而不同,iOS10中字体变大了。导致了原来的显示有问题,会造成...的出现。暂时没有好的解决办法,需要自己在一个个适配一下!
3.5UIRefreshControl
在iOS 10 中, UIRefreshControl可以直接在UICollectionView和UITableView中使用,并且脱离了UITableViewController.现在RefreshControl是UIScrollView的一个属性.
3.6、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。
解决办法二: 移除不支持BitCode的平台SDK,或者寻找支持BitCode的替代品,或者联系SDK方支持BitCode。
4.2HTTP 请求失败
iOS9 默认不支持 HTTP 请求,需要改用更安全的 HTTPS(默认用 TLS 1.2)。苹果还提供了配置,使得所有安全性更低的网络请求也能使用,解决方案就是在 info.plist 里面增加以下配置:
NSAppTransportSecurity NSAllowsArbitraryLoads 复制代码
如果复杂一些,还可以指定白名单域名,声明所支持 TLS 的最低版本。另外需要注意的是,即使写了上述配置,在 HTTPS 页面中,HTTP 的 javascript 或 css 不会被加载,因为苹果认为这降低了页面的安全性
4.3canOpenUrl 限制
canOpenUrl 可以用来判断用户是否安装了某个 APP。也许是出于用户隐私的考虑,iOS9 上对 canOpenUrl 做了限制,最多只能对 50 个 scheme 做判断。如果是用 Xcode7 编译,需要在 plist 里面声明这些 scheme,没有声明的会直接返回 NO:
4.4UIStatusBar的问题
iOS9中废弃的方法
// 修改状态栏的样式为白色//'setStatusBarStyle(_:animated:)'was deprecatediniOS 9.0: Use -[UIViewController preferredStatusBarStyle]UIApplication.shared.setStatusBarStyle(.lightContent, animated:true)// 隐藏状态栏//'setStatusBarHidden(_:with:)'was deprecatediniOS 9.0: Use -[UIViewController prefersStatusBarHidden]UIApplication.shared.setStatusBarHidden(true, with: .fade)
//替换方法
-[UIViewController preferredStatusBarstyle]
-[UIViewController preferredStatusBarHidden]
4.5泛型
带泛型的容器(规定容器中所存储的数据类型)
(1)带泛型的数组
声明一个可变数组, 内部存放的都是NSString1.数组中添加其他类型会有警告2.数组取出来的类型不再是id类型, 会对应变成声明时的类型3.泛型会改变类的一些方法, 使与声明的类型相同看下图的情况:
(2)带泛型的字典
可以看到使用泛型规定了字典key和value的数据类型后,向字典中添加其他类型(如图中的数组)时会有类型不匹配的警告。而从字典中取出的value也有了固定的类型(图中规定的是NSString),因此可以通过取出来的value使用getter方法得到字符串的length属性
4.5协变性与逆变性
还是先来看看实际的例子来了解下什么是协变性和逆变性吧,下图是系统NSArray的头文件部分,可以看到它使用了自定义泛型并命名为 OBjectType,在自定义泛型前加了一个 __covariant 的修饰符,这个修饰符就表示协变性
__covariant - 协变性,子类型可以强转到父类型(里氏替换原则)
__contravariant - 逆变性,父类型可以强转到子类型
后记我不记得实在那里看的文章,如果有人知道请@wo,我给上连接