首页 > 解决方案 > 在 Flutter 中使用平台特定代码时如何在 App Delegate 中实现协议委托模式?

问题描述

我想在 iOS 上为我的 Flutter 应用程序实现特定于平台的代码。我想从原生 iOS 实现 EventKit。但是现在我很困惑如何在 Flutter 中使用 Platform Channel 时在应用程序委托中实现协议委托模式。

在本机 iOS 中,我的代码将是这样的

import EventKitUI

class MyViewController : UIViewController, EKEventEditViewDelegate, UINavigationControllerDelegate {
    

    override func viewDidLoad() {
       super.viewDidLoad()
    
    
    }


   @IBAction func buttonPressed(_ sender: Any) { 

      // after pressing a button then show a VC
      showEventKitViewController()
   }
    
    func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
        // this is the method to conform the protocol
        
        dismiss(animated: true, completion: nil)
    }
    

    
    func showEventKitViewController() {
        
        
        let eventVC = EKEventEditViewController()
        eventVC.editViewDelegate = self // I am confused in this line
        eventVC.eventStore = EKEventStore()
        
    
        let event = EKEvent(eventStore: eventVC.eventStore)
        eventVC.event = event
        present(eventVC, animated: true)
    }
}

如您所见,我将self( MyViewController 类作为委托)分配给editViewDelegate

现在我很困惑如何showEventKitViewController在下面的 Flutter 应用程序委托中实现上面的方法

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    
    
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    
    let channel = FlutterMethodChannel(name: "useOtherApp", binaryMessenger: controller.binaryMessenger)
    channel.setMethodCallHandler({ (call: FlutterMethodCall, result: FlutterResult) -> Void in
        
        if (call.method == "saveToEventKit") {
            
            // what should I do in here to get the same result like my code above in native?
            
        }
        
    })
}

特别是当我需要分配一个类作为这样的代表editViewDelegate

在此处输入图像描述

标签: iosswiftflutter

解决方案


我可以通过使用扩展来使用这样的代码来解决它。请滚动到最底部以查看 FlutterViewController 扩展

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    
    setUpMethodChannels(controller: controller) // set the method channel

    
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
    

    
    private func setUpMethodChannels(controller: FlutterViewController) {
        
        let channel = FlutterMethodChannel(name: "useOtherApp", binaryMessenger: controller.binaryMessenger)
        channel.setMethodCallHandler({ (call: FlutterMethodCall, result: FlutterResult) -> Void in
            
            guard let args = call.arguments as? [String : Any] else {return}
            
            if (call.method == "saveToCalendar") {
            
                let eventVC = EKEventEditViewController()
                eventVC.editViewDelegate = controller // set FlutterViewController as the delegate
                eventVC.eventStore = EKEventStore()
                        
                let event = EKEvent(eventStore: eventVC.eventStore)
                eventVC.event = event
                eventVC.title = "hallooooo"
                controller.present(eventVC, animated: true)
            
                
            } else {
                result(FlutterMethodNotImplemented)
            }

        })
        
        
    }
    
    
}




// set the extension like below OUTSIDE the AppDelegate class
extension FlutterViewController : EKEventEditViewDelegate, UINavigationControllerDelegate {
    
    // conform to the EKEventEditViewDelegate protocol
    public func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
        dismiss(animated: true, completion: nil)
    }
    
    
}

推荐阅读