【问题标题】:Access delegate protocol from Swift framework into Objective C从 Swift 框架访问委托协议到 Objective C
【发布时间】:2019-12-27 09:26:50
【问题描述】:

我创建了Swift 框架并集成到ObjC 项目中。

现在,我想在ObjC 中传递/访问委托处理程序。

Swift 框架包含带有关闭和提交按钮的UIViewController

ListViewController.swift SwiftFramework

public protocol ListHandler {
    func submit(options: String)
    func close()
}

public class ListViewController: UIViewController {

    public var handler: ListHandler?

    @objc func dismiss(_ sender: UIButton) {
        handler?.close()
    }

    @objc func submit(_ sender: UIButton) {
        handler?.submit(options: "Done")
    }
}

已创建 MyApp-Bridginh-Header.hSwiftWrapper.swift 显示 ListViewController

import SwiftFramework

@objc public class SwiftWrapper: NSObject {

    @objc public var controller: ListViewController?

    override init() {
        print("Working")
    }

    @objc public func showListScreen() -> UIViewController {

        self.controller = ListViewController(title: "List")

        /*
          IMPORTANT: How I can pass this to ObjC called controller?
        */
        // self.controller?.handler =
        return self.controller!
    }
}

终于在 objC 视图控制器中,能够显示列表屏幕但不能传递委托和处理提交/关闭按钮操作。

ProductListViewController.m

#import "MyApp-Swift.h"

SwiftWrapper *wrapper = [[SwiftWrapper  alloc] init];

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:[wrapper showListScreen]];
[self presentViewController:navController animated:YES completion:nil];

如何进入这里?

示例项目存储库: 斯威夫特框架:https://github.com/harshal-wani/SwiftListFramework ObjC 项目:https://github.com/harshal-wani/SwiftFrameworkDelegateExample

感谢您的帮助和建议。

谢谢

【问题讨论】:

  • 为什么你的协议不是@objc?你还想在哪里访问这个代表?我在你的代码中看不到它
  • 您不能将@objc 添加到委托属性,因为它的类型不能在Objective-C 中表示

标签: ios objective-c swift frameworks delegates


【解决方案1】:

从 cmets 继续,您应该使协议与 Objective-c 一起使用 开始:

@objc public protocol ListHandler {
    func submit(options: String)
    func close()
}

然后你就可以制作了

@objc public var handler: ListHandler?

【讨论】:

  • 显示错误:方法不能是@objc协议的成员,因为参数的类型不能在Objective-C中表示
  • 上传了两者的示例存储库。请检查
  • @HarshalWani 在您的示例中您仍然没有将@objc 添加到protocol ListHandler,请使用我们的建议,然后尝试使用您的代码
  • 正如我之前在评论中回答的那样,已经尝试过了。也在演示项目中显示错误:使用未声明的类型'ListHandler'
  • 也许我做错了什么。感谢您的帮助,请尝试在 repos 中进行更改,谢谢
【解决方案2】:

包装类为您完成工作。让我们在 wrapper 类中添加所有可以管理内部框架类功能的函数。

查看源代码后,您需要对所有类进行大量更改。让我们从ListViewController开始。

  1. 为协议定义提供协议类类型。您可以使用NSObject

所以你的协议会是这样的:

public protocol ListHandler: NSObject {
    func submit(options: String)
    func close()
}
  1. SwiftWrapper 类:使用这个类你不能直接将handler 传递给 Objective-C 类,所以你需要在这个类中创建一个可以与 Objective-C 类通信的委托或协议。

所以在这个类中创建一个委托:

@objc protocol SwiftWrapperDelgate {
    func submit(options: String)
    func close()
}

现在,ListViewControllerprotocol 方法必须在这个类中声明,以便我们可以从这里将它传递给 Objective-C。创建一个extension 来监听协议方法。

extension SwiftWrapper : ListHandler {
    public func submit(options: String) {
        self.delegate?.submit(options: options)
    }

    public func close() {
        self.delegate?.close()
    }
}

并且,不要忘记在showListscreen() 函数中分配委托,否则此方法将不会调用。

@objc public func showListscreen() -> UIViewController {
    self.controller = ListViewController(title: "Demo List")
    self.controller?.handler = self
    return self.controller!
}
  1. 现在在 Objective-C ViewController.m 文件中分配 SwiftWrapper 类的委托

    @interface ViewController () <SwiftWrapperDelgate>
    
    @property (nonatomic, strong) SwiftWrapper *wrapper;
    @property (nonatomic, strong) ListViewController *controller;
    
    @end
    

这里我为SwiftWrapper & ListViewController创建了全局变量

viewDidLoad() 中创建SwiftWrapper 类的对象并将其分配给self

- (void)viewDidLoad {
    [super viewDidLoad];

    self.wrapper = [SwiftWrapper new];
    self.wrapper.delegate = self;
}

最后,创建将在ListViewController 类的操作时调用的委托方法。

- (void)submitWithOptions:(NSString *)options {
    NSLog(@"Submit button tapped");
}

- (void) close {
    NSLog(@"Close button tapped");
}

按照这些步骤来实现您的要求。

【讨论】:

  • 当用户点击 Objc 类时似乎无法捕捉到提交/关闭操作?我们该怎么办?
  • 上传了两者的示例存储库。请检查
  • 完美运行!实际上,我试图避免创建双重委托,但似乎行不通。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多