【SwiftUI/Firebase】Realtime Databaseでオフラインキャッシュを有効にする方法

この記事からわかること

  • SwiftFirebaseRealtime Databaseオフラインでのローカルキャッシュ有効にする方法
  • isPersistenceEnabledプロパティ設定方法と記述場所
  • ネットワーク接続可否識別するには?

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

公式リファレンス:Appleプラットフォームのオフライン機能

Realtime Databaseでのオフラインデータ表示

FirebaseのRealtime Databaseではオフライン環境でも永続的なデータの表示が可能になっているのが大きなメリットでもあります。

仕組みとしてはオンライン時に取得したいデータをデバイス内にローカルキャッシュとして保存しておくことで最終読み込み時のデータを表示できる仕組みになっています。また更新などの操作もローカルキャッシュに対して行うことができるのでユーザーはオフラインを意識することなく操作できるようになっています。

そして再度オンラインになった際に書き込み処理や変更処理などをが自動で反映されるようになっています。

ですがRealtime Databaseではオフライン環境でのデータ表示を有効にするには設定を明示的にする必要があります。

Swift UIでオフラインを有効にする方法

オフライン時のためにデータキャッシュを有効にするには以下のようにdatabaseインスタンスのisPersistenceEnabledプロパティの設定を変更する必要があります。

Database.database().isPersistenceEnabled = true

Swift UIを使用している場合はアプリプロジェクトファイルのdelegateの中に記述します。importも忘れずにしておきます。

import FirebaseDatabase // 追加
class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
         // 追加
        Database.database().isPersistenceEnabled = true
        return true
    }
}

これでデータがローカルにも保存されオフライン環境になってもデータ表示を永続的に行えるようになりました。

ネットワーク接続の可否を識別する

さらにRealtime Databaseではネットワーク接続の可否を簡単に識別できるような機能が組み込まれています。

/.info/connected内にユーザーの接続状態を真偽値で常に保持されるようになっているので、その値によって識別可能です。

let connectedRef = Database.database().reference(withPath: ".info/connected")
connectedRef.observe(.value, with: { snapshot in
  if snapshot.value as? Bool ?? false {
    print("Connected")
  } else {
    print("Not connected")
  }
})

ネットワーク接続によって読み込み先を分岐させる

ネットワーク接続の可否によってサーバーからデータを読むか明示的にローカルキャッシュからデータを読み込むかを分岐させる処理を実装してみます。

// ネット接続状況によって処理を分岐させる
func checkConnectedCallLoading(){
    let connectedRef = Database.database().reference(withPath: ".info/connected")
    connectedRef.observe(.value, with: { snapshot in
      if snapshot.value as? Bool ?? false {
//              print("Connected")
          self.loadingData()
        
      } else {
//              print("Not connected")
          self.localLoadingData()
      }
    })
}

// オンライン時のデータ読み込み
func loadingData() {
ref.child("users").child(currentUserID).getData(completion:  { error, snapshot in
        guard error == nil || snapshot != nil else {
              print(error!.localizedDescription)
            return
        }
    })
}

// オフライン時のキャッシュデータ読み込み
func localLoadingData() {
  ref.child("users").child(currentUserID).observeSingleEvent(of: .value, with: { snapshot in
    })
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index