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

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

Swift SDKでセッションの確認と強制ログアウトを実装する

f:id:mbaasdevrel:20180806093819p:plain

Swift SDKのTipsです。執筆時点のバージョン1.1.2ではコード修正の必要がありますが、将来的には解決している可能性があります。

mBaaSでは認証情報をアプリ内部に保存します。それによって毎回認証を行うことなく、アプリがオフラインであっても認証状態を維持できるようになっています。しかし、認証セッションの有効期限は最長1週間であり、気づかないうちにセッションが無効になっている可能性があります。

そこでセッションの有効性チェックと、ログアウト処理を実行する方法を紹介します。

ログイン状態を取得する

ログイン状態は NCMBUser.currentUser で確認できます。これで nil が返ってくる場合はログインしていません。

let user = NCMBUser.currentUser
if user == nil {
    // ログインしていません
} else {
    // ログインしています
}

セッションの有効性を確認する

問題はこのログインしている状態の場合です。ローカルデータから復元していますので、この時点ではセッションが有効かどうかは確認していません。そこで、mBaaSのAPIを実行してみます。一番簡単なのはデータストアにアクセスしてみることです。

// セッションの有効性チェック
var query : NCMBQuery<NCMBObject> = NCMBQuery.getQuery(className: "Todo")
query.limit = 1
query.findInBackground(callback: { results in
    switch results {
    case let .success(obj):
        print(obj)
    case let .failure(error):
        // 強制ログアウト
    }
})

ここで強制ログアウトと書いているのは理由があります。セッションが無効な場合、ログアウトAPIを呼び出すのも失敗してしまいます。通常のログアウトメソッドが呼び出せないので、ユーザデータを消せない状態になってしまいます。

コードを修正する

そこでコードを修正します。CocoaPods を使っている場合は対象のファイルは Pods/NCMB/NCMBUser.swift になります。元は次のようになっています(372行目)。

public class func logOutInBackground(callback: @escaping NCMBHandler<Void>) -> Void {
    NCMBLogoutService().logOut(callback: {(result: NCMBResult<NCMBResponse>) -> Void in
        switch result {
            case .success(_):
                deleteFile()
                _currentUser = nil
                callback(NCMBResult<Void>.success(()))
                break
            case let .failure(error):
                callback(NCMBResult<Void>.failure(error))
                break
        }
    })
}

これを次のように修正します。deleteFile と _currentUser = nil を前に持ってきます。これで強制的にローカルファイルの削除が実行されます。なお、修正時にロックされているのを解除するか求められるので、解除してから修正・保存してください。

public class func logOutInBackground(callback: @escaping NCMBHandler<Void>) -> Void {
    NCMBLogoutService().logOut(callback: {(result: NCMBResult<NCMBResponse>) -> Void in
        // レスポンスに関係なくログアウト処理
        deleteFile()
        _currentUser = nil
        switch result {
            case .success(_):
                callback(NCMBResult<Void>.success(()))
                break
            case let .failure(error):
                callback(NCMBResult<Void>.failure(error))
                break
        }
    })
}

強制ログアウトを実行

この修正を行えば、後はログアウトを実行するだけです。エラーが出ていてもログアウト処理は完了していますので問題ありません。

// セッションの有効性チェック
var query : NCMBQuery<NCMBObject> = NCMBQuery.getQuery(className: "Todo")
query.limit = 1
query.findInBackground(callback: { results in
    switch results {
    case let .success(obj):
        print(obj)
    case let .failure(error):
        // 強制ログアウト
        NCMBUser.logOutInBackground(callback: { result in
            print("強制ログアウト")
        })
    }
})

まとめ

将来的なバージョンではアプリ内部のデータを強制的に消されるようになるはずです。一時的な対処法ですが、現状ログアウトできない場合には、この方法で対応してください。

中津川 篤司

中津川 篤司

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