Skip to content

Instantly share code, notes, and snippets.

@maiyama18
Last active July 19, 2022 09:52
Show Gist options
  • Save maiyama18/260e123146cf0f28ed23b9db64756e9b to your computer and use it in GitHub Desktop.
Save maiyama18/260e123146cf0f28ed23b9db64756e9b to your computer and use it in GitHub Desktop.
import UIKit
import Combine
enum MessageViewControllerFactory {
static func createDefaultImplementation() -> MessageViewController<MessageRepository<APIClient>> {
return MessageViewController(viewState: MessageViewState())
}
}
final class MessageViewController<Repository: MessageRepositoryProtocol>: UIViewController {
private let viewState: MessageViewState<Repository>
private var messageLabel: UILabel?
private var cancellables: [AnyCancellable] = []
init(viewState: MessageViewState<Repository>) {
self.viewState = viewState
super.init(nibName: nil, bundle: nil)
view.backgroundColor = .white
setupMessageLabel()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
Task {
for await message in viewState.$message.values {
messageLabel?.text = message
}
}
Task {
await viewState.onViewLoaded()
}
}
private func setupMessageLabel() {
let messageLabel = UILabel()
messageLabel.text = "default"
view.addSubview(messageLabel)
messageLabel.translatesAutoresizingMaskIntoConstraints = false
messageLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
messageLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
self.messageLabel = messageLabel
}
}
final class MessageViewState<Repository: MessageRepositoryProtocol>: ObservableObject {
@Published private(set) var message: String = ""
func onViewLoaded() async {
message = await Repository.execute()
}
}
protocol MessageRepositoryProtocol {
static func execute() async -> String
}
struct MessageRepository<APIClient: APIClientProtocol>: MessageRepositoryProtocol {
static func execute() async -> String {
await APIClient.getMessage()
}
}
protocol APIClientProtocol {
static func getMessage() async -> String
}
struct APIClient: APIClientProtocol {
static func getMessage() async -> String {
try! await Task.sleep(nanoseconds: 1_000_000_000)
return "Hello, world!"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment