View Routing.swift
protocol CanDisplayHeroDetailsScreen { | |
func displayHeroDetailsScreen(presenter aPresenter: Presenter) | |
} | |
extension CanDisplayHeroDetailsScreen where Self: UIViewController { | |
func displayHeroDetailsScreen(presenter aPresenter: Presenter) { | |
let detailsVC = HeroDetailsViewController.instantiateFromStoryboard(presenter: aPresenter) | |
navigationController?.pushViewController(detailsVC, animated: true) | |
} |
View HeroListPresenter.swift
final class HeroListPresenter: Presenter { | |
private let service: HeroService | |
weak private var view : HeroListView? | |
... | |
init(service: HeroService) { | |
self.service = service | |
} | |
func attachView(view: HeroListView) { |
View HeroListView.swift
protocol HeroListView: NSObjectProtocol { | |
func startLoading() | |
func finishLoading() | |
func reloadHeroList() | |
func showEmptyListMessage() | |
func gotoHeroDetails(presenter aPresenter: HeroDetailsPresenter) | |
} |
View HeroDetailsViewController.swift
final class HeroDetailsViewController: RootViewController { | |
override class func instantiateFromStoryboard(presenter aPresenter: Presenter) -> UIViewController { | |
let vc = UIStoryboard(name: "Hero", bundle: nil) | |
.instantiateViewController(withIdentifier: "HeroDetailsViewController") | |
as! HeroDetailsViewController | |
vc.presenter = aPresenter as? HeroDetailsPresenter | |
return vc | |
} | |
} |
View RootViewController.swift
class RootViewController: UIViewController, StoryboardInitializable { | |
class func instantiateFromStoryboard(presenter aPresenter: Presenter) -> UIViewController { | |
fatalError("Override failed. Dependency injection not processed. Presenter injection hampered.") | |
} | |
// Preventing segue to support dependency injection | |
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { | |
fatalError("Segues should not be used. Presenter injection hampered.") | |
} |
View StoryboardInitializable.swift
class Presenter {} | |
protocol StoryboardInitializable { | |
static func instantiateFromStoryboard(presenter aPresenter: Presenter) -> UIViewController | |
} |
View RetainCycle3.swift
class Person { | |
... | |
} | |
class Apartment { | |
... | |
weak var person: Person? | |
... | |
} |
View RetainCycle2.swift
class Person { | |
let name: String | |
init(name: String) { | |
self.name = name | |
} | |
deinit { | |
print("\(name) is being deinitialized") | |
} | |
} |
View RetainCycle8.swift
class HTMLElement { | |
... | |
lazy var asHTML: () -> String = { [weak self] in | |
guard let htmlElement = self else { return "" } | |
return "<\(htmlElement.name)>\(htmlElement.text)</\(htmlElement.name)>" | |
} | |
... | |
} |
View RetainCycle7.swift
class HTMLElement { | |
let name: String | |
let text: String? | |
lazy var asHTML: () -> String = { | |
return "<\(self.name)>\(self.text)</\(self.name)>" | |
} | |
init(name: String, text: String? = nil) { |
NewerOlder