A brief introduction of iOS Coordinator pattern
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let object = fetchedResultsController.object(at: indexPath)
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
class OrderSummaryViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "checkout" {
let vc = segue.destination as! DeliveryAddressViewController
vc.cart = cart // pass along cart information to next view controller
}
}
}
class OrderSummaryViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "checkout" {
let vc = segue.destination as! ShippingOptionViewController
vc.cart = cart // pass along cart information to next view controller
}
}
}
class Cart {
var items: [Product]
var paymentMethod: PaymentMethod
// Old implementation
var deliveryAddress: String
var shippingOption: ShippingOption
}
// 1
protocol ProductListViewControllerDelegate: class {
func productListViewController(_ vc: ProductListViewController, didSelectProduct product: Product)
}
class ProductListViewController: UIViewController {
weak var delegate: ProductListViewControllerDelegate?
}
protocol ProductDetailViewControllerDelegate: class {
func productDetailViewController(_ vc: ProductDetailViewController, didAddProduct product: Product)
}
class ProductDetailViewController: UIViewController {
weak var delegate: ProductDetailViewControllerDelegate?
}
protocol OrderSummaryViewControllerDelegate: class {
func orderSummaryViewControllerDidCheckout(_ vc: OrderSummaryViewController)
}
class OrderSummaryViewController: UIViewController {
var items: [Cart.Item]!
weak var delegate: OrderSummaryViewControllerDelegate?
}
// 2
struct Product {
let id: String
let name: String
let price: Decimal
}
class Cart {
struct Item {
let product: Product
var quantity: Int
}
var items = [Item]()
func addProduct(_ product: Product) {}
func removeProduct(_ product: Product) {}
}
// 3
class PurchaseCoordinator: ProductListViewControllerDelegate, ProductDetailViewControllerDelegate, OrderSummaryViewControllerDelegate {
var cart = Cart()
var paymentMethod: PaymentMethod?
// Removed this in new implementation
var deliveryAddress: String?
var shippingOption: ShippingOption?
var rootViewController: UINavigationController
init() {
let vc = ProductListViewController()
rootViewController = UINavigationController(rootViewController: vc)
vc.delegate = self
}
// MARK: - Product list
// MARK: - Go to product detail
func productListViewController(_ vc: ProductListViewController, didSelectProduct product: Product) {
let vc = ProductDetailViewController()
vc.delegate = self
vc.navigationItem.rightBarButtonItem = checkoutButton
rootViewController.pushViewController(vc, animated: true)
}
private var checkoutButton: UIBarButtonItem {
return UIBarButtonItem(title: "Cart (\(cart.items.count))", style: .plain, target: self, action: #selector(didTapCheckout(_:)))
}
// MARK: - Go to order summary
@objc func didTapCheckout(_ sender: UIBarButtonItem) {
let vc = OrderSummaryViewController()
vc.items = cart.items
vc.delegate = self
vc.navigationItem.leftBarButtonItem = closeButton
rootViewController.present(UINavigationController(rootViewController: vc), animated: true, completion: nil)
}
// MARK: - Product detail
// MARK: - Add product
func productDetailViewController(_ vc: ProductDetailViewController, didAddProduct product: Product) {
cart.addProduct(product)
}
// MARK: - Order Summary
func orderSummaryViewControllerDidCheckout(_ vc: OrderSummaryViewController) {
// Go to delivery or shipping options
}
// MARK: - Helpers
private var closeButton: UIBarButtonItem {
return UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(didTapClose(_:)))
}
@objc func didTapClose(_ sender: UIBarButtonItem) {
rootViewController.dismiss(animated: true, completion: nil)
}
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
private var purchaseCoordinator: PurchaseCoordinator
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let window = UIWindow(frame: UIScreen.main.bounds)
let purchaseCoordinator = PurchaseCoordinator()
self.window = window
self.purchaseCoordinator = purchaseCoordinator
window.rootViewController = purchaseCoordinator.rootViewController
window.makeKeyAndVisible()
return true
}
}
Ready to start your project? Contact Us
From us to your inbox weekly.