Code Monkey home page Code Monkey logo

bloodymary's Introduction

BloodyMary logo

Twitter

BloodyMary

BloodyMary is a stripped down version of Tempura. It is a one-directional MVVM inspired framework that helps you write clean code and seperate the responsabilities properly.

BloodyMary has its own custom navigation system layer that works on top on Apple's native navigation system so none of the Apple magic is lost. BloodyMary's navigation system can work next to Apple's way with no problem what so ever.

BloodyMary's navigation system aims to help you write the least code needed to get the most out of your app. You provide the SDK with the routes identifiers and their respective view controllers, and BloodyMary does the rest. From instantiating the correct VC to properly pushing it or presenting it etc.. The show and hide functions are done on a single queue in a synchronous way.

The 1.3.x is the version containing the navigation system, currently being used on different WiseEmotions libraries and Telepass iOS app.

RoadMap

  • Custom Navigation System
  • Integrate Combine

1. Requirements and Compatibility

Swift BloodyMary iOS
5.1+ 1.0.x 10+
5.1+ 1.1.x 10+
5.1+ 1.2.x 10+
5.1+ 1.3.x 10+

2. Installation

Cocoapods

Add the following line to your Podfile pod 'BloodyMary' ~> '1.3.1'

3. Documentation

BloodyMary is fully documented. Checkout the documentation here.

4. Code Example

The one directional MVVM

struct RemindersListViewModel: BMViewModel {
  var reminders: [Models.Reminders]
  
  func shouReloadData(oldModel model: RemindersListViewModel) -> Bool {
    model.reminders.count != self.reminders.count
  }
}

class RemindersListView: BMViewWithViewControllerAndViewModel {
  [...]
  
  func update(oldModel: RemindersListViewModel?) {
    guard let model = self.viewModel else { return }
    if model.shouReloadData(oldModel: oldModel) {
      self.tableView.reloadData()
    }
  }
  
  [...]
}

class RemindersListViewController: BMViewController {
  func setupInteractions() {
    self.rootView.didTapDeleteButton = { [weak self] index in
      guard let self = self, let model = self.viewModel else { return }
      let newReminders = model.reminders.remove(at: index)
      let newViewModel = RemindersListViewModel(reminders: newReminders)
      self.update(to: newViewModel)
    }
  }
}

The Navigation System

Providing the configuration for the router

import BloodyMary

struct DependenciesContainer: RoutingConfigurationProvider {
  // prevent it from being instantiated.
  private init() {}
  
  static var shared = DependenciesContainer()
  
  var screensAndDestinations: [ScreenIdentifier : RoutableViewController.Type] {
    [
      "green": GreenViewController.self,
      "red": RedViewController.self
    ]
  }
  
  lazy var router: Router = Router(with: self)
}

Installing the root

import UIKit
import BloodyMary

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  
  var window: UIWindow?
  
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    self.window = self.window ?? UIWindow(frame: UIScreen.main.bounds)
    
    guard let window = self.window else {
      return false
    }
    
    let redVC = RedViewController()
    let redVM = RedViewModel()
    redVC.viewModel = whiteVM

    DependenciesContainer.shared.router.installRoot(using: greenViewController, in: window)

    return true
  }
}

Navigating from a view to another

class RedViewController: BMViewController<RedView>, Routable {
  
  func assign(model: Any) -> Bool {
    guard let model = model as? RedViewModel else {
      return false
    }
    self.viewModel = model
    return true
  }
  
  static var screenIdentifier: ScreenIdentifier {
    "red"
  }
  
  override func setupInteractions() {
    super.setupInteractions()
    
    self.rootView.didTapButton = { _ in
      let greenRoutableObject = RoutableObject(
        screenIdentifier: GreenViewController.screenIdentifier,
        viewModel: GreenViewModel(),
        navigationStyle: .modal(),
        animated: false
      )
      
      DependenciesContainer.shared.router.show(
        routableElements: greenRoutableObject, completion: nil)
    }
  }
}

5. Contribution

Working on your first Pull Request? You can learn how from this free series How to Contribute to an Open Source Project on GitHub

Generate the project

To generate this project locally, you need xcodegen. It is a great tool to customize a project and generate it on the go.

You can either install it manually following their steps, or just run my setup.sh script. It automatically installs Homebrew if it is missing, installs xcodegen, removes existing (if present) .xcodeproj, run xcodegen and moves configuratiom files to their appropriate place.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.