在Swift中,如何调用Objective-C代码?

苹果提到它们可以共存于一个应用程序中,但这是否意味着人们可以在技术上重用Objective-C中创建的旧类,同时在Swift中构建新类?


当前回答

我写了一个简单的Xcode 6项目,展示了如何混合c++, Objective-C和Swift代码:

https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console

特别地,这个例子调用了Swift中的Objective-C和c++函数。

关键是创建一个共享头文件Project-Bridging-Header.h,并将Objective-C头文件放在那里。

请下载该项目作为完整的示例。

其他回答

在Swift中使用Objective-C类

如果您有一个想要使用的现有类,请执行步骤2,然后跳到步骤5。(在某些情况下,我必须在旧的Objective-C文件中添加显式的#import <Foundation/Foundation.h。)

步骤1:添加Objective-C实现——.m

向类中添加一个.m文件,并将其命名为CustomObject.m。

步骤2:添加桥接头

当添加你的.m文件时,你可能会看到这样的提示:

单击Yes !

如果你没有看到提示,或者不小心删除了桥接头,添加一个新的。h文件到你的项目,并命名为<#YourProjectName#>-Bridging-Header.h。

在某些情况下,特别是在使用Objective-C框架时,你没有显式地添加Objective-C类,Xcode就找不到链接器。在这种情况下,创建如上所述的.h文件,然后确保将其路径链接到目标项目设置中,如下所示:

注意:

使用$(SRCROOT)宏链接您的项目是最好的做法,这样如果您移动您的项目,或使用远程存储库与他人一起处理它,它仍然可以工作。$(SRCROOT)可以被认为是包含.xcodeproj文件的目录。它可能是这样的:

$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h

步骤3:添加Objective-C Header——.h

添加另一个.h文件并将其命名为CustomObject.h。

步骤4:构建Objective-C类

在CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

在CustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}

@end

步骤5:添加类到桥接头

在YourProject-Bridging-Header.h:

#import "CustomObject.h"

第六步:使用你的对象

在SomeSwiftFile.swift:

var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

不需要显式地导入;这就是桥接头的作用。

在Objective-C中使用Swift类

步骤1:创建新的Swift类

添加一个.swift文件到你的项目中,并将其命名为MySwiftObject.swift。

在MySwiftObject.swift:

import Foundation

@objc(MySwiftObject)
class MySwiftObject : NSObject {

    @objc
    var someProperty: AnyObject = "Some Initializer Val" as NSString

    init() {}

    @objc
    func someFunction(someArg: Any) -> NSString {
        return "You sent me \(someArg)"
    }
}

步骤2:将Swift文件导入ObjC类

在SomeRandomClass.m:

#import "<#YourProjectName#>-Swift.h"

文件:<#YourProjectName#>-Swift.h应该已经在你的项目中自动创建了,即使你看不到它。

第三步:利用你的课程

MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);

NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];

NSLog(@"RetString: %@", retString);

注:

If Code Completion isn't behaving as you expect, try running a quick build with ⌘⇧R to help Xcode find some of the Objective-C code from a Swift context and vice versa. If you add a .swift file to an older project and get the error dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, try completely restarting Xcode. While it was originally possible to use pure Swift classes (Not descendents of NSObject) which are visible to Objective-C by using the @objc prefix, this is no longer possible. Now, to be visible in Objective-C, the Swift object must either be a class conforming to NSObjectProtocol (easiest way to do this is to inherit from NSObject), or to be an enum marked @objc with a raw value of some integer type like Int. You may view the edit history for an example of Swift 1.x code using @objc without these restrictions.

创建桥接头后,进入构建设置=>搜索“Objective-C桥接头”。

就在下面你会发现“Objective-C Generated Interface Header Name”文件。

在视图控制器中导入那个文件。

例子:在我的例子中:“Dauble-Swift.h”

点击新建文件菜单,并选择文件选择语言目标。这时,它会自动生成一个“Objective-C Bridging Header”文件,用于定义一些类名。

“Swift编译器-代码生成”下的“Objective-C桥接头”。

混合Objective-C和Swift

高层图:

相同的目标

//Objective-C exposes API for Swift thought <target_name>-Bridging-Header.h
.swift uses .h.m = Swift consumer, Objective-C producer = <target_name>-Bridging-Header.h

//Swift exposes API for Objective-C thought <target_name>-Swift.h
.h.m uses .swift = Objective-C consumer, Swift producer = <target_name>-Swift.h

Swift消费者,Objective-C生产者

添加一个新的头文件。h和实现文件。m - Cocoa类文件(Objective-C) 例如<MyFileName>.h和<MyFileName>.m 配置桥接报头 当您看到“是否想配置Objective-C桥接头”时,单击“是” <target_name>-Bridging-Header.h将自动生成 构建设置-> Objective-C桥接头(SWIFT_OBJC_BRIDGING_HEADER) 将类添加到桥接头 在<target_name>-Bridging-Header.h中添加一行#import "<MyFileName>.h"

之后你可以使用Swift Objective-C的MyFileName.h,MyFileName.m

附注:如果你要添加一个现有的Objective-C文件到Swift项目中,请预先添加Bridging-Header.h并导入它

Objective-C消费者,Swift生产者

添加一个<MyFileName>.swift和extends NSObject 将Swift文件导入ObjC类 在Objective-C文件中添加#import "<target_name>-Swift.h" 通过@objc公开Swift代码[关于]

在此之后,您可以使用Objective-C Swift的<MyFileName>.swift

[<product_name>-Swift.h文件未找到]

不同的目标 (。modulemap]和[伞盖.h]用于暴露Objective-C for Swift。Swift.h用于为Objective-C公开Swift代码

(词汇)

引用自文档:

Any Objective-C framework (or C library) that’s accessible as a module can be imported directly into Swift. This includes all of the Objective-C system frameworks—such as Foundation, UIKit, and SpriteKit—as well as common C libraries supplied with the system. For example, to import Foundation, simply add this import statement to the top of the Swift file you’re working in: import Foundation This import makes all of the Foundation APIs—including NSDate, NSURL, NSMutableData, and all of their methods, properties, and categories—directly available in Swift.