体验XCode9中的Swift

Swift与OC混合编译

Tom 创建于 2017-11-9

最新发表:


浅谈面向对象的SDK的结果处理方式

返回值、代理还是其他方法

你可能感兴趣的内容:


iOS8的列表控件存在隐性bug

iOS11出来,iOS8还要继续维护?


Xcode9命令行新打包方法

升级以后打包失败?

体验XCode9中的Swift

最近尝试了一下Swift的兼容性、混编及SDK、app,了解正确的编译方法及输出结果对app的影响,下面简单说说遇到的问题、解决方法及是否会应用到后续商用开发。

1、Swift3.2 vs Swift4.0

Swift3.2的代码与4.0代码编译不会出错。目前没有加入特别复杂的逻辑,所以很少发现问题。语法上closure存在比较奇怪的用法,不是可选的值在函数中定义要在前面加<pre>@escaping</pre>。

public class func startWithAppInfo(appInfo: [String: String], productInfo: [[String: String]]?, cloudSeviceInfo: [String: String]?, completionHandler: @escaping ((Int) -> Void)) -> Void {
}

2、Objective C 与 Swift 混编动态库的坑

Objective C 与 Swift 代码,只开发应用的情况下,可以直接桥接,任何符号都可以正常转换。动态库是否也能这样,于是做了尝试:

第一步:动态库设置桥接头

设置了bridging header后,打包framework后,给其他工程引用,会出现找不到模块的问题。

第二步:模块图文件的定义

桥接头行不通后,改为module map方式实现。由于工程内部配置的module map选项无论怎么编译,编译器总是报错找不到任何设置的私有符号。类似第一步那样,会有依赖。所以改为放弃自动生成module map和objective c兼容头的形式,编译前先把自定义的module map文件拷贝到framework中,发布的时候把私有的modulemap文件、头文件一起去除掉就可以了。

示例工程内部包含两个modulemap文件,一个是公共的,一个是私有的。

公共modulemap文件内容:

framework module GizWifiSDK {
}

私有modulemap文件内容:

framework module GizWifiSDK.Private {
    umbrella header "GizWifiSDKAsync.h"
    export *
}

私有的modulemap文件链接了一系列私有的二次封装接口。

注意:编译之前要把Install Objective-C Compatibility Header、Defines Module改为NO。

第三步:定义头文件要拷贝的位置

由于私有模块与 Objective C 之间存在一些头文件找不到,编译还是出现一堆错误。头文件只能在指定路径内查找,所以在编译swift代码之前,先把私有的二次封装接口拷贝到privateHeader里面。此时还有一些头文件是找不到的

第四步:修改头文件引用

将编译器不认的头文件删掉,包含枚举部分的头文件从公共代码复制一份副本,继续编译。

第五步:放进app测试

通过以上步骤一步步设置好,放在app以后,就不会出现import失败的问题了,代码运行完全正常,优点:

1、框架可以支持基于Objective C的工程编译,也可以支持基于Swift工程编译
2、Objective C、Swift接口可以分别根据不同语言的特性做最优化定义

测试后发现,用swift写的库放在app内编译会存在以下问题:

1、Objective C工程需要强制依赖swift运行时库后,才可以正常运行
2、Swift工程编译app后,当前app仍然需要捆绑运行时组件

总结:

Swift语言虽然好,现在还是在发展过程中,运行时库不断在发生变化。Swift也不见得开发速度能提升很多,需要前期的语法学习才能提高编码速度。最近两年,Swift的语法趋于稳定,后续有商用可能,目前来看还是不足以让我完全取代现有的Objective C语言。

一个小工具

无意间发现了一个代码转换网站,可以把Objective C代码转换成Swift代码,有兴趣的朋友可以玩玩