如何从 Swift 调用 Objective-C 代码? [英] How do I call Objective-C code from Swift?

查看:20
本文介绍了如何从 Swift 调用 Objective-C 代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 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);

注意事项:

  1. 如果 Code Completion 的行为不符合您的预期,请尝试使用 R 运行快速构建以帮助 Xcode从 Swift 上下文中找到一些 Objective-C 代码,反之亦然.

  2. 如果您将 .swift 文件添加到旧项目并得到错误 dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib,请完全尝试重启 Xcode.

  3. 虽然最初可以使用纯 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:

  1. 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.

  2. 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.

  3. 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.

这篇关于如何从 Swift 调用 Objective-C 代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆