在Swift中,如何调用Objective-C代码?
苹果提到它们可以共存于一个应用程序中,但这是否意味着人们可以在技术上重用Objective-C中创建的旧类,同时在Swift中构建新类?
在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.