Swiftpack.co - KazaiMazai/PureduxUIKit as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by KazaiMazai.
KazaiMazai/PureduxUIKit 1.0.2
UIKit bindings to connect UI to PureduxStore
⭐️ 9
🕓 2 weeks ago
iOS
.package(url: "https://github.com/KazaiMazai/PureduxUIKit.git", from: "1.0.2")

Sublime's custom image

UIKit bindings to connect UI to PureduxSrore

Continuous Integration

Features

  • Clear path to data-driven UIViewControllers
  • Presentation data model aka. 'Props' can be prepared on Main or Background queue
  • State updates deduplication to avoid unnecessary UI refresh

Installation

Swift Package Manager.

PureduxStore is available through Swift Package Manager. To install it, in Xcode 11.0 or later select File > Swift Packages > Add Package Dependency... and add Puredux repositoies URLs for the modules requried:

https://github.com/KazaiMazai/PureduxUIKit

Quick Start Guide

  1. Import:
import PureduxUIKit

  1. Implement view controller and conform it to Presentable

final class FancyViewController: UIViewController, Presentable {
    var presenter: PresenterProtocol? { get set }

    func setProps(_ props: Props) {
        //update views here
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        presenter?.subscribeToStore()
    }
}

extension FancyViewController {
    struct Props {
        //some data that is prepared for showing here
    }
}

  1. Prepare Props with current state and store. For e.g. as a part of some fancy presenter:

struct FancyVCPresenter {
    func makeProps(
        state: FancyFeatureState, 
        store: Store<FancyFeatureState, Action>) -> FancyViewController.Props {
        
        //prepare props for your fancy view controller
    }
}

  1. Connect your fancy view controller to store, providing how it should be connected:
let appState = AppState()
let rootStore = RootStore<AppState, Action>(initialState: appState, reducer: reducer)

let fancyFeatureStore = rootStore.store().proxy { $0.yourFancyFeatureSubstate }
 
let presenter = FancyVCPresenter()
let viewController = FancyViewController()

viewController.with(store: fancyFeatureStore,
                    props: presenter.makeProps)
 
  1. Present it immediately!

Q&A

Click for details

What is PureduxStore?

  • It's minilistic UDF architecture store implementation. More details can be found here

Which DispatchQueue is used to prepare props?

  • By default, it works on a shared PresentationQueue. It is a global serial queue with user interactive quality of service. The purpose is to do as little as possible on the main thread queue.

Is it safe at all?

  • PureduxUIKit hops to the main dispatch queue to update UIViewController. So yes, it's safe. Unless you try to do UIKit related things (you should not) during your Props preparation.

How to change presentation queue that is used to prepare props?

  • PureduxUIKit allows to use main queue or user-provided custom queue. The only requirement for the custom queue is to be serial one.
viewController.with(store: fancyFeatureStore,
                    props: presenter.makeProps,
                    presentationQueue: .main)
                    

or standalone queue:


let queue = DispatchQueue(label: "some.queue", qos: .userInteractive)

viewController.with(store: fancyFeatureStore,
                    props: presenter.makeProps,
                    presentationQueue: .serialQueue(queue))
        

How to deduplicate state changes?

  • State deduplication is done by providing a way to compare two states on equality.
  • It's done with the help of Equating<State> guy:

viewController.with(store: fancyFeatureStore,
                    props: presenter.makeProps,
                    removeStateDuplicates: .equal {
                        $0.title
                    })
                    

Why we need Equating<State> guy?

  • Depending on context (or particular screen), we might be interested in different part of the state. Different properties of the same type.
  • And would like to deduplicate updates depending on it.
  • That's why single Equatable implementation won't work here.

firstViewController.with(store: fancyFeatureStore,
                        props: firstVCpresenter.makeProps,
                        removeStateDuplicates: .equal {
                            $0.title
                        })
                    
secondViewController.with(store: fancyFeatureStore,
                    props: secondVCpresenter.makeProps,
                    removeStateDuplicates: .equal {
                        $0.subtitle
                    })
                    

Any other Equating<State> details ?

  • Equating is a protocol witness for Equtable. It answers the question: "Are these states equal?"
  • With the help of it, deduplication happens.

Here is the definition:

  
    Equating<T> { (lhs: T, rhs: T) -> Bool
        //compare here
    }

It has handy extensions, like Equating.alwaysEqual or Equating.neverEqual as well as && operator:


viewController.with(store: fancyFeatureStore,
                        props: vcPresenter.makeProps,
                        removeStateDuplicates: 
                            .equal { $0.title } &&
                            .equal { $0.subtitle }
                        )
            

Licensing

PureduxUIKit is licensed under MIT license.

GitHub

link
Stars: 9
Last commit: 2 weeks ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Release Notes

Release v1.0.2
2 weeks ago

All is done and tests work on Github Actions

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics