Swift与Objective-C混和编程

14年6月3日苹果发布Swift以来,这门语言以让人惊讶的速度在成长,越来越多的开发者关注学习,很多App和开源库也在从Objective-C迁移到Swift上。

Swift语法确实更新进、更漂亮,而在实际开发过程中,由于Objective-C更贴近底层,可以使用如OC Runtime这样的黑魔法,很多开源库也是依赖其实现。因此OC和Swift混编应该一个长期的趋势,之前只是依赖于Xcode自动引入bridge header等类似的机制,没有仔细去理解,借着新做项目用到evernote oc库的机会好好的总结一下。苹果提供的Swift与Objective-C混编方案都是基于Xcode和LLVM编译,采用Mix and Match机制。


从开发者实现角度根据不同的混编场景可以分为如下几种情况:

  • 普通代码混编:项目内普通代码文件混编(.swift内使用OC的.h和.m文件或者反过来,包括.a形式项目的开发),采用的bridge方案;

  • 开发Framework混编:如果你的项目是输出一个Framework,混编方式稍有不同,姑且成为umbrella方案;

  • 引用外部Framework和宿主App混编:如果你的项目引用一个外部提供的Framework(无论这个Framework是单一语言开发还是本身就是混编的),混编方案也有不同。> 详细的原理参见上文提到的官方文档,本文主要关注三种方式的实现以及可能遇到的问题。

普通代码文件混编方案:

Swift引用OC实现通过桥接头文件,OC引用Swift实现直接importProductModuleName-Swift.h这个文件即可。

OC引用Swift实现

ProductModuleNameBuild Settings里面配置:

默认用ProductName,可以支持自定义。(注明:Framework项目不支持自定义)

Swift引用OC实现

Swift引用OC实现稍微麻烦一点,需要自己生成一个bridge header文件,和创建普通.h方式相同File > New > File > (iOS, watchOS, tvOS, or OS X) > Source > Header File,名字随意,然后配置到Build Settings - Swift Compiler - Code Generation下的Objective-C Bridging Header选项。

注意路径从项目根目录开始计算,可以使用..来指定与根目录平级目录。bridge header内import所有想要在swift中使用的OC类,就会作为一个module在swift中使用。例如:

#import "XYZCustomCell.h"    

#import "XYZCustomView.h"   

#import "XYZCustomViewController.h"

Swift中用如下代码访问:

let myOtherCell = XYZCustomCell()    

myOtherCell.subtitle = "Another custom cell"

FYI. 语言类型为Swift的项目引入OC文件时Xcode会给个创建bridge header的提示,自己会配置了之后用处不大:

Framework项目中使用代码混编方案:

Umbrella Header的相关知识苹果没有给出很明确的说明,只有以前介绍Umbrella Framework的时候介绍过,找了很久发现iOS - Umbrella Header在framework中的应用这篇文章介绍的很好,详细的内容可以进入了解。

Swift引用OC实现

现在我们只需要了解Framework里面Swift引用OC逻辑需要一个与ProductName同名的.h文件作为Umbrella Header,如果不存在则创建一个。不需要在Build Settings配置因为这文件是map modules的时候自动指定的,如果基于某种原因(比如这个同名文件已经被用来写其他逻辑)一定要自定义的话可以参考上面文章里介绍的方法。第二步到Build Settings - Packaging中将Defines Module选项设为YES。然后将Swift中需要引用的OC逻辑引用进来,访问方式同普通代码混编

#import "XYZCustomCell.h"    

#import "XYZCustomView.h"    

#import "XYZCustomViewController.h"

OC引用Swift

实现OC引用Swift同样需要将Defines Module选项设为YES,其余和普通代码混编相比只是改了个引用文件的方式:#import

引用外部Framework时混编

方案:

重要前提

这里有一个重要的前提是这个外部Framework在编译时必须开启了Defines Module,如果没有开启并且没有Framework源码的情况下还是绕路吧。

external framework混编

在这种情况下当前App使用外部Framework是不关心其内部到底是Swift实现、OC实现还是本身就是混编实现的。只需要Swift使用Framework逻辑时添加import FrameworkName,OC使用时在任意.m文件中添加@import FrameworkName;语法即可。

混编后哪些逻辑可以被另一种语言引用到?

Swift中可以被OC引用的逻辑:

  • public关键字;

  • 有bridging header的target中用internal关键字修饰;

  • private修饰的关键字通常是访问不到的,除了@IBAction, @IBOutlet, 和 @objc标记;

OC中由于开发习惯的原因基本上头文件中的属性、方法都可以被swift访问到。

Evenote-Mac Framework混编时遇到的问题

  1. Evenote-Mac这个奇葩的Framework名字在生成umbrella header的时候报错:

warning: EvernoteSDK-Mac is not a valid PRODUCT_NAME for use with framework targets enabling DEFINES_MODULE (name is not a valid C99 extended identifier)

warning: no umbrella header found for target 'EvernoteSDK-Mac', module map will not be generated

因为名字中有-字符,所以只能替换或者去掉;

  1. 改名时建议直接改target的名字,只改module的名字就会报错:

Warning: PRODUCT_MODULE_NAME may not be overridden for framework target 'EvernoteSDKMac'

参考链接

  1. Mixed language framework

  2. 链接1回答中还有个Demo

  3. 官方对Umbrella Framework的一点介绍

  4. 对Umbrella Framework的一篇更好的介绍

  5. so上有关framework name的回答

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容