18.2 Swift调用Objective-C

Swift调用Objective-C需要一个名为“<工程名>-Bridging-Header.h”的桥接头文件,如图18-1所示。桥接头文件的作用是为Swift调用Objective-C对象搭建一个桥,它的命名必须是“<工程名>- Bridging-Header.h”,我们需要在桥接头文件中引入Objective-C头文件,而且桥接头文件是需要管理和维护的。

{%}

图 18-1 Swift调用Objective-C与桥接头文件

18.2.1 创建Swift的iOS工程

为了能够更好地介绍混合搭配调用,我们首先创建一个基于Swift的iOS工程。具体参考14.3节创建工程,删除AppDelegate.swift、ViewController.swift和Main.storyboard这3个文件。

参考14.3节创建一个main.swift文件,注意在文件创建过程中,Xcode会弹出一个是否创建桥接头文件对话框,如图18-2所示,这里要选择Yes,这样就会在创建swift文件的同时也创建一个桥接头文件,如果我们选择No也可以在以后创建,就是有些麻烦。

{%}

图 18-2 创建桥接头文件

完成上述操作的Xcode界面如图18-3所示。

{%}

图 18-3 Xcode界面

18.2.2 在Swift工程中添加Objective-C类

我们刚刚创建了Swift的工程,还需要调用其他Objective-C类来实现某些功能,需要添加Objective-C类到Swift工程中。具体过程是,右键选择HelloWorld组,然后选择菜单中的“New File…”弹出新建文件模板对话框,如图18-4所示,选择“iOS →Source→Cocoa Touch Class”。

{%}

图 18-4 新建文件模板

接着单击“Next”按钮,随即出现如图18-5所示的界面。在Class中输入“ObjCObject”,在Language中选择Objective-C,其他的选项保持默认值就可以了。

{%}

图 18-5 新建Objective-C类

相关选项设置完成后,单击“Next”按钮,进入保存文件界面,根据提示选择存放文件的位置,然后单击“Create”按钮创建Objective-C类。

18.2.3 调用代码

Objective-C的ObjCObject创建完成后,我们会在Xcode工程中看到新增加的两个文件ObjCObject.h和ObjCObject.m。本书并不打算过多地介绍Objective-C语言,但为了更好地理解Swift与Objective-C的互相调用,我们还是简单地解释一下Objective-C代码。

ObjCObject.h代码如下:

  1. #import <Foundation/Foundation.h> ①
  2. @interface ObjCObject : NSObject
  3. -(NSString*)sayHello:(NSString*)greeting withName: (NSString*)name;
  4. @end

ObjCObject.h文件是Objective-C的头文件,我们在这里定义类,声明类的成员变量和方法。第①行代码引入Foundation框架的头文件。第②行代码定义类ObjCObject,它继承自NSObject父类。NSObject类是所有Objective-C的根类。第③行代码声明了实例方法sayHello: withName:,它有两个参数greetingname

ObjCObject.m代码如下:

  1. #import "ObjCObject.h" ①
  2. @implementation ObjCObject
  3. -(NSString*)sayHello:(NSString*)greeting withName: (NSString*)name
  4. {
  5. NSString *string = [NSStringstringWithFormat:@"Hi,%@ %@.",name,greeting];
  6. return string;
  7. }
  8. @end

上述代码第①行引入ObjCObject.h头文件,第②行代码定义sayHello: withName:方法。

下面我们再来看看Swift调用文件main.swift的代码:

  1. import Foundation
  2. var obj : ObjCObject = ObjCObject()
  3. var hello = obj.sayHello("Good morning", withName:"Tony")
  4. println(hello)

上述代码第①行的import Foundation语句是引入Foundation框架,类似于Objective-C的#import 语句,关于Foundation框架我们会在下一章介绍。

第②行代码声明并实例化ObjCObject类的实例objObjCObject就是Objective-C里定义的ObjCObject

第③行代码调用ObjCObject类的sayHello: withName:方法。要注意Swift调用时的方法名和参数与Objective-C中该方法的方法名和参数的对应关系,如图18-6所示。

{%}

图 18-6 Objective-C与Swift调用方法和参数对应关系

第④行代码打印输出结果,输出结果如下:

  1. Hi,Tony Good morning.

要使Swift能够调用Objective-C,还必须在桥接头文件中引入Objective-C头文件。HelloWorld-Bridging-Header.h代码如下:

  1. #import "ObjCObject.h"

很简单,只有一行代码,如果还有其他的Objective-C头文件,都需要在此引入。

这样就实现了在Swift中调用Objective-C代码,我们可以借助于这样的调用充分地利用已有的Objective-C文件,减少重复编写代码,提供工作效率。

至此,整个工程创建完毕。点击左上角的“运行”按钮{%}即可查看运行结果,运行结果输出到日志窗口。运行和查看日志窗口的操作细节可以参考14.3节,这里不再赘述。