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

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

提问人:programcode 提问时间:1/23/2021 最后编辑:programcode 更新时间:1/23/2021 访问量:1541

问:

此代码来自 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 后,构建 App 时会显示两个错误

//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'

这是在编译时出现类似的错误,之前被添加到演示 Swift 函数 MockApiClient 中。是否应该将其添加到其他地方?我尝试在此处的答案中提到的枚举中添加,但无济于事。@objc@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 中创建了一个演示类,同时仍在 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. 将导入复制到自动生成的文件中,以将其中的 Objective C 暴露给 swift#import "ViewController.h"project-Bridging-Header.h

  4. 将必要的 Swift 文件添加到 Objective C 项目中,以便可以找到Constants.publishablekeyConstants.swift

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

编辑:添加到声明时出错@objcenumConstants.swift

enter image description here

iOS Swift iPhone Xcode Cocoa-Touch

评论

2赞 matt 1/23/2021
如果 STPPaymentConfiguration 和 Constants 是 Swift 对象,那么要被 Objective-C 看到,它们需要是 Objective-C 可以看到的类型(即用 公开的类),并且 Objective-C 文件需要导入自动生成的头文件(与“添加”头文件无关)。@objc

答:

1赞 matt 1/23/2021 #1

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

然后,你的 Swift 内容需要进入该文件。要做到这一点,它们需要是 Objective-C 完全可以看到的类型(即类),并且它们需要显式地暴露给具有适当属性的 Objective-C。@objc

评论

0赞 programcode 1/23/2021
感谢您@matt回复。您能否验证正确的步骤是创建桥接头,添加到 Appdelegate.m,添加 ,到桥接头文件,因为它包含一个包含所有 Stripe 头文件的 .m 文件,然后和桥接头文件,然后将 Swift 行添加到方法中,然后添加前缀?#import "YourProject-Swift.h"#import "Stripe.h"AppDelegate.hAppdelegate.mdidFinishLaunchingWithOptions@objc
0赞 programcode 1/23/2021
具体来说,我尝试过@objc枚举常量......在常量中.swift并显示编译器警告:“@objc”枚举必须声明整数原始类型
0赞 matt 1/23/2021
是的,你读过我说的话吗?我非常清楚目标 C 可以看到什么。我提到枚举了吗?我说的不是桥接头。请阅读我实际说的话。
2赞 OOPer 1/23/2021 #2

编辑:将@objc添加到常量中的枚举声明时出错.swift

用作命名空间的 Swift 枚举不能向 Objective-C 公开。 你可能需要使用它来使它同时适用于 Swift 和 Objective-C:class

@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() {}
}

评论

0赞 programcode 1/23/2021
谢谢。按照建议更新文件后,错误消失了,因此要知道该应用程序似乎正在正式读取 Constant 属性。现在只有一个错误Constants.SwiftUse of undeclared identifier 'Constants'Property 'shared' not found on object of type 'STPPaymentConfiguration'. Any ideas?
0赞 programcode 1/23/2021
委托中使用的类是从 Stripe Cocoapods 中声明的。考虑到这个类已经写在目标 C 中,如何进一步包含它?STPPaymentConfigurationSTPPaymentConfiguration.h
2赞 OOPer 1/23/2021
据我查看 Stripe 的文档页面,所有类型、属性和方法都已标记为 .但是其中一些被赋予了独立于 Swift 名称的 Objective-C 名称。查看文档。@objc