Xcode8中Swift3.0适配问题

时间:2022-02-01 22:20:40

写在前面

收到一些小伙伴的来信,觉得可能下边没有表达清楚,先把大家关心的要点在此进行总结,有兴趣的可以看看下边的研究过程,没兴趣的直接看这段即可。

  • Xcode8支持Swift2.3和Swift3.0两种语编译,但是在整个工程中只能使用一种语法。
  • 如果想用Swift2.3版本开发,当弹出是否迁移到Swift3.0的对话框一律选择Later。所有的target(包括自己创建的和Cocoapods自动生成的)的Use Legacy Swift Language Version选择Yes。
  • 如果想用Swift3.0版本开发,当迁移到Swift3.0的界面选择target时,只要选择自己创建的target即可,Cocoapods导入的第三方不要勾选。所有的target(包括自己创建的和Cocoapods自动生成的)的Use Legacy Swift Language Version选择No.
  • Alamofire最新正式版本(4.0.0)只支持Swift3.0,想用Swift2.3开发的请选择3.5.0版本;
  • SnapKit的最新正式版本(3.0.0)同时支持Swift2.3和Swift3.0,请根据需求选择Use Legacy Swift Language Version的选项。
  • ReactiveCocoa的最新正式版本(4.2.2)只支持Swift2.3,凡是用到这个框架的项目只能使用Swift2.3开发。所有target包括自己创建的和Cocoapods自动生成的)的Use Legacy Swift Language Version选择Yes。

探究过程

Xcode8发布了,随着Xcode8一起到来的还有Swift3.0。相信好多小伙伴已经兴冲冲的下载了Xcode8,并且打开了自己的Swift项目想要尽快将自己的项目切换到Swift3.0吧。

Tip:

首先郑重提示,如果是Swift的项目:

  1. Xcode不要覆盖安装,最好保留Xcode7和Xcode8两个开发工具;
  2. 请先备份自己的项目,请先备份自己的项目,请先备份自己的项目;
  3. 如果项目迁移到Swift3.0失败,请用Xcode7打开自己备份项目继续开发,凡是用Xcode8打开过的Swift项目,Xcode7打开都会报错。

我也是这么想的,用Xcode8打开自己的项目,首先提示我们Swift语法修改了,询问我们是否要迁移到Swift3.0,如图所示:

Xcode8中Swift3.0适配问题
是否转变当前的Swift语法

当然选择Convert了,选择后,如图所示:

Xcode8中Swift3.0适配问题
转换到哪个版本的Swift

选择转换到Swift3.0,一路Next之后,发现,发现依然报错,然后我就傻眼了。

Xcode8中Swift3.0适配问题
依然报错

仔细观察错误信息,发现报错大部分集中在了第三方框架SnapKit中,难道是SnapKit不支持Swift3.0,我们在GitHub上看到:

Xcode8中Swift3.0适配问题
SnapKit最新版本支持Swift3.0

难道是由于我们项目中的SnapKit不是最新版本导致的?
更新后依然报错,这就尴尬了,人家明明说支持了,但是项目中就报错,这是为什么?

这个时候我们应该去百度一下,发现好多人说要设置这个选项:

Xcode8中Swift3.0适配问题
是否使用旧版本的Swift语言

设置之后,有些小伙伴可能就编译成功了,有些小伙伴可能依然编译出错。那么编译未成功如何解决呢?下面我们就来研究一下这个编译选项到底该怎么设置。

正常来说,我们可以随便改自己写的代码,但是对于第三方的代码,如果我使用Cocopods导入的,一般会在代码的右上角看到这个锁形标志:

Xcode8中Swift3.0适配问题
lock

这个标志表示当前文件被锁住,你没有修改的权限。所以我们最好不要修改第三方中的代码。但是主要问题又出在第三方框架中,所以我们优先解决第三方框架的Swift3.0的适配。

SnapKit适配Swift3.0

既然SnapKit的作者说SnapKit已经支持Swift3.0了,那么我们就先来适配SnapKit,首先用Xcode8新建一个空项目,利用Cocoapods导入SnapKit.

Xcode8中Swift3.0适配问题
Podfile

打开工程,依然弹出这个选项:

Xcode8中Swift3.0适配问题
是否转换到Swift3.0

刚才选择了Convert依然报错,可见不靠谱,这次我们全部选择Later。

编译后,报错:

Xcode8中Swift3.0适配问题
报错

错误提示我们依然是“Use Legacy Swift Language Version”这个选项的问题。
我们来看看这个选项怎么设置,如图所示:

Xcode8中Swift3.0适配问题
设置SnapKit的编译选项

因为SnapKit已经支持了Swift3.0,所以我们选择No,不支持旧的Swift版本,即使用Swift3.0的语法。编译通过。我们再来看看我们写的代码生成的target的编译选项:

Xcode8中Swift3.0适配问题
自己的target的编译选项

由于Xcode8新建的工程默认使用Swift3.0的语法,所以此处默认选择为No。

Tip:

如果要使用Swift2.3的语法,请指定SnapKit的版本号为:0.22.0

Xcode8中Swift3.0适配问题
官方提示!

ReactiveCocoa适配Swift3.0

相信在好多人在Swift中使用了响应式编程,提到响应式编程,就不得不说说RAC了,RAC是一个重型的OC框架,但是为了在Swift中可以使用,作者提供了Swift的桥接文件,所以,在Swift项目中导入了RAC,都会包含一些Swift的文件,这些Swift的文件也需要适配。

GitHub上RAC的作者在readme中写到:

Xcode8中Swift3.0适配问题
readme

RAC 5 支持Swift3.0.x,RAC 4支持Swift2.x。我们在Cocoapods中搜索ReactiveCocoa这个库:

Xcode8中Swift3.0适配问题
pod search ReactiveCocoa

只找到了4.2.2版本的库,我不知道上边提到的RAC 5 和 RAC 4 分别指什么。只能先用这个版本了。同样的,新建一个工程:

Xcode8中Swift3.0适配问题
默认使用Swift3.0

使用Cocoapods导入RAC:

Xcode8中Swift3.0适配问题
Podfile

是否迁移到Swift3.0依然选择Later,编译,报错:

Xcode8中Swift3.0适配问题
报错

和SnapKit的错误一样,同样的,我们去设置ReactiveCocoa的targetsh设置一下参数:

Xcode8中Swift3.0适配问题
编译设置

和SnapKit同样设置为No,编译,报错。我们可以看到,安装ReactiveCocoa同时安装了一个Result,看看它的target设置:

Xcode8中Swift3.0适配问题
Result的便已设置

设置的为Yes,那我们也把ReactiveCocoa的设置为Yes。编译,依然报错:

Xcode8中Swift3.0适配问题
依然报错

我们尝试着把自己的target设置修改一下:

Xcode8中Swift3.0适配问题
修改自己工程的target设置

编译成功。

同时导入SnapKit和RAC

现在分别导入SnapKit和RAC都编译成功了,但是可以看出SnapKit支持Swift3.0。RAC不支持。那么如果两个同时导入该选什么呢?

经过测试,如果同事导入两个框架,所有的target的设置都得选择Yes。(大家可以自己试一下,在此不做赘述。)

可以看到SnapKit既支持Swift3.0,也支持Swift2.3。那么它是如何做到的呢?通过查看源代码可以看到:

Xcode8中Swift3.0适配问题
源代码示例

通过这样的宏来判断当前的Swift的编译版本来编译不同的代码段,从而实现兼容Swift2.3和Swift3.0。

Alamofire

经过测试,Alamofire的4.0.0版本仅支持iOS9+和Swift3.0.x,如果想使用Swift2.3开发的同学可以安装Alamofire的3.5.0版本,设置所有的Use Legacy Swift Language Version为Yes。

总结

  • target的Build Setting的Use Legacy Swift Language Version选项的作用是设置当前target对应的文件是采用Swift2.3的语法编译还是Swift3.0的语法编译。当选择为Yes时,采用Swift2.3的语法编译;当选择是No时,采用Swift3.0的语法编译。
  • 新建的项目中,编译设置的原则为:所有的第三方中只要有一个第三方使用了Swift2.3的语法,那么所有的target的编译设置都应为Yes。如果都支持Swift3.0的语法,那么就可以设置为No。并且不能选择Unspecified。
  • 当Use Legacy Swift Language Version的选项设置为Yes时候,我们的工程只能使用Swift2.3来进行开发,当然你也可以像SnapKit那样利用宏来判断当前Swift的编译版本来实现适配Swift3.0,这样当以后迁移到Swift3.0也方便一些。

思考

既然每个target有自己单独的编译设置,理论上应该在编译的时候按照各自的target的编译设置来按照不同的Swift的版本编译,这样我们就可以自己的代码使用3.0编写,第三方根据各自不同进行不同的编译设置。以后想要迁移到完全的Swift3.0也更容易一些。但是目前看来编译的时候是统一按照我们缩写的target来编译的,这样的话单独设置各自的target还有什么意义呢?或许还需要一些别的设置才可以实现各自独立编译?对此有了解的同学麻烦告知一下,在此先谢过了。

文/光无影(简书作者)
原文链接:http://www.jianshu.com/p/cbd650c9daad
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Xcode8中Swift3.0适配问题的更多相关文章

  1. Swift3.0变化分享

    Swift 3.0 做出的改变很大,在这篇文章中,我将尽我所能,利用代码样例给大家解释Swift 3.0最重要(要命)的改变,希望大家能够做好升级Swift 3.0 的准备.Swift 3.0的改变不 ...

  2. swift3.0变化总结

    Swift 3.0 做出的改变很大,在这篇文章中,我将尽我所能,利用代码样例给大家解释Swift 3.0最重要(要命)的改变,希望大家能够做好升级Swift 3.0 的准备.Swift 3.0的改变不 ...

  3. Swift2.3适配Swift3.0时出现的各种问题

    昨晚上一波手贱把我的小5s升到iOS10.如此配套的话,Xcode7.3升级Xcode8.1看来也是势在必行了.公司程序是Swift2.3的,出于对苹果的恐惧迟迟不敢升级.但丑媳妇儿总要见公婆,借这个 ...

  4. UICollectionView在Swift3.0中的用法

    UICollectionView在Swift3.0中的用法 UICollectionView的初始化跟OC中是相似的,创建 GameView 集成自 UICollectionView .注意不同于UI ...

  5. swift3.0 中NSNotification 的使用

    swift3.0 有很大变化,其中之一就是NSNotification使用跟原来不一样,以前NSNotification name是String:3.0中定义了一个类型NSNotification.n ...

  6. Swift3.0中关于日期类的使用指引

    日期的处理在大大小小的iOS项目中都十分常见,随着Swift3.0正式版的即将推出,语法的改变让NSDate以及相关类的使用都与之前略有不同,这里将会对基于Swift3.0版本的NSDate及相关类的 ...

  7. Xcode8中添加SnapKit框架报错,编译失败

    既然SnapKit的作者说SnapKit已经支持Swift3.0了,那么我们就先来适配SnapKit,首先用Xcode8新建一个空项目,利用Cocoapods导入SnapKit. Podfile  打 ...

  8. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  9. iOS开发 Xcode8中遇到的问题及改动

      iOS开发 Xcode8中遇到的问题及改动 新版本发布总会有很多坑,也会有很多改动. 一个一个填吧... 一.遇到的问题 1.权限以及相关设置 iOS10系统下调用系统相册.相机功能,或者苹果健康 ...

随机推荐

  1. SpringMVC 结合HttpClient调用第三方接口实现

    使用HttpClient 依赖jar包 1:commons-httpclient-3.0.jar 2:commons-logging-1.1.1.jar 3:commons-codec-1.6.jar ...

  2. Jackson转换对象为json的时候报java.lang.*error

    无论在将一个对象转为json字符串的时候采用何种算法,如果你的对象的属性的类型不是基本类型或对应的引用类型,转换应该都不会就此结束,那么有一种方式可以导致这种转换陷入无限循环:将某个对象的属性设为对象 ...

  3. postgresql数据类型转换

    PostgreSQL数据类型转换需要使用语法 alter table tbname alter column fieldname type date_type 遇到需要转换为特殊类型如DATE.BOO ...

  4. Matlab聚类分析[转]

    Matlab聚类分析[转] Matlab提供系列函数用于聚类分析,归纳起来具体方法有如下: 方法一:直接聚类,利用clusterdata函数对样本数据进行一次聚类,其缺点为可供用户选择的面较窄,不能更 ...

  5. QVariant(相当于是Java里面的Object,起到一个数据类型“擦除”的作用,可以使用Q_DECLARE_METATYPE进行注册)

    =QVariant= [%这个类型相当于是Java里面的Object,它把绝大多数Qt提供的数据类型都封装起来,起到一个数据类型“擦除”的作用.比如我们的 table单元格可以是string,也可以是 ...

  6. CDQ分治嵌套模板:多维偏序问题

    CDQ分治2 CDQ套CDQ:四维偏序问题 题目来源:COGS 2479 偏序 #define LEFT 0 #define RIGHT 1 struct Node{int a,b,c,d,bg;}; ...

  7. MSIL实用指南-字段的加载和保存

    字段有静态字段和非静态字段之分,它们的加载保存指令也是不一样的,并且非静态字段要生成this. 静态字段的加载加载静态字段的指令是Ldsfld.ilGenerator.Emit(OpCodes.Lds ...

  8. Activity、Window、View三者之间的联系

    Activity类:Android四大组件之一,是开发者最常用的一个组件 Window类:是一个抽象类,具有窗口管理的功能,实现类为PhoneWindow View类:提供对View的操作,包括绘制测 ...

  9. 蜕变成蝶~Linux设备驱动中的阻塞和非阻塞I/O

    今天意外收到一个消息,真是惊呆我了,博客轩给我发了信息,说是俺的博客文章有特色可以出本书,,这简直让我受宠若惊,俺只是个大三的技术宅,写的博客也是自己所学的一些见解和在网上看到我一些博文以及帖子里综合 ...

  10. Hibernate基本应用01

    一. Hibernate简介 1.1 Hibernate介绍 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全 ...