Skip to content

Instantly share code, notes, and snippets.

@yoxisem544
Last active June 17, 2017 08:50
Show Gist options
  • Save yoxisem544/7f9e4366fcec96168732d69134253aed to your computer and use it in GitHub Desktop.
Save yoxisem544/7f9e4366fcec96168732d69134253aed to your computer and use it in GitHub Desktop.
// VIPER template for Xcode code snippet.
// This is not a tipical VIPER arichtecture.
// It's a VIPER with builder, I called it b-viper.
// View is simple.
// Define what will happen on view.
// Like content reload, reviece new data.
// Plug it to view controller.
public protocol <#SomeView#>: class {
// Like, present new content
}
// Router handles all view navigation jobs.
// So, router holds a weak reference to view controller.
public protocol <#SomeRouter#> {
}
final public class <#SomeDefaultRouter#> : <#SomeRouter#> {
public weak var viewController: UIViewController?
public init(viewController: UIViewController) {
self.viewController = viewController
}
}
// Interactor contains all your business logics,
// includes, make api requests, store some data to data base, do some calaulations.
// Also, I put NotificationCenter observing here.
// When interactor gets a notification,
// when then notitfy presenter to do some job or do the job interactor has been told to.
//
// Interactor knows about entity, service, manager.
// Will use these services to finish business logics.
//
// If necessary, interactor can have a delegate and owns by presenter.
// To get notified by update from interactor. (Like get notification, listening to a socket.)
// I think all business logics should all be inside interactor.
public protocol <#SomeInteractor#> {
// something like, get locations for weather app
// make a api call then get the data presenter wanted.
// store data to data base.
}
final public class <#SomeDefaultInteractor#> : <#SomeInteractor#> {
// init wtih required entity, service or manager
}
// Presenter's jobs is to handle user interactions.
// To ask interactor for an update.
// After work done, presenter will tell view to update its content.
public protocol <#SomePresenter#> {
// Something like, load initial content.
// user has trigger a button click with username and password, what's next?
}
// Presenter holds a weak reference to view, in order to update view.
// Holds a router and an interactor.
final public class <#SomeDefaultPresenter#> : <#SomePresenter#> {
private weak var view: <#SomeView#>?
private let router: <#SomeRouter#>
private let interactor: <#SomeInteractor#>
// A init template.
required public init(view: <#SomeView#>, router: <#SomeRouter#>, interactor: <#SomeInteractor#>) {
self.view = view
self.router = router
self.interactor = interactor
}
}
// Builder is a funny part here.
// VIPER do not have a builder part.
// I think builder as playing with LEGO,
// You are able to build slightly different module by giving different service, manager, or an interactor.
// If you are building a weather app, sometimes you do not want weather data from yahoo, you prefer data from google.
// All you need to do is just build another service that fetch data from google.
// Then plug it to the builder, and you are good to go!
//
// (You can have one builder that builds different modules.)
import UIKit
public protocol <#SomeBuilder#> {
func buildSomeModule() -> UIViewController?
}
final public class <#SomeDefaultBuilder#> : <#SomeBuilder#> {
}
// Entity, service, manager are the basics of your app.
// You can have a DatabaseService to handle all database work.
// To have a WeatherDataFetchService to fetch weather data.
//
// According to Uncle Bob's clean architectrue, these are the core part of your application.
// If you want to make testing app easy.
// This architecture should help.
// To test entity, service, manager is easy.
// So this means that testing other parts of code is simpler by mocking these entity.
public protocol <#SomeService#> {
}
final public class <#SomeDefaultService#> : <#SomeService#> {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment