LoginSignup
26
18

More than 5 years have passed since last update.

PromiseKit 6 にアップデートしたらいろいろ変わってたメモ

Last updated at Posted at 2018-05-28

PromiseKit6が出てた

https://github.com/mxcl/PromiseKit
https://promisekit.org/news/2018/02/PromiseKit-6.0-Released/

まだ絶賛PromiseKit4使用中だったので、バージョンを上げましょうという話になった。
ご丁寧に上記URLでPromiseKit4からの変更について書かれている。

本記事では、バージョンアップのmigrationの際に主に変更があった部分のメモだけ載せるので、詳しくは上記を参照してください。

何か間違いあればご指摘お願いします :bow:

initializerが変わったので対応する

今まで

Promise { fulfill, reject in
    if ... {
        fulfill(data)
    } else {
        reject(error)
    }
}

新しいやつ

Promise { resolver in
    if ... {
        resolver.fulfill(data)
    } else {
        resolver.reject(error)
    }
    // resolver.resolve(data, error) でもOK
}

resolver (公式ではseal) が引数として渡されるようになったのね。中身はそんなに変わってないけど、 resolver.resolve で一気に渡せるようにもなってる。

thenが3つに別れたので対応する

今までthenで一括りにされていたのが、次の3つに分解された。
元のthenは次の3つがあった。

then(execute: Results<U>) -> Promise<U>
then(execute: Results<U>) -> AnyPromise
then(execute: Results<U>) -> U

AnyPromiseは置いておくとして、thenひとつでPromiseを返すものとその値を返すものがあった。
また、多くの場合で何も値を返したくないこともあり、明示的に Promise<U> -> Void と書いてやることでコンパイルエラーを回避する、ということをやっていたりした。(私だけだったら悲しい)
これらをわかりやすくするために次の3つができたっぽい。

  • then
  • done
  • map

then (新しい方)

Promiseを受け取ってPromiseを返すときに使う。今までどおり。

somePromise.then { obj -> Promise<U> in
    doSomething(obj)
    return getSomePromise()
}.then ...

done

Promiseを受け取って何も返却値がないときに使う。だいたいこれを使うことが多い。

promise.done { obj in
    some(obj)
}

map

Promiseを受け取って中のvalueなどPromiseでない値を返すときに使う。

promise.map { obj -> U in
    value = some(obj) // valueは非Promise
    return value
}

その他の便利なやつ

他にも、上記の3つ+αなもののエイリアス的なメソッドが増えていた。

compactMap

mapのoptional unwrap付きバージョン。nilだとcatchに入る。

somePromise.compactMap { data in
    UIImage(data: data)
}.done { image in
    imageView.image = image
}.catch {
    ...
}

get

doneと同じで明示的にreturnしないが、与えられたものと同じ値を返す。

somePromise.get { data in
    setup1(data)
}.done { data in
    setup2(data)   
}

tap

値を Result<T> でラップした値を受け取る。catch使えばいいんじゃないかと思うけど、何か用途があるんだろうか。

alwaysなくなってensureになった

名前変わっただけ。

catchがPromiseを返さなくなった

地味にやっかいなやつ。
catchがPromiseを返さなくなったので、このあとに処理を続けられなくなった。
ensureもダメ。
しかしまぁ、エラーのあとにやりたい処理があるでしょ、という場合のために finally が追加された。

というわけで、catchのあとにはfinallyを使う。

somePromise.done { data in
    setData(data)
}.catch { e in
    handleError(e)
}.finally {
    finish()
}

Promiseを返すメソッドの最後がcatchになっていた場合ややこしい気がする。やってみて追記する。

新しい型 Guarantee<T> ができたので使えそうなら使っていく

failしないPromiseとしてGuarantee<T>ができた。
catchが書けなくなるので、エラーになることのない処理はこっちになる。わかりやすい例のはafter

after(seconds: 1.0).done {
    startAnimation()
} // .catchは書けない

エラー有り無しを制御しやすくて良い。UIKitのextensionにあった UIView.animate 系も Guarantee<Bool> を返すようになっている(下記参照)。

UIViewのアニメーション

UIKitのextensionも同様に更新されていて、例えばアニメーションの書き方が少し変わっている。
https://github.com/PromiseKit/UIKit

大きな違いは、Promise<Bool> ではなく Guarantee<Bool> を返すようになっている点。
catchを書けなくなったので良い。

今まで

UIView.promise(animateWithDuration: 0.2, animation: {
    someMove()
}).then { 
    ... 
}

新しい

UIView.animate(.promise, duration: 0.5, options: .curveLinear) {
    someMove()
}.then { _ -> Guarantee<Bool> in
    return UIView.animate(.promise, duration: 1.0, delay: 1.0, options: .curveEaseOut) {
        anotherMove()
    }
}.then {
    ...

調べる予定

時間切れなのでこのへんにしつつ、他にもなにかでてきたら調べて追記したい

例えば、
UIView.promiseにwarning消すために全部catch書くのが面倒 UIView.animate も変わってたので追記済み。

26
18
1

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
26
18