iOSアプリ開発

DispatchQueueを使って容量のあるファイルをダウンロードする方法

iOSアプリなどで画像のようなファイルデータをダウンロードすることはよくありますよね。ファイルのサイズが小さければあまり問題になりませんが、多くのアプリでは重いファイルデータをダウンロードすることが多いと思います。

重いファイルをダウンロードするためには、メインスレッドではなくサブスレッドを使ってダウンロードする必要があります。今回は、Swiftでサブスレッドを使って非同期でダウンロードする方法を紹介します。

Data(contentsOf:)を使うと簡単

Swiftでファイルデータを取得する方法として、もっともシンプルなのはData(contentsOf:)を使うことです。ファイルデータを取得することができます。

この時、いくつか気をつけないといけない点があります。

1つ目は、ヘッダー情報を渡せないこと。シンプルにURLのみの情報からファイルデータの取得を行うため、OAuth認証などのあるファイルデータの取得はできないことです。

2つ目は、Aの位置で直接データを取得するためブロッキングが発生する。この場合、メインスレッドで取得をしてしまうとUIがブロックされてしまいます。

DispatchQueueを使って非同期で取得

上記の方法だとUIをブロックしてしまうので、DispatchQueueを使ってサブスレッド上でデータを取得すしてみましょう。

以下のコードは、データ取得をサブスレッドで行いUIの更新をメインスレッドで行う実装です。

UIはメインスレッドで更新するためデータを取得した後はメインスレッドに移行して更新をしている。

URLConnectionを使う方法

Data(contestsOf:)を使ってデータを取得する方法を紹介しました。この方法だと、データを取得するだけであれば問題ないのですが、OAuth認証が必要な場合などヘッダー情報を付加できなかったり処理をブロックしてしまうことから、サーバーからファイルデータを取得するようなや大きなデータを取得する場合は、URLSessionのようなネットワークモジュールを使った処理が増えてきます。

先ほど紹介した処理をURLSessionで実装すると以下のようになります。

DispatchGroupを使って非同期処理をまとめて実行する

URLSessionを使えばメインスレッドを使わずにサブスレッドで重たいデータを取得することが可能にすることができました。

しかし、一方で非同期処理によるデメリットもあります。複数のデータをまとめて取得したい場合、以下のように非同期処理だと複雑になってしまうことが多々あります。

こういった時に他の処理が完了するまで待つ方法として、DispatchGroupとDispatchSemaphoreというものがあります。今回は、DispatchGroupを使った方法を紹介します。

DispatchGroupは、wait()を呼び出した時点で処理をブロッキングします。全ての同じ回数のenter()とleave()が呼び出される回数だけ処理を待つことができます。

今回は、2つの画像読み込みを行ってそれぞれが完了するまで処理をブロッキングして待つようにしています。

この場合も気をつけるポイントがあります。getImagesByUsingSemaphore()をそのまま呼び出すと処理がブロッキングされるので、必ずサブスレッドに移動してから呼び出します。

async/awaitを実現するHydra

JavaScriptでよく使われれる機能の中に async/await というものがあります。これは、先ほど紹介したDispatchQueue/DispatchSemaphoreを使った処理に似た処理が可能にすることができます。
HydraというOSSで await/async を使うことができるのでおすすめです。

Related post

  1. iOSアプリ開発

    人気iOSアプリが作れるようになるおすすめの本8選

    アプリ開発にチャレンジできていなかったりアプリ開発に詰まってしまったり…

  2. iOSアプリ開発

    iOSアプリ開発者が本当にオススメする6つの技術系サイト

    今回は、iOSアプリエンジニアとして実際に良く参考にしているサイトを紹…

  3. iOSアプリ開発

    iOSアプリ初心者が覚えておきたい10のUIクラス

    iOSアプリを開発したいけど、最初は何を知っていたら開発できるのかわか…

  4. xcode

    iOSアプリ開発

    iOSアプリ開発に必要なXcodeについて知ろう

    「アプリ開発って難しそう」「アプリを作ってみたいけど作り方がわからない…

  5. iOSアプリ開発

    xcconfigを使って本番とテスト環境を切り替える方法

    iOSアプリを開発していると、本番の環境とテストする環境を切り替えて開…

  6. iOSアプリ開発

    SwiftでJSONデータを使いやすくする!Codableの使い方

    APIからデータを取得する時、JSONでデータを受け取ることがあるかと…

PAGE TOP