Skip to content

Instantly share code, notes, and snippets.

View Sajjon's full-sized avatar
💭
Core Developer @ Parity 12ktCaPgc745AwxALoU4E2NAhAc8aW3ytSM5Qigi3SwaNodc

Alexander Cyon Sajjon

💭
Core Developer @ Parity 12ktCaPgc745AwxALoU4E2NAhAc8aW3ytSM5Qigi3SwaNodc
View GitHub Profile
@Sajjon
Sajjon / ViewModelType.swift
Created November 26, 2018 09:53
Medium article: SLC part 1 - ViewModelType
protocol ViewModelType {
associatedtype Input: InputType
associatedtype Output
func transform(input: Input) -> Output
}
@Sajjon
Sajjon / InputType.swift
Created November 26, 2018 09:53
Medium article: SLC part 1 - InputType
protocol InputType {
associatedtype FromView
associatedtype FromController
var fromView: FromView { get }
var fromController: FromController { get }
init(fromView: FromView, fromController: FromController)
}
@Sajjon
Sajjon / BaseViewModel.swift
Created November 26, 2018 13:48
Medium article: SLC part 1 - BaseViewModel
import RxSwift
import RxCocoa
class BaseViewModel<NavigationStep, FromView, Output>: ViewModelType {
let bag = DisposeBag()
// Small type wrapping a RxSwift PublishSubject, that we notify about navigation, passing
// a contextual `NavigationStep` which typically is an enum, modelling all possible
// outgoing navigation steps we can take from this scene.
let navigator = Stepper<NavigationStep>()
@Sajjon
Sajjon / AuthenticationViewModel.swift
Last active November 26, 2018 14:31
Medium article: SLC part 1 - ViewModel (simple)
// The cases should be named as if they were prefixed with the words
// "user intends to" or "user did"
enum AuthenticateNavigationStep {
case signIn
case signUp
}
final class AuthenticateViewModel: BaseViewModel<
AuthenticateNavigationStep,
AuthenticateViewModel.InputFromView,
@Sajjon
Sajjon / AuthenticationCoordinator.swift
Created November 26, 2018 14:25
Medium article: SLC part 1 - Coordinator
private extension AuthenticationCoordinator {
func toAuthentication() {
let viewModel = AuthenticateViewModel()
push(scene: Authenticate.self, viewModel: viewModel) { [unowned self] userIntendsTo in
switch userIntendsTo {
case .signUp: self.toSignIn()
case .signIn: self.toSignUp()
}
@Sajjon
Sajjon / SceneController.swift
Last active November 26, 2018 15:23
Medium article: SLC part 1 - ViewController base
import RxSwift
class SceneController<View>: UIViewController where View: UIView & ViewModelled {
typealias ViewModel = View.ViewModel
private let bag = DisposeBag()
private let viewModel: ViewModel
// We omit some additional "AbstractTarget" wrappers taking these `PublishSubjects` as arguments
@Sajjon
Sajjon / Authenticate.swift
Created November 26, 2018 15:50
Medium article: SLC part 1 - Authenticate Controller
/* This ⬇ single line ⬇ constitutes a fully working ViewController. Clean code 👌🏽 */
typealias Authenticate = SceneController<AuthenticateView>
@Sajjon
Sajjon / SignInView.swift
Last active November 27, 2018 10:49
Medium article: SLC part 1 - SignInView
final class SignInView: UIView {
// Some loading view, it might contain a `UIActivityIndicatorView`
// it has reactive binding for `isLoading`, but starts invisible
private lazy var loadingView = LoadingView()
// In fact these TextFields are some subclass capable of displaying validation errors
private lazy var usernameField = UITextField()
private lazy var passwordField = UITextField()
private lazy var confirmPasswordField = UITextField()
@Sajjon
Sajjon / AuthenticationUseCase.swift
Created November 27, 2018 12:51
Medium article: SLC part 1 - AuthenticationUseCase
protocol AuthenticationUseCase: AnyObject {
func signIn(request: SignInRequest) -> Observable<Void>
}
struct SignInRequest {
let username: String
let password: String
}
@Sajjon
Sajjon / Validation.swift
Created November 27, 2018 12:52
Medium article: SLC part 1 - Validation
enum Validation<Validated> {
case valid(Validated)
case invalid(errorMessage: String)
var asValidated: Validated? {
switch self {
case .valid(let validated): return validated
default: return nil
}
}