GameCenterのログイン処理

以前に書いた「GameCenterを用いたオンラインスコア対応手順」に関して
起動時に強制的にGeme Centerへのログイン処理を行っていたのでユーザとしては少し邪魔かと思い少し模索。

まず最初に対応したかったのが、Game Centerへのデータの送受信が必要な場合のみにログイン処理を発生させる事。
これはログインの処理をAppDelegate.swiftではなく、ランキング用のシーンに追加する事で対応。
※常時ログイン状態を維持出来るようにという流れには反しますが・・

次に「データ送信」or「一覧表示」ボタンを押した際に
ログイン処理 ⇒ 送信or取得
という流れを試してみたが、

player.authenticateHandler =
{(viewController: UIViewController?, error: NSError?) in
~以下略

のplayer.authenticateHandlerに関数を渡す部分と
実際に関数が実行される時間にラグがあり、直列的な処理ではログイン判定が正しく行えなかった。

下記を試してみたが上手くいかず
・関数を渡す処理にコールバックはさむ
⇒渡す前後での処理を挟む事は出来るが、当然のように呼び出しタイミングとは無関係の為、挙動変わらず

・グローバルな変数でログイン確認状態を管理し、
「ログイン」~「送信or一覧表示」処理の間で強制的にスリープをかける
⇒可能は可能だが、挙動が不自然になってしまう為、没案

・(非同期のまま)ログイン処理の直後に「送信or一覧表示」処理を記述
⇒反応がないように見える為、スリープ以上に違和感が発生、また間に他の処理が出来てしまう事への配慮も必要。


結局上手く行かなかったので最終的に以下の形で妥協しました。
・ランキング画面移動時にログイン状態の判定を行う
・ログインボタンを追加
・ログイン状態でのみ送信or一覧表示ボタン有効(状態保存&touchesBegan関数内での振り分けなどで対応)
とてもブサイクな仕様ですが・・・

関数例)

//game center ログイン処理
//ログインボタン押下時に呼び出し
func gameCenterLogin() {
if let rootView = self.view?.window?.rootViewController {
let player = GKLocalPlayer.localPlayer()

player.authenticateHandler =
{(viewController: UIViewController?, error: NSError?) in
if player.authenticated {
print("geme center authenticated")

} else if viewController != nil {
print("game center not login. login page open")
rootView.presentViewController(viewController!, animated: true, completion: nil)

} else {
if error != nil {
print("game center login error, \(error!.code): \(error!.description)")
}
}

//ログイン状態の更新
self.gameCenterSet(player.authenticated)
}
}
}

//game center のログイン状態確認
//画面
func gameCenterLoginCheck() {
let player = GKLocalPlayer.localPlayer()
if player.authenticated {
self.gameCenterSet(true)

} else {
self.gameCenterSet(false)
}
}

//アプリ内の各種状態の更新
func gameCenterSet(state: Bool) {
if state {
//ログイン状態に更新
//送信、一覧の有効化、ログインの無効化、etc
} else {
//非ログイン状態に更新
}
}



※以下、私が参考にしている本の紹介になります。









スポンサーリンク

この記事へのコメント


この記事へのトラックバック