Giter Club home page Giter Club logo

reswift-thunk's Introduction

ReSwift-Thunk

Build Status Code coverage status CocoaPods Compatible Platform support License MIT Reviewed by Hound

Supported Swift Versions: Swift 4.2, Swift 5.0, Swift 5.3

When ReSwift is a Redux-like implementation of the unidirectional data flow architecture in Swift, ReSwift-Thunk is like redux-thunk.

Why Use ReSwift-Thunk?

Example

// First, you create the middleware, which needs to know the type of your `State`.
let thunkMiddleware: Middleware<MyState> = createThunkMiddleware()

// Note that it can perfectly live with other middleware in the chain.
let store = Store<MyState>(reducer: reducer, state: nil, middleware: [thunkMiddleware])

// A thunk represents an action that can perform side effects, access the current state of the store, and dispatch new actions, as if it were a ReSwift middleware.
let thunk = Thunk<MyState> { dispatch, getState in 
    if getState!.loading {
        return
    }
    dispatch(RequestStart())
    api.getSomething() { something in
        if something != nil {
            dispatch(RequestSuccess(something))
        } else {
            dispatch(RequestError())
        }
    }
}

// A thunk can also be a function if you want to pass on parameters
func thunkWithParams(_ identifier: Int) -> Thunk<MyState> {
    return Thunk<MyState> { dispatch, getState in
        guard let state = getState() else { return }
        
        if state.loading {
            return
        }
        
        api.getSomethingWithId(identifier) { something in
            if something != nil {
                dispatch(RequestSuccess(something))
            } else {
                dispatch(RequestError())
            }
        }
    }
}

// As the thunk type conforms to the `Action` protocol, you can dispatch it as usual, without having to implement an overload of the `dispatch` function inside the ReSwift library.
store.dispatch(thunk)

// You can do the same with the Thunk that requires parameters, like so
store.dispatch(thunkWithParams(10))

// Note that these actions won't reach the reducers, instead, the thunks middleware will catch it and execute its body, producing the desired side effects.

Testing

The ExpectThunk helper, available as a CocoaPods subspec, allows for testing the order and actions of dispatch as well as the dependencies on getState.

ExpectThunk(thunk)
    .getsState(RequestState(loading: false))
    // If the action is Equatable it will be asserted for equality with `dispatches`.
    .dispatches(RequestStart())
    .dispatches { action in
        XCTAssert(action.something == expectedSomething)
    }
    .wait() // or simply run() for synchronous flows

Installation

ReSwift-Thunk requires the ReSwift base module.

CocoaPods

You can install ReSwift-Thunk via CocoaPods by adding it to your Podfile:

target 'TARGET' do
    pod 'ReSwiftThunk'
end

target 'TARGET-TESTS' do
    pod 'ReSwiftThunk/ExpectThunk'
end

And run pod install.

A Note on Including ExpectThunk

If the ExpectThunk subspec is used, the tests target cannot be nested in another target due to current limitations. The tests target must be a standalone target as shown in the snippet above.

Carthage

You can install ReSwift-Thunk via Carthage by adding the following line to your Cartfile:

github "ReSwift/ReSwift-Thunk"

Swift Package Manager

You can install ReSwift-Thunk via Swift Package Manager by adding the following line to your Package.swift:

import PackageDescription

let package = Package(
    [...]
    dependencies: [
        .Package(url: "https://github.com/ReSwift/ReSwift-Thunk.git", majorVersion: XYZ)
    ]
)

Import testing support by importing ReSwiftThunkTesting

import ReSwiftThunkTesting

Checking out Source Code

After checking out the project run pod install to get the latest supported version of SwiftLint, which we use to ensure a consistent style in the codebase.

Example Projects

  • ReduxMovieDB: A simple App that queries the tmdb.org API to display the latest movies. Allows searching and viewing details. Relevant file.

Contributing

You can find all the details on how to get started in the Contributing Guide.

Credits

License

ReSwift-Thunk Copyright (c) 2018 ReSwift Contributors. Distributed under the MIT License (MIT). See LICENSE.md.

reswift-thunk's People

Contributors

bergquester avatar cardoso avatar dani-mp avatar divinedominion avatar fbernutz avatar gert-janvercauteren avatar jayhickey avatar mjarvis avatar obj-p avatar okaverin avatar shawnkoh avatar xavierlowmiller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reswift-thunk's Issues

carthage build fails for non-iOS platforms

Running initial carthage bootstrap or later carthage build --platform mac, the error I get is this:

Failed to write to /Users/ctm/Downloads/test/Carthage/Build/Mac/ReSwift_Thunk.framework: Error Domain=NSCocoaErrorDomain Code=260 "The file “ReSwift_Thunk.framework” couldn’t be opened because there is no such file." UserInfo={NSURL=file:///Users/ctm/Library/Caches/org.carthage.CarthageKit/DerivedData/10.1_10B61/ReSwift-Thunk/9ff0068fc855efd3a1a8944056d8b0da41123a23/Build/Intermediates.noindex/ArchiveIntermediates/ReSwift-Thunk/BuildProductsPath/Release-iphoneos/ReSwift_Thunk.framework, NSFilePath=/Users/ctm/Library/Caches/org.carthage.CarthageKit/DerivedData/10.1_10B61/ReSwift-Thunk/9ff0068fc855efd3a1a8944056d8b0da41123a23/Build/Intermediates.noindex/ArchiveIntermediates/ReSwift-Thunk/BuildProductsPath/Release-iphoneos/ReSwift_Thunk.framework, NSUnderlyingError=0x7ffc38749d50 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

Note that the source path is Build/Intermediates.noindex/ArchiveIntermediates/ReSwift-Thunk/BuildProductsPath/Release-iphoneos/ReSwift_Thunk.framework, with emphasis on Release-iphoneos. A build product does exist in Release/ReSwift_Thunk.framework, so we have to get rid of the suffix somehow 🤔

Am investigating 💪

how can i redo or undo a async action

Hello, I tried ReSwift-Thunk to do async action, and my reducer is undoable. How to use both libraries at the same time

Below is my code

let mainStore = Store(
reducer: undoable(reducer: mainReduer, filter: nil),
state: nil,
middleware: [createThunkMiddleware()]
)

createThunksMiddleware is typo?

The equivalent of createThunksMiddleware in redux-thunk is createThunkMiddleware. It does not contain 's'. Is this difference intended or typo?

Export ExpectThunk e.g. to Carthage

I noticed that ExpectThunk is only available as a Pod subspec.

Since I don't use CocoaPods, I'm stuck with copying the file. I wonder if it makes sense to add another framework target, e.g. ReSwiftThunkTesting, that exports this type. The RxSwift package is split into RxTesting and all the RxSwift parts as well, and sharing the scheme produces another framework that you can use during tests.

Can't pass Xcode 12.5.1 build

@DivineDominion @mjarvis

Hi 😄

I'm using Xcode 12.5.1 to build carthage, but it doesn't look like it's working.
On the failure log it says something like this:

image

MyProject/Carthage/Checkouts/ReSwift-Thunk/ReSwift-Thunk/createThunkMiddleware.swift:10:8: 
error: module compiled with Swift 5.3.1 cannot be imported by the Swift 5.4.2 compiler: 

/Users/username/my-project/Carthage/Checkouts/
ReSwift-Thunk/Carthage/Build/iOS/ReSwift.framework/
Modules/ReSwift.swiftmodule/arm64-apple-ios.swiftmodule

I'm pretty sure that I used the correct xcode-version to build this.

Can you guys please help with this issue.

Can createThunkMiddleware be customized?

I want to custom the createThunkMiddleware function. Is this possible?

I tried to call thunk.body(dispatch, getState), but the body variable was protected.
ERROR: ('body' is inaccessible due to 'internal' protection level)

Can you give me a hand?

public func createThunkMiddleware<State>() -> Middleware<State> {
    return { dispatch, getState in
        return { next in
            return { action in
                switch action {
                case let thunk as Thunk<State>:
                    thunk.body(dispatch, getState)
                default:
                    next(action)
                }
            }
        }
    }
}


Cannot import ReSwiftThunkTesting via SPM

I'm using ReSwiftThunk via SPM. In my test file, I try to import the testing helper like this:

import ReSwiftThunk
import ReSwiftThunkTesting

but when I do, Xcode shows the error No such module 'ReSwiftThunkTesting'.

This is an Xcode Project...not a pure Swift module, so not sure if that has anything to do with it.

I got conflict between ReSwiftThunk-Core-ExpectThunk and ReSwiftThunk when make archive

This is I can see in log
Showing Recent Messages
Multiple commands produce '/Users/.../UninstalledProducts/iphoneos/ReSwiftThunk.framework':

  1. Target 'ReSwiftThunk-Core-ExpectThunk' has create directory command with output '/Users/.../iphoneos/ReSwiftThunk.framework'
  2. Target 'ReSwiftThunk' has create directory command with output '/Users/.../iphoneos/ReSwiftThunk.framework'

pod file

pod 'ReSwift'
pod 'ReSwiftThunk'
pod 'ReSwiftRouter'

before this I can see this issue ( the same I can see when launch on iPhone, but I get no fail)

Showing Recent Messages
Multiple targets match implicit dependency for linker flags '-framework ReSwiftThunk'. Consider adding an explicit dependency on the intended target to resolve this ambiguity. (in target 'TrackdMusic' from project 'TrackdMusic')

Xcode 11.3.1 CocoaPods
COCOAPODS: 1.8.4

at Cocoapods target I can see two target whichProduces framework with the same name, https://prnt.sc/qwhbb3 , of course it not ok for CI. So any Ideas how resolve it?

P.S If I remove pod 'ReSwiftThunk' I still can see target ReSwiftThunk but I have failure ( no such module ReSwiftThunk)

Release

I'm sorry if anyone takes offense of blunt statements, because I am grateful for this project, and ReSwift. This project is one of the smallest codebases in the entirety of my project, or any project I've worked on in recent memory. Seriously, what's the hold up of an actual 1.0.0 release?

ReSwift-Thunk on SPM has different module name

Good morning,
I am migrating all my dependencies from cocoapods to SPM and I noticed the package for this library changes the import to include and _ so instead of import ReSwiftThunk we have to now import import ReSwift_Thunk. Was this change done on purpose?

If this change was on purpose we should consider renaming the module on Cocoapods etc to remain consistent across the board.

Happy to make a PR for this if I can help out in any way :)

Chaining thunks

Hi,

I was wondering whether there is a recommended way how to chain thunks? The original redux-thunk works with promises while our Thunk is just a Void closure which makes chaining a bit complicated.

Thanks in advance.

Unable to install ExpectThunk using Cocoapods

Hey all, I seem to be stuck. First I tried using this Podfile to install ExpectThunk:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'MyApp' do
  use_frameworks!

  pod 'ReSwift'
  pod 'ReSwiftThunk'

  pod 'PromiseKit', '~> 6.8'

  target 'MyAppTests' do
    inherit! :search_paths

    pod 'Quick'
    pod 'Nimble'
    pod 'ReSwiftThunk/ExpectThunk'
  end

end

That produced this error:

[!] CocoaPods could not find compatible versions for pod "ReSwiftThunk/ExpectThunk":
In Podfile:
ReSwiftThunk/ExpectThunk

None of your spec sources contain a spec satisfying the dependency: ReSwiftThunk/ExpectThunk.

I noticed the note in the Readme on issues with nested targets, so I updated my Podfile to this:

def common_pods
  pod 'ReSwift'
  pod 'PromiseKit', '~> 6.8'
end

target 'MyApp' do
  use_frameworks!

  common_pods

  pod 'ReSwiftThunk'
end

target 'MyAppTests' do
  common_pods

  pod 'Quick'
  pod 'Nimble'

  pod 'ReSwiftThunk/ExpectThunk'
end

That is producing the same error, which doesn't actually seem to be related to the nested target issue.

Any suggestions?

ExpectThunk fails for watchOS using CocoaPods (pod lib lint)

See the error by Travis on #33

ExpectThunk is only supposed to be used for test targets. watchOS doesn't have any. So the whole build process fails, e.g. during pod lib lint.

$ pod lib lint

 -> ReSwiftThunk (1.2.0)
    - NOTE  | [ReSwiftThunk/Core,ReSwiftThunk/ExpectThunk] xcodebuild:  note: Using new build system
    - NOTE  | [ReSwiftThunk/Core,ReSwiftThunk/ExpectThunk] xcodebuild:  note: Planning build
    - NOTE  | [ReSwiftThunk/Core,ReSwiftThunk/ExpectThunk] xcodebuild:  note: Constructing build description
    - ERROR | [watchOS] [ReSwiftThunk/ExpectThunk] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
    - ERROR | [watchOS] [ReSwiftThunk/ExpectThunk] xcodebuild:  /Users/ctm/Coding/ReSwift-Thunk/ReSwift-ThunkTests/ExpectThunk.swift:9:8: error: no such module 'XCTest'
    - ERROR | [watchOS] [ReSwiftThunk/ExpectThunk] xcodebuild:  /Users/ctm/Library/Developer/Xcode/DerivedData/App-cpmepnvvxujdnyaypnrkyuqqmcbo/Build/Products/Release-watchsimulator/ReSwiftThunk/ReSwiftThunk.framework/Modules/module.modulemap:9:12: error: header 'ReSwiftThunk-Swift.h' not found
    - ERROR | [watchOS] [ReSwiftThunk/ExpectThunk] xcodebuild:  /var/folders/62/8k21681d08z9lhq8h433z3rh0000gp/T/CocoaPods-Lint-20190906-51488-dhxrll-ReSwiftThunk/App/main.swift:1:8: error: could not build Objective-C module 'ReSwiftThunk'

[!] ReSwiftThunk did not pass validation, due to 4 errors.
You can use the `--no-clean` option to inspect any issue.

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.