Swiftpack.co - hollyoops/RecoilSwift as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by hollyoops.
hollyoops/RecoilSwift 0.2.0
A New, Modern Reactive State Management Library for Swift and SwiftUI (The iOS implementation of Recoil)
⭐️ 39
🕓 1 week ago
iOS macOS
.package(url: "https://github.com/hollyoops/RecoilSwift.git", from: "0.2.0")

RecoilSwift

RecoilSwift is a lightweight & reactive swift state management library. RecoilSwift is a SwiftUI implementation of recoil.js which powered by Facebook.

Recoil is an alternate option to replace of the Redux(reswift) or MVVM.

Version License Platform

What is recoil

Watch the video

State Management Data Flow

       ← ← ← ← ← ← ← ← ← ← ← atoms ← ← ← ← ← ← ← ← ← ← ← ← ← ←
       ↓                                                     ↑ 
       ↓                                                     ↑
selectors/callback                              mutable selectors/callback    
       ↓                                                     ↑ 
       ↓                                                     ↑
       → → → → → → → → src="https://raw.github.com/hollyoops/RecoilSwift/master/ view(hooks) → → → → → → → → → → →

<img style="max-width:100%;" src="image.png" width="700" height="378"/>

Requirements

  • iOS 13+
  • Xcode 12.4+

NOTE: Currently this library only support for SwiftUI, UIKit is not available. But it planned.

In recent release, we re-implement this library with react hooks pattern which making the usage of this lib is more similar with official way.

Installation

  1. In Xcode, open your project and navigate to FileSwift PackagesAdd Package Dependency...
  2. Paste the repository URL (https://github.com/hollyoops/RecoilSwift.git) and click Next.
  3. For Rules, select Branch (with branch set to master).
  4. Click Finish.

RecoilSwift is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'RecoilSwift'

Basic Usage

Create Atom / Selector:

// Create a Atom
let allBooksState = atom { [Book](https://raw.github.com/hollyoops/RecoilSwift/master/) }

// Create readonly Selector
let currentBooksSelector = selector { get -> [Book] in
    let books = get(allBooksState)
    if let category = get(selectedCategoryState) {
        return books.filter { $0.category == category }
    }
    return books
}

// Create parameterized selector 
let someSelector = selectorFamily { (id: String, get: Getter) -> AnyPublisher<[String], Error> in
    // Do some logic in here with id
}

Use Atom / Selector in SwiftUI

Because the useRecoilXXX series API is based on Hooks. so it should follow all the rule of hooks

struct YourView: RecoilView { // You have to implement the RecoilView protocol
    var hookBody: some View { 
     let currentBooks = useRecoilValue(currentBooksSelector)

     let allBooks = useRecoilState(allBooksStore)

     let loadable = useRecoilValueLoadable(fetchRemoteDataByID(someID))
      // Your UI Code
    }
}

Advance Usage

Async task

let fetchRemoteDataById = selectorFamily { (id: String, get: ReadonlyContext) -> AnyPublisher<[String], Error> in
      Deferred {
        Future { promise in
              // Do some logic in here with id
        }
    }.eraseToAnyPublisher()
}

// In some function
func someView() -> some View {
    HookScope { // when your view is not implement with RecoilView, you have to use `HookScope`
        let id = useRecoilValue(selectedCategoryState)
        let loadable = useRecoilValueLoadable(fetchRemoteDataById(id))
        
        // This body will be render after task completed
        return VStack {
            // while loading
            if loadable.isLoading {
                ProgressView()
            }

            // when error
            if let err = loadable.error {
                errorView(err)
            }

            // when data fulfill
            if let names = loadable.data {
                dataView(allBook: names, onRetry: loadable.load)
            }
        }
    }
}

Documentation

API Reference

TODOs

  • ☐ [performance]avoid duplicated compute when rerender hook
  • ☐ [Bug]Use callback not work when you click refetch button while updating view
  • ☐ [feature]Make UIKit compatible

Reference:

GitHub

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

Dependencies

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