0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[RxSwift]詰み① アプリキル直前にデータを保存したい

Posted at

RxSwift初心者です。完全自分用の学習備忘録として残します。

開発中、RxSwiftで以下の実装方法に詰まりました。

  1. ユーザーが誤ってデータをDBへ保存せずに、アプリをキルしようとする
  2. アプリがバックグラウンドに移行した際にローカルにデータを保存
  3. アプリがキルされ、再度、アプリを起動する
  4. ローカルに保存されたデータの有無を確認
  5. データがある場合、「前回保存されていないデータがあります。データを保存しますか?」という文言でUIAlertを表示
  6. 保存ボタンを押下し、データを保存する非同期処理を実行
  7. 非同期処理中、仮にエラーが発生するとする
  8. 画面上に「エラー データの保存に失敗しました。保存しますか?」というエラーUIAlertを表示
  9. 6, 7, 8 を繰り返す

この記事では、1 〜 2 を扱い、3 〜 9は別の記事**「[RxSwift]詰み② UIAlertを活用してデータ保存の失敗時に繰り返しリトライさせたい」**で扱います。

1. ユーザーが誤ってデータをDBへ保存せずに、アプリをキルしようとする

うっかりデータを保存し忘れてアプリを終了させてしまうユーザーもいると思います。開発者は対策を考える必要があります。

2. アプリがバックグラウンドに移行した際にローカルにデータを保存

結論から言うと、Realmを使用してローカルにデータを保存させています。

特定のViewControllerに以下の処理を実装して、アプリがバックグラウンドに移行したことを検知し、その時点でのユーザーの勉強時間等をRealmに保存するようにしています。


    // バックグラウンド移行時
     NotificationCenter.default.addObserver(
            self,
            selector: #selector(self.didEnterBackground),
            name: UIApplication.didEnterBackgroundNotification,
            object: nil
    )
        
    // バックグラウンドへの移行時の処理
    @objc func didEnterBackground() {
        // アプリをキル(完全終了)した場合でもローカルに勉強記録等を保存しておく
        viewModel.saveStudyProgress(shouldSaveLocallyOnKill: true)
    }
  • 少し苦戦した話

はじめは、Realmではなく、直接Firebaseに保存する処理を実装していましたが、以下のフローを行うとFirestoreへデータが正常に更新されない時がありました。

  1. アプリをフォアグラウンド状態にする(普通にアプリの画面を表示させている状態)

  2. app switcherにアプリ画面を表示する(以下のような状態です)
    (この時点ではまだ@objc func didEnterBackground()は呼ばれません。)

  3. 2の状態からアプリをキル(アプリ画面を上にスワイプさせて完全終了させた状態)させる

  4. ここで初めて@objc func didEnterBackground() に処理が入り、Firestoreへのデータ保存処理を実行

  5. Firebase consoleFirestoreを確認するも、データが正常に更新されない
    ・ とあるフィールドは正常に更新されていて、とあるフィールドが更新されなかったり…
    ・ 時には、全てのデータが正常に更新されていたり… 逆も然り…

アプリがキルされる”直前”に@objc func didEnterBackground() が呼ばれている → すなわち、言い換えれば、app switcherからであれば、キルされないと@objc func didEnterBackground() が呼ばれないということか…

そして、データが正常に更新されない理由は、おそらく非同期処理中にアプリがキル(完全に終了)されたためだと思います。

app switcher に移行した時点で@objc func didEnterBackground() が呼ばれると思っていたのですが、違ったようです。勉強になりました。

以上の問題から、Realmを使用して、一旦ローカルにデータを保存しておくと言う方針にしました。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?