Ios 将委托协议从Swift框架访问到目标C

Ios 将委托协议从Swift框架访问到目标C,ios,objective-c,swift,frameworks,delegates,Ios,Objective C,Swift,Frameworks,Delegates,我已经创建了Swift框架并集成到ObjC项目中 现在,我想在ObjC中传递/访问委托处理程序 Swift框架包含带有关闭和提交按钮的UIViewController ListViewController.swiftSwiftFramework public protocol ListHandler { func submit(options: String) func close() } public class ListViewController: UIViewContr

我已经创建了
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];
如何进入这里

项目存储库示例: Swift框架: ObjC项目:

感谢您的帮助和建议


感谢继续评论,您应该制定使用objective-c的协议 首先:

@objc public protocol ListHandler {
    func submit(options: String)
    func close()
}
那么你就可以

@objc public var handler: ListHandler?

包装器类为您完成这项工作。让我们在包装类中添加所有可以管理内部框架类特性的函数

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

  • 为协议定义提供协议类类型。您可以使用
    NSObject
  • 因此,您的协议将类似于:

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

    @objc protocol SwiftWrapperDelgate {
        func submit(options: String)
        func close()
    }
    
    现在,必须在此类中声明
    ListViewController
    协议
    方法,以便我们可以从这里将其传递给Objective-C。创建
    扩展
    以侦听协议方法

    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!
    }
    
  • 现在,在Objective-C
    ViewController.m
    文件中,分配
    SwiftWrapper
    类的委托

    @interface ViewController () <SwiftWrapperDelgate>
    
    @property (nonatomic, strong) SwiftWrapper *wrapper;
    @property (nonatomic, strong) ListViewController *controller;
    
    @end
    
    最后,创建将在
    ListViewController
    类的操作中调用的委托方法

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

    按照以下步骤实现您的需求

    为什么您的协议不是
    @objc
    ?另外,您在哪里尝试访问此代理?我在你的代码中看不到它。你不能将@objc添加到委托属性,因为它的类型不能在Objective C中表示。显示错误:方法不能是@objc协议的成员,因为参数的类型不能在两者的Objective CUploaded示例存储库中表示。请check@HarshalWani在您的示例中,您仍然没有将@objc添加到
    协议ListHandler
    ,请使用我们的建议,然后尝试使用您的代码,正如我之前在评论中回答的,已经尝试过。同样在演示项目中显示错误:使用未声明的类型“ListHandler”可能是我做错了什么。感谢您的帮助,请尝试在回购中进行更改,Thankseems在用户单击Objc类时无法捕获提交/关闭操作?我们该怎么做?上传了这两个示例库。请检查工作是否完美!实际上,我试图避免创建双重委托,但似乎无法工作。
    - (void)submitWithOptions:(NSString *)options {
        NSLog(@"Submit button tapped");
    }
    
    - (void) close {
        NSLog(@"Close button tapped");
    }