LoginSignup
0
0

More than 5 years have passed since last update.

ReSwift Vol2

Last updated at Posted at 2017-03-12

前回(Vol1)はこちら
http://qiita.com/nakadoribooks/items/c5f53071abdfafd47d4f

javascript実装はこちら
http://qiita.com/nakadoribooks/items/f7f48197d6d5723a96d5

成果物
https://github.com/nakadoribooks/CalilClient-ios/releases/tag/vol2

ActionCreator リファクタリング

  • ActionCreator 内でのDispatchしない

ライブラリ取り込み

Podfile
use_frameworks!
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

target 'CalilClient' do
  pod 'ReSwift'
  pod "PromiseKit", "~> 4.0"
  pod 'PromiseKit/Alamofire' 
end

PromiseKitを使います
https://github.com/mxcl/PromiseKit

ActionCreator

ActionCreator.swift
static func loadLibraries(prefName:String="秋田県")-> Promise<Action>{

    return Promise { fulfill, reject in

        let parameters: Parameters = ["appkey": Config.API_KEY, "pref":prefName, "format":"json", "callback":""]
        Alamofire.request(Config.API_LIBRARY, parameters: parameters).responseJSON().then { responseAny -> Void in

            guard let json = responseAny as? [NSDictionary] else{
                // 〜 略 〜
                let failAction = LibraryListFailLoadAction()
                fulfill(failAction)
                return
            }

            print("ok json")
            let results = Library.createList(list: json)
            let loadedAction = LibraryListLoadedAction(libraryList: results)
            fulfill(loadedAction)
        }.catch { error in
            let failAction = LibraryListFailLoadAction()
            fulfill(failAction)
        }
    }
}

static func loadLibrariesAction()->Action{
    return LibraryListLoadAction()
}

変更前

// ActionCreator interface
static func loadLibraries(prefName:String="秋田県")->Action

// 使う側 (View)
let loadAction = ActionCreator.loadLibraries()
mainStore.dispatch(loadAction)

変更後


// ActionCreator interface
static func loadLibraries(prefName:String="秋田県")-> Promise<Action>
static func loadLibrariesAction()->Action

// 使う側 (View)
ActionCreator.loadLibraries().then { (action) -> Void in
    mainStore.dispatch(action)
}
let loadAction = ActionCreator.loadLibrariesAction()
mainStore.dispatch(loadAction)

たぶんこっちの方が好ましい。

※ 追記 AsyncActionCreator 使用バージョン

Webの方
http://qiita.com/nakadoribooks/items/f7f48197d6d5723a96d5
で redux-thunk のオススメコメントいただいたので、こっちもインタフェース揃える。

AsyncActionCreator
Reswiftの中に入ってる。
こいつが dispatch に渡せる

typealias AsyncActionCreator = (
    _ state: State,
    _ store: Store,
    _ actionCreatorCallback: @escaping ((ActionCreator) -> Void)
) -> Void

mainStore.dispatch(AsyncActionCreator)

成果物
https://github.com/nakadoribooks/CalilClient-ios/releases/tag/vol2.5

準備

特になし。

ActionCreator

ActionCreator.swift
import ReSwift
import Alamofire
import PromiseKit

public enum ActionCreatorError: Error {
    case unknown
    case json
}

struct ActionCreator{

    static func loadLibraries(prefName:String="秋田県")->Store<AppState>.AsyncActionCreator {
        return { (state, store, callback) in
            _loadLibraries(prefName: prefName).then(execute: { (action) -> Void in
                callback({ (_, _) -> Action? in action })
            }).catch(execute: { (error) in
                let failAction = LibraryListFailLoadAction()
                callback({ (_, _) -> Action? in failAction })
            })
        }
    }

    static func _loadLibraries(prefName:String="秋田県")-> Promise<Action>{

        return Promise { fulfill, reject in

            let parameters: Parameters = ["appkey": Config.API_KEY, "pref":prefName, "format":"json", "callback":""]

            Alamofire.request(Config.API_LIBRARY, parameters: parameters).responseJSON().then { responseAny -> Void in

                guard let json = responseAny as? [NSDictionary] else{
                    print("fail json")

                    reject(ActionCreatorError.json)
                    return
                }

                print("ok json")
                let results = Library.createList(list: json)
                let loadedAction = LibraryListLoadedAction(libraryList: results)

                // 時間かかっているてい
                DispatchQueue.global(qos: .default).async {
                    Thread.sleep(forTimeInterval: 1)
                    DispatchQueue.main.async {
                        fulfill(loadedAction)
                    }
                }

            }.catch { error in
                reject(ActionCreatorError.unknown)
            }

        }

    }

    static func loadLibrariesAction()->Action{
        return LibraryListLoadAction()
    }

}

変更前


// ActionCreator interface
static func loadLibraries(prefName:String="秋田県")-> Promise<Action>
static func loadLibrariesAction()->Action

// 使う側 (View)
ActionCreator.loadLibraries().then { (action) -> Void in
    mainStore.dispatch(action)
}
let loadAction = ActionCreator.loadLibrariesAction()
mainStore.dispatch(loadAction)

変更後

// ActionCreator interface
static func loadLibraries(prefName:String="秋田県")->Store<AppState>.AsyncActionCreator
static func loadLibrariesAction()->Action

// 使う側 (View)
mainStore.dispatch(ActionCreator.loadLibraries())
mainStore.dispatch(ActionCreator.loadLibrariesAction())

なるほど。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0