编写一个类作为辅助服务并从另一个类中调用它

时间:2018-12-01 12:31:44

标签: swift

我正试图了解如何在Swift中解决这个问题。

例如,我有以下UIViewController

.movie .opening {
  display: none;
}

.active .opening {
  display: block
}

和AuthService

class ViewController: UIViewController {

    let logoutButton: UIButton = {
        let button = UIButton()
        button.setTitle("Logout", for: .normal)
        button.setTitleColor(UIColor.black, for: .normal)
        button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 24)
        button.addTarget(self, action: #selector(onPressLogout), for: .touchUpInside)
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        navigationItem.title = "Logged in"

        view.addSubview(logoutButton)
        NSLayoutConstraint.activate([
            logoutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            logoutButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
    }

    @objc fileprivate func onPressLogout() {
        AuthService.logOut()
    }
}

我想做的就是在按下final class AuthService { static func logOut() -> Void { print("Logout Pressed") } } 时在我的logOut上呼叫AuthService

我想了解的是如何以正确和最佳的方式访问onPressLogout

例如,像我现在一样?类上的静态方法?

我应该像这样创建它的实例

logOut

然后通过lazy var auth = AuthService() 退出而不使用auth.logOut()关键字吗?

我对创建这些“帮助”类的最佳方法感到困惑。

3 个答案:

答案 0 :(得分:2)

我不知道AuthService的确切用法,但是您可以考虑以Singleton模式编写它。

这保证了仅初始化该类的一个实例。单例模式的示例:URLSession.sharedUserDefaults.standard

这样,您将可以通过AuthService.shared.logout()AuthService.shared.isUserLoggedIn之类的方式访问它

答案 1 :(得分:1)

使用单例是一种常见的做法。

出于可测试性,我建议您将AuthService注入为依赖项。首先,我将创建一个协议:

protocol AuthServiceProtocol {
    func logOut()
}

然后,我将使我的服务符合该协议。 (请注意:此类可以设置为单例,这对我在这里的目的演示依赖注入确实无关紧要。)

class AuthService: AuthServiceProtocol {
    func logOut() {
        print("Logout Pressed")
    }
}

我会在我的视图控制器中添加一个类级变量:

class ViewController: UIViewController {
    var authService: AuthServiceProtocol?

    //existing code...
}

注销功能需要进行如下更改:

@objc fileprivate func onPressLogout() {
    authService?.logOut()
}

创建视图控制器后,我会将服务传递给它:

let vc = ViewController()
vc.authService = AuthService()

就是这样。我可以像这样在操场上进行测试:

//TEST by forcing view to load and sending fake button touch event
let _ = vc.view
vc.logoutButton.sendActions(for: .touchUpInside)

//prints... "Logout Pressed"

现在,我可以编写一个真实的单元测试,该测试可以通过没有依赖性的模拟服务。这使我可以更可靠地测试视图控制器。

答案 2 :(得分:0)

我也许会使用singleton来解决这个问题。

struct AuthService {

    static let shared: AuthService = {
        return AuthService()
    }()

    func logOut() -> Void {
        print("Logout Pressed")
    }
}

这将允许您像AuthService.shared.logOut()

那样调用方法