如何从 Swift 调用 Objective-C 代码? [英] How do I call Objective-C code from Swift?
问题描述
在 Swift 中,如何调用 Objective-C 代码?
Apple 提到它们可以共存于一个应用程序中,但这是否意味着在技术上可以重用在 Objective-C 中创建的旧类,同时在 Swift 中构建新类?
在 Swift 中使用 Objective-C 类
<块引用>如果您想要使用现有课程,请执行第 2 步,然后跳至第 5 步.(在某些情况下,我必须向旧的 Objective-C 文件添加显式 #import
步骤 1:添加 Objective-C 实现 -- .m
将 .m
文件添加到您的类中,并将其命名为 CustomObject.m
.
第 2 步:添加桥接头
在添加 .m
文件时,您可能会看到如下提示:
点击是!
如果您没有看到提示,或者不小心删除了桥接头,请在您的项目中添加一个新的 .h
文件并将其命名为 <#YourProjectName#>-Bridging-Header.h
.
在某些情况下,尤其是在使用 Objective-C 框架时,您不会显式添加 Objective-C 类并且 Xcode 找不到链接器.在这种情况下,创建如上所述命名的 .h
文件,然后确保将其路径链接到目标的项目设置中,如下所示:
注意:
最好使用 $(SRCROOT)
宏链接您的项目,这样如果您移动您的项目,或与其他人使用远程存储库一起处理它,它仍然可以工作.$(SRCROOT)
可以被认为是包含 .xcodeproj 文件的目录.它可能看起来像这样:
$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h
第 3 步:添加 Objective-C 标头 -- .h
添加另一个 .h
文件并将其命名为 CustomObject.h
.
第 4 步:构建您的 Objective-C 类
在CustomObject.h
#import @interface 自定义对象:NSObject@property (strong, nonatomic) id someProperty;- (void) someMethod;@结尾
在CustomObject.m
#import "CustomObject.h"@implementation 自定义对象- (void) someMethod {NSLog(@"SomeMethod Ran");}@结尾
步骤 5:向 Bridging-Header 添加类
在 YourProject-Bridging-Header.h
中:
#import "CustomObject.h"
第 6 步:使用您的对象
在 SomeSwiftFile.swift
中:
var instanceOfCustomObject = CustomObject()instanceOfCustomObject.someProperty = "Hello World"打印(instanceOfCustomObject.someProperty)instanceOfCustomObject.someMethod()
无需显式导入;这就是桥接头的用途.
在 Objective-C 中使用 Swift 类
第 1 步:创建新的 Swift 类
将 .swift
文件添加到您的项目中,并将其命名为 MySwiftObject.swift
.
在 MySwiftObject.swift
中:
import Foundation@objc(MySwiftObject)类 MySwiftObject : NSObject {@对象var someProperty: AnyObject = "Some Initializer Val" as NSString在里面() {}@对象func someFunction(someArg: Any) ->NSString {return "你给我发了 (someArg)"}}
第 2 步:将 Swift 文件导入 ObjC 类
在 SomeRandomClass.m
中:
#import "<#YourProjectName#>-Swift.h"
文件:<#YourProjectName#>-Swift.h
应该已经在您的项目中自动创建,即使您看不到它.
第 3 步:使用您的课程
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);
注意事项:
如果 Code Completion 的行为不符合您的预期,请尝试使用 ⌘⇧R 运行快速构建以帮助 Xcode从 Swift 上下文中找到一些 Objective-C 代码,反之亦然.
如果您将
.swift
文件添加到旧项目并得到错误dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
,请完全尝试重启 Xcode.虽然最初可以使用纯 Swift 类(不是
NSObject
的后代)通过使用@objc
前缀对 Objective-C 可见,这已经不可能了.现在,要在 Objective-C 中可见,Swift 对象必须是符合NSObjectProtocol
的类(最简单的方法是从NSObject
继承),或者是一个enum
标记为@objc
的带有某种整数类型的原始值,例如Int
.您可以在没有这些限制的情况下使用@objc
查看 Swift 1.x 代码示例的编辑历史记录.
In Swift, how does one call Objective-C code?
Apple mentioned that they could co-exist in one application, but does this mean that one could technically re-use old classes made in Objective-C whilst building new classes in Swift?
Using Objective-C Classes in Swift
If you have an existing class that you'd like to use, perform Step 2 and then skip to Step 5. (For some cases, I had to add an explicit
#import <Foundation/Foundation.h
to an older Objective-C File.)
Step 1: Add Objective-C Implementation -- .m
Add a .m
file to your class, and name it CustomObject.m
.
Step 2: Add Bridging Header
When adding your .m
file, you'll likely be hit with a prompt that looks like this:
Click Yes!
If you did not see the prompt, or accidentally deleted your bridging header, add a new .h
file to your project and name it <#YourProjectName#>-Bridging-Header.h
.
In some situations, particularly when working with Objective-C frameworks, you don't add an Objective-C class explicitly and Xcode can't find the linker. In this case, create your .h
file named as mentioned above, then make sure you link its path in your target's project settings like so:
Note:
It's best practice to link your project using the $(SRCROOT)
macro so that if you move your project, or work on it with others using a remote repository, it will still work. $(SRCROOT)
can be thought of as the directory that contains your .xcodeproj file. It might look like this:
$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h
Step 3: Add Objective-C Header -- .h
Add another .h
file and name it CustomObject.h
.
Step 4: Build your Objective-C Class
In CustomObject.h
#import <Foundation/Foundation.h>
@interface CustomObject : NSObject
@property (strong, nonatomic) id someProperty;
- (void) someMethod;
@end
In CustomObject.m
#import "CustomObject.h"
@implementation CustomObject
- (void) someMethod {
NSLog(@"SomeMethod Ran");
}
@end
Step 5: Add Class to Bridging-Header
In YourProject-Bridging-Header.h
:
#import "CustomObject.h"
Step 6: Use your Object
In SomeSwiftFile.swift
:
var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()
There is no need to import explicitly; that's what the bridging header is for.
Using Swift Classes in Objective-C
Step 1: Create New Swift Class
Add a .swift
file to your project, and name it MySwiftObject.swift
.
In 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)"
}
}
Step 2: Import Swift Files to ObjC Class
In SomeRandomClass.m
:
#import "<#YourProjectName#>-Swift.h"
The file:<#YourProjectName#>-Swift.h
should already be created automatically in your project, even if you can not see it.
Step 3: Use your class
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);
Notes:
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 errordyld: 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 toNSObjectProtocol
(easiest way to do this is to inherit fromNSObject
), or to be anenum
marked@objc
with a raw value of some integer type likeInt
. You may view the edit history for an example of Swift 1.x code using@objc
without these restrictions.
这篇关于如何从 Swift 调用 Objective-C 代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!