如何从 Objective C 项目 App Delegate 调用 Swift?

How to call Swift from an Objective C project App Delegate?

此代码来自 Swift 项目 App 委托。它用于帮助使用可发布密钥配置 Stripe。

//Appdelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: 
[UIApplicationLaunchOptionsKey: Any]?) -> Bool 
{
//The code helps configure Stripe with a publishable key.
STPPaymentConfiguration.shared().publishableKey = Constants.publishableKey
...
}

将 Swift 行添加到 Objective C App Delegate

后构建应用程序时显示两个错误
//AppDelegate.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
STPPaymentConfiguration.shared().publishableKey = Constants.publishableKey

Property 'shared' not found on object of type 'STPPaymentConfiguration'
Use of undeclared identifier 'Constants'

这是在 @objc 添加到演示 Swift 函数 MockApiClient 之前编译时出现的类似错误。是否应该在其他地方添加?我已尝试将 @objc 添加到枚举中,如此处的答案中所述,但无济于事。

//Constants.swift 
//This is the file the original Swift app delegate accesses
import Foundation

  enum Constants {
  static let publishableKey = "pk_live_..."
  static let baseURLString = "http://54.33.123.227:1234"
  static let defaultCurrency = "usd"
  static let defaultDescription = "Receipt" //change to describe actual app & charge
  }

采取的步数:

  1. 打开了Objective C项目并创建了一个桥接头

  2. 在 Swift 中创建了一个演示 class,同时还在 Obj C 项目中以确保它可以使用,在本例中是从 Objective C 文件加载视图时。具体派生自 NSObject。将覆盖添加到初始化程序并使用 @objc 前缀。

    //  MockApiClient.swift
    import Foundation
    class MockApiClient: NSObject
    {
    override init()
    {
    print("Initializer called in Mock API client")
    }
    @objc func executeRequest()
    {
    print("The execute request has been called in the Mock API Client")
    }
    }
    
    //ViewController.h
    //Prints the Swift request written in the MockApiClient the the view loads
    
    @implementation ViewController
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    MockApiClient *client = [MockApiClient new];
    [client executeRequest];
    }
    
  3. #import "ViewController.h" 导入复制到自动生成的 project-Bridging-Header.h 文件,以将其中的 Objective C 暴露给 swift

  4. 向 Objective C 项目添加了必要的 Swift 文件,以便可以找到来自 Constants.swiftConstants.publishablekey 数据

如何将此Swift App 委托代码添加到Objective C 项目的App 委托中?

编辑:将 @objc 添加到 Constants.swift

中的 enum 声明时出错

Objective-C 能否查看 Swift 中定义的内容取决于自动生成的头文件。这是不是桥接头。它是一个隐藏在您的派生数据中的头文件,名为 YourProject-Swift.h。您的 Objective-C .m 文件需要 #import "YourProject-Swift.h"(使用正确的名称)。

然后,您的 Swift 内容需要进入该文件。为此,它们需要是 Objective-C 完全可以看到的类型(即 类),并且它们需要通过适当的 @objc 显式暴露给 Objective-C属性。

Edit: error when adding @objc to the enum declaration in Constants.swift

Swift 用作命名空间的枚举无法公开给 Objective-C。 您可能需要使用 class 才能使其同时适用于 Swift 和 Objective-C:

@objcMembers
class Constants: NSObject {
    static let publishableKey = "pk_live_..."
    static let baseURLString = "http://54.33.123.227:1234"
    static let defaultCurrency = "usd"
    static let defaultDescription = "Receipt" //change to describe actual app & charge
    
    private override init() {}
}