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

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


当前回答

混合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代码

(词汇)

其他回答

在Xcode 10.1中的Swift 4.2.1项目中,您可以轻松地添加Objective-C文件。按照以下步骤将Objective-C文件连接到Swift项目。

Step_01:使用Swift语言创建新的Xcode项目:

文件>新建>项目> objc。

在Swift项目中添加新的Objective-C文件:

File >新建>文件…> macOS > Objective-C文件。

Step_03:如果你第一次添加一个新的Objective-C文件到Swift项目中,Xcode会问你:

你想配置一个Objective-C桥接头吗?

Step_04:选择选项:

创建桥接头。

Step_05:将生成一个对应的文件,文件的名称如下:

Objc-Bridging-Header.h。

Step_06:现在,你需要在桥标头中设置桥文件路径。在项目导航器中单击名称为objc的项目,然后选择:

> Objective-C桥接头> objc桥接头。h

将Objc-Bridging-Header.h拖放到该框中生成文件路径。

打开你的Objc-Bridging-Header.h文件,并导入你想要在Swift文件中使用的Objective-C文件。

#import "SpecialObjcFile.m"

下面是SpecialObjcFile.m的内容:

#import <Foundation/Foundation.h>

@interface Person: NSObject {
@public
    bool busy;
}
@property
    bool busy;
@end

现在在你的Swift文件中,你可以使用一个Objective-C类:

override func viewDidLoad() {
    super.viewDidLoad()
    let myObjcContent = Person()
    print(myObjcContent.busy)
}

Create a .h file from NewFile -> Source -> header file Then save the name of file Your_Target_Name-Bridging-Header.h People here gets common mistake by taking their project name but it should be the Project's Target's name if in case both are different, generally they are same. Then in build settings search for Objective-C Bridging Header flag and put the address of your newly created bridging file, you can do it right click on the file -> show in finder -> drag the file in the text area then the address will be populated. Using #import Your_Objective-C_file.h In the swift file you can access the ObjC file but in swift language only.

你可以看看Swift & Cocoapods的帖子。基本上,我们需要创建一个桥接头文件,并将所有Objective-C头文件放在那里。然后我们需要从构建设置中引用它。之后,我们可以使用Objective-C代码。

let manager = AFHTTPRequestOperationManager()
manager.GET(
  "http://example.com/resources.json",
  parameters: nil,
  success: { (operation: AFHTTPRequestOperation!,
              responseObject: AnyObject!) in
      println("JSON: " + responseObject.description)
  },
  failure: { (operation: AFHTTPRequestOperation!,
              error: NSError!) in
      println("Error: " + error.localizedDescription)
  })

也可以看看苹果的文档Using Swift with Cocoa和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.

我还想补充一点:

我非常感谢@Logan的回答。创建桥文件和设置有很大帮助。

但是在做了所有这些步骤之后,我仍然没有在Swift中获得Objective-C类。

我使用cocoapods库并将其集成到我的项目中。也就是豆荚"pop"。

因此,如果你在Swift中使用Objective-C pod,那么可能有一个机会,你不能获得或导入类到Swift中。

你要做的一件简单的事情是:

转到<YOUR-PROJECT>-Bridging-Header文件和 将语句#import <ObjC_Framework>替换为@import ObjC_Framework

例如:(Pop library)

取代

#import <pop/POP.h>

with

@import pop;

当#import无效时使用clang import。