Protocols

The following protocols are available globally.

  • A protocol that views should conform to.

    Its main goal is to help structure the code in a more clean, organized way.

    Example

    /// An image based checkbox.
    open class SKCheckbox: UIControl, BMView {
    
      // MARK: - Properties
    
      /// The currently displayed checkbox Image.
      private var checkboxImage = UIImageView()
    
      /// Overriding the original method to update the icon based on state.
      open override var isEnabled: Bool {
        didSet { self.update() }
      }
    
      // MARK: - Interactions
    
      public var valueDidChange: ((_ checkbox: SKCheckbox, _ oldValue: Bool) -> Void)?
    
      // MARK: - init
    
      /// `init` via code.
      public override init(frame: CGRect) {
        super.init(frame: frame)
        self.configure()
        self.update()
        self.layout()
      }
    
      /// `init` via IB.
      public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.configure()
        self.update()
        self.layout()
      }
    
      // MARK: - CSUL
    
      public func configure() {
        self.addSubview(self.checkboxImage)
      }
    
      public func style() {
        // style the default looks of the view and its subviews.
      }
    
      public func update() {
        // update UI when isEnabled changes status, among other things.
      }
    
      public func layout() {
        // layout the `checkboxImage` and other potential subviews.
      }
    }
    

    The view exposes properties and interactions to the outside world. The properties deal with the state of the element, whereas the interactions are callbacks to interact with changes inside the element. The lifecycle of the view is composed of configure, style, update andlayout`.

    Configure

    Executed once when the view is instatiated. It deals with configuring the view. For instance, a typical usecase would be to add subviews, or setup interactions.

    func configure() {
      self.addSubiew(sel.checkboxImage)
    }
    

    Style

    Executed once when the view is instatiated. It deals with applaying the basic static styling to the view. In other words element properties that are independent of the state of the element are applied here. If the background of the element always has the same color, the background color is set here.

    func style() {
      self.backgroundColor = .white
    }
    

    Update

    Update is not directly called when the object is instantiated but rather when a state related value changes its state. Inside of the update, changes should be made to the UI to reflect the new state.

      open override var isEnabled: Bool {
        didSet { self.update() }
      }
    

    Layout

    Excecuted once when the view is instatiated. It layouts the subviews as intended.

    func layout() {
     self.checkboxImage.frame = self.bounds
    
    See more

    Declaration

    Swift

    public protocol BMView : AnyObject
  • An object, preferably a struct, containing a set of properties to be passed to a BMViewWithViewModel. These properties should help the view render itself to reflect proper states.

    struct ProfileViewModel: BMViewModel {
      let name: String
      let age: Int = 27
    }
    

    Declaration

    Swift

    public protocol BMViewModel
  • A BMViewWithViewControllerAndViewModel is a BMViewWithViewModel view managed by a UIViewController. This “managing” automatically calls the configure, style and layout phases. In addition, the controller set the viewModel of the view, therefore invoking the update at least once before the view is actually displayed. This view is extended with helpers allowing to access the UINavigationBar, UINavigationItem, UIViewController from the view when present.

    See more

    Declaration

    Swift

    public protocol BMViewWithViewControllerAndViewModel : BMViewWithViewModel
  • A BMViewWithViewModel takes the BMView and UIView a step further by introducing a view model. The view model is an object containing a set of properties reflecting the state of the view. A view model makes it easier to mock a view by passing the state from the outside and therefore test it in any desired state.

    Example

    struct ProfileViewModel: BMViewModel {
      let name: String
      let age: Int
    
      var isAdult: Bool {
        age > 18
      }
    
      var badgeColor: UIColor {
        isAdult ? .green : .red
      }
    }
    
    class ProfileView: BMViewWithViewModel {
      let badge = UIView()
      let nameLabel = UILabel()
    
      func configure() {
        self.addSubview(self.badge)
        self.addSubview(self.nameLabel)
      }
    
      func style() {
        // style the elements
      }
    
      func update(oldViewModel: ProfileViewModel?) {
        self.badge.backgroundColor = self.viewModel?.badgeColor
        self.nameLabel.text = self.viewModel?.name
      }
    
      func layout() {
        // layout the subviews
      }
    }
    

    By conformimng to BMViewWithViewModel in this previous example, we notice we do not explicetely need to specify the viewModel since it is infered by swift through the update(oldViewModel: VM?) method.

    By altering the view model, different states of the view can be tested in a fast efficient way.

    See more

    Declaration

    Swift

    public protocol BMViewWithViewModel : BMView
  • A protocol requiring its conformer to declare its UIViewController Hierarchy. Any custom UIViewController other than UINavigationController, UITabBarController containing a custom navigation should conform to this protocol.

    See more

    Declaration

    Swift

    public protocol InspectableHierarchy : AnyObject
  • A protocol that only UIViewController should conform to to returnm the presentedViewController if present.

    See more

    Declaration

    Swift

    public protocol InspectablePresentedViewController : AnyObject
  • A protocol that all navigable ViewControllers should adhere to. The UINavigationController and the UITabBarController should NOT adhere to this protocol.

    See more

    Declaration

    Swift

    public protocol Routable : AnyObject
  • TypeErasure for RoutableObject<VM: BMViewModel>

    See more

    Declaration

    Swift

    public protocol AnyRoutableObject
  • A configuration provider for the Router that the dependencies manager in the app should conform to. It requires the conformer to provide the screens and their respective view controller.

    See more

    Declaration

    Swift

    public protocol RoutingConfigurationProvider