管理委托出 UIViewController class

Manage Delegate out UIViewController class

我想了解实现委托的最佳方式是什么 UIViewController class

如何使用 AuthManager 中函数的 controller: UIViewController 参数管理委托?

这是我正在使用的两个 classes ..我给你看一些小例子来让你理解

 class StartController: UIViewController {

    @objc private func presentAuthFacebookController() {
        AuthManager.signInWithFacebook(controller: self)
    }
}

class AuthManager {
static func signInWithFacebook(controller: UIViewController) {

    let loginManager = LoginManager()
    loginManager.logIn(permissions: [.publicProfile, .email], viewController: controller) { (result) in

        switch result {
        case .cancelled : print("\n AuthFacebook: operazione annullata dall'utente \n")
        case .failed(let error) : print("\n AuthFacebook: \(error) \n")
        case .success(granted: _, declined: let declinedPermission, token: _):


            let authVC = ExistingEmailController()

            authVC.delegate = // ?????? (controller)

            UIApplication.shared.windows.first?.rootViewController?.present(authVC, animated: true, completion: nil)
        }
    }
}
}

我个人认为StartController不应该知道about/conform到ExistingEmailControllerDelegate。但如果你真的想要,你可以将 controller 声明为组合类型:

static func signInWithFacebook(controller: UIViewController & ExistingEmailControllerDelegate) {
    ...
    authVC.delegate = controller

在我看来,拥有 AuthManager 的全部意义在于 ExistingEmailController 之上创建一个抽象层 ,并 封装认证逻辑。因此,StartController 不应该知道或关心 ExistingEmailControllerDelegate。它只知道 AuthManager

AuthManager 应该是 ExistingEmailController 的委托,这意味着 signInWithFacebook 不应该是静态的,并且 AuthManager 可以有一个 AuthManagerDelegate StartController 符合:

class AuthManager : ExistingEmailControllerDelegate {
    weak var delegate: AuthManagerDelegate?

    func signInWithFacebook(controller: UIViewController) {

        ...

        let authVC = ExistingEmailController()

        authVC.delegate = self

        UIApplication.shared.windows.first?.rootViewController?.present(authVC, animated: true, completion: nil)
    }

    func someMethodFromExistingEmailControllerDelegate() {
        delegate?.someMethod() // delegating it self.delegate, which StartController conforms to
    }
}

protocol AuthManagerDelegate : class {
    func someMethod()
}

 class StartController: UIViewController, AuthManagerDelegate {

    var authManager: AuthManager!

    override func viewDidLoad() {
        authManager = AuthManager()
        authManager.delegate = self
    }

    @objc private func presentAuthFacebookController() {
        authManager.signInWithFacebook(controller: self)
    }

    func someMethod() {
        // write here the code that you would have written in someMethodFromExistingEmailControllerDelegate
    }
}