Home > Software design >  How to access callback function in adjacent Swift class method
How to access callback function in adjacent Swift class method

Time:11-28

I'm building an app that prompts the users for their contacts. I'm brand new to Swift but making decent progress.

I'm invoking this open function from a parent call site and want to receive the response value back from the contactPicker function. I'm a bit unfamiliar with the implied nature of the contactPicker invocation, and was expecting to have to invoke it directly from within the presentContactPicker function, but the documentation seemed to suggest this approach is preferable.

As it stands now, this implementation correctly prompts the Contact Picker UI, and prints the selected contacts to the console. But I need assistance actually passing the contacts to the callback function.

The issue that I have is that I'm not able to access the callback function from inside the contactPicker. I have an intuition that maybe I could attach the callback to the parent class with a technique like self.callback = callback in the open function and then call self.callback() in the contactPicker itself, but it didn't work.

import Foundation
import UIKit
import ContactsUI

@objc(ContactsPicker)
class ContactsPicker : NSObject, CNContactPickerDelegate {
  
  @objc static func requiresMainQueueSetup() -> Bool {
    return false
  }
  
  @objc func open(_ options: NSDictionary, callback: RCTResponseSenderBlock) -> Void {
    DispatchQueue.main.async {
      self._presentContactPicker(options: options)
    }
  }
  
  func _presentContactPicker(options: NSDictionary) -> Void {
      let contactPickerVC = CNContactPickerViewController()
      contactPickerVC.delegate = self
      let controller = RCTPresentedViewController()
      controller?.present(contactPickerVC, animated: true)
  }
  
  func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
    print("                           ")
    print(contacts)
    print("                           ")

    ### But how can I access the callback from the exposed open method?
  }
}

CodePudding user response:

maybe I could attach the callback to the parent class with a technique like self.callback = callback in the open function and then call self.callback() in the contactPicker itself

This is the right idea. You can declare a property to store the callback like this:

private var callback: RCTResponseSenderBlock?

@objc func open(_ options: NSDictionary, callback: @escaping RCTResponseSenderBlock) -> Void {
    self.callback = callback
    DispatchQueue.main.async {
        self._presentContactPicker(options: options)
    }
}

Note that the since the callback "escapes" into the class, you should mark the parameter as @escaping.

func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
    callback(someParameters)
}
  • Related