ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

iOS SDKとPromiseライブラリHydraを組み合わせる

f:id:mbaasdevrel:20180806093819p:plain

Swiftでは非同期処理が多用されます。非同期処理の結果はコールバック方式になっているので、非同期処理が続くとネストがどんどん深くなってしまいます。そこでJavaScriptでは昔からPromiseという方式が使われてきました。

iOSではPromiseKitなどが知られていますが、この記事では高機能なPromiseライブラリであるHydraとiOS SDKを組み合わせる方法を紹介します。

Hydraのインストール

HydraはCocoaPodsなどでインストールできます。

# use_frameworks!
pod 'HydraAsync'

Hydraの使い方

Hydraはまず使うViewController上でインポートします。

import Hydra

例えばファイルストアへアップロードする処理の場合、次のように関数を作ります。

func uploadPhoto(file: NCMBFile) -> Promise<NCMBFile> {
  return Promise<NCMBFile>(in: .background, { resolve, reject, _ in
    file.saveInBackground({(error) in
      if error != nil {
        // 保存失敗時の処理
        reject(error!)
      } else {
        // 保存成功時の処理
        resolve(file)
      }
    })
  })
}

そして、これを使う方は以下のように書きます。 in: .main を書いた後、resolveやrejectで受け取る引数を記述します。

let file = NCMBFile.file(withName: fileName, data: photoData) as! NCMBFile
self.uploadPhoto(file: file).then(in: .main, {file in
  print("アップロード完了")
  print(file)
})
.catch(in: .main, { error in
  print(error)
})

async/awaitも

さらにPromiseの場合はチェーンでつないだ時に、前の結果を見られない(別な変数をスコープ外で定義しておく必要がある)のが不便です。そこでJavaScript界隈で使われているのがasync/awaitになります。Hydraでも同様に操作が可能です。

先ほどの処理をasync/awaitで書き直したものです。asyncというグローバル関数が定義されており、それを使うことで非同期処理をawaitで囲んで書けるようになります。最後にreturnすることでthen処理に繋ぐこともできます。

async { _ -> NCMBFile in
  let result = try! await(self.uploadPhoto(file: file))
  return result
}.then({fileResult in
  print(fileResult)
})

次の処理に繋げない場合でも async 関数を実行するために then は必要です。特に引数が不要な場合は次のように書けます。

async { _ -> Void in
  let result = try! await(self.uploadPhoto(file: file))
  print(result);
  return
}.then({_ in
  
})

まとめ

Hydraを使うことで、NCMBのように非同期処理の多いSDKでも容易に扱えるようになります。コールバックやPromiseで苦しんだ経験のある方はHydraを使ってみてください。

malcommac/Hydra: Lightweight full-featured Promises, Async & Await Library in Swift

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。