Last active
November 29, 2017 01:08
-
-
Save cjnevin/2f7c17f3ee973707f675cfa4c55e7b4e to your computer and use it in GitHub Desktop.
Login UseCase/Repository/Service setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Domain | |
struct User { | |
let firstName: String | |
let lastName: String | |
} | |
struct LoginUseCase { | |
enum Error: Swift.Error { | |
case invalidCredentials | |
case invalidResponse | |
} | |
struct Request { | |
let username: String | |
let password: String | |
} | |
struct Response { | |
let user: User | |
} | |
enum Result { | |
case success(Response) | |
case failure(Error) | |
} | |
let repository: LoginRepositoryType | |
func login(with request: Request, completion: @escaping (Result) -> ()) { | |
repository.login(with: request.username, password: request.password, completion: { (user, error) in | |
guard let user = user else { | |
guard let error = error as? Error else { | |
completion(Result.failure(.invalidResponse)) | |
return | |
} | |
completion(Result.failure(error)) | |
return | |
} | |
completion(Result.success(.init(user: user))) | |
}) | |
} | |
} | |
protocol LoginUseCaseProviderType { | |
func makeLoginUseCase() -> LoginUseCase | |
} | |
protocol LoginRepositoryType { | |
func login(with username: String, password: String, completion: @escaping (User?, Error?) -> ()) | |
} | |
//: Platform | |
protocol NetworkType { } | |
struct Network: NetworkType { } | |
protocol LoginStorageType { } | |
struct LoginStorage: LoginStorageType { } | |
struct LoginUseCaseProvider: LoginUseCaseProviderType { | |
let repository: LoginRepositoryType | |
func makeLoginUseCase() -> LoginUseCase { | |
return LoginUseCase(repository: repository) | |
} | |
} | |
struct LoginRepository: LoginRepositoryType { | |
private let network: NetworkType | |
private let storage: LoginStorageType | |
init(network: NetworkType, storage: LoginStorageType) { | |
self.network = network | |
self.storage = storage | |
} | |
func login(with username: String, password: String, completion: @escaping (User?, Error?) -> ()) { | |
completion(User(firstName: "first", lastName: "last"), nil) | |
} | |
} | |
protocol LoginRepositoryProviderType { | |
func makeRepository() -> LoginRepositoryType | |
} | |
struct LoginRepositoryProvider: LoginRepositoryProviderType { | |
private let network: NetworkType | |
private let storage: LoginStorageType | |
init(network: NetworkType, storage: LoginStorageType) { | |
self.network = network | |
self.storage = storage | |
} | |
func makeRepository() -> LoginRepositoryType { | |
return LoginRepository(network: network, storage: storage) | |
} | |
} | |
struct RepositoryProvider { | |
let loginRepositoryProvider: LoginRepositoryProviderType | |
init() { | |
loginRepositoryProvider = LoginRepositoryProvider(network: Network(), storage: LoginStorage()) | |
} | |
} | |
struct ServiceProvider { | |
let loginUseCaseProvider: LoginUseCaseProviderType | |
init(repositoryProvider: RepositoryProvider) { | |
self.loginUseCaseProvider = LoginUseCaseProvider(repository: repositoryProvider.loginRepositoryProvider.makeRepository()) | |
} | |
} | |
let repositoryProvider = RepositoryProvider() | |
let serviceProvider = ServiceProvider(repositoryProvider: repositoryProvider) | |
let useCase = serviceProvider.loginUseCaseProvider.makeLoginUseCase() | |
let request = LoginUseCase.Request(username: "username", password: "password") | |
useCase.login(with: request) { (result) in | |
switch result { | |
case let .failure(error): | |
print(error) | |
case let .success(user): | |
print(user) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment