Game Center機能を実装する

SwiftでGame Center機能を実装する情報が少なかったので、まとめておきます。
今回は、ベストタイムを送信する機能を実装してみます。

## 大まかな流れ
- iTunes Connectにアプリを登録する。
- iTunes ConnectでGame Center機能を有効化する。
- Xcodeでスコア送信機能などを実装する。
- 動作確認を行う。

## iTunes Connectへの登録
- [iTunes Connect](https://itunesconnect.apple.com/)にアクセスし、ログインする。
- 「マイ App」を押下する。
![iTunesConnect.png](https://qiita-image-store.s3.amazonaws.com/0/70446/c40f0f31-6907-dc17-bca2-da1c7a049b9e.png)

- 「新規 iOS App」を押下し、アプリを登録する。 
![newApp.png](https://qiita-image-store.s3.amazonaws.com/0/70446/a679c491-b4c9-9a5d-0e2f-b30c41dab0dd.png)

## Game Center機能の有効化とLeaderBoardの作成
- アプリ詳細ページからGame Centerタブを開き、シングルゲーム向けに有効化を押下する。
![gamecenter.png](https://qiita-image-store.s3.amazonaws.com/0/70446/6a29cb9c-9a27-8f8d-902d-c344f3f722ce.png)


- LeaderBoardの追加を押下する。
![gamecenter2.png](https://qiita-image-store.s3.amazonaws.com/0/70446/d5917138-58a2-a17f-37e1-9d4bf83ce4a1.png)

- 各項目を埋め、対応させる言語毎にサフィックスなどを入力する。
![gamecenter3.png](https://qiita-image-store.s3.amazonaws.com/0/70446/82d7842a-af96-eabc-32dd-ef242f42ebcf.png)  
![gamecenter4.png](https://qiita-image-store.s3.amazonaws.com/0/70446/349d5a1d-71ad-8989-3ca7-b118cdc35e64.png)

- アプリの詳細情報入力画面で、Game Centerを有効化する。
![gamecenter5.png](https://qiita-image-store.s3.amazonaws.com/0/70446/1c90861c-a040-2efb-0829-3b739c711b78.png)

## Xcodeの設定
- GameKit.Frameworの追加（General - Linked Frameworks and Libraries）
![GameKitFramework.png](https://qiita-image-store.s3.amazonaws.com/0/70446/7c14f2a0-5f7d-4d90-5e04-e79c9a41fea4.png)

- plist（General - Info - Custom iOS Target Properties）にGameKitを追記
![plist.png](https://qiita-image-store.s3.amazonaws.com/0/70446/57eba405-ca9e-79e6-e95b-7fed432f9b06.png)

## スコア送信機能の実装
### ログイン機能の構築
アプリ起動時に呼ばれるAppDelegateの"didFinishLaunchingWithOptions"内にログイン処理を記述することで、アプリが非アクティブから復帰した際にもきちんとログインするようにします。
※Swiftサラリーマンさんのソースを拝借させていただきました。

```swift:AppDelegate.swift
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        if let window = window{
            window.backgroundColor = UIColor.whiteColor()
            window.rootViewController = ViewController()
            window.makeKeyAndVisible()
        }
        // GameCenter Auto Login
        if let presentView = window?.rootViewController {
            let targetViewController = presentView
            GKLocalPlayerUtil.login(targetViewController)
        }
        return true
    }以下略
```

```swift:GKLocalPlayerUtil.swift
import UIKit
import GameKit

struct GKLocalPlayerUtil {
    static var localPlayer:GKLocalPlayer = GKLocalPlayer();
    
    static func login(target: UIViewController){
        self.localPlayer = GKLocalPlayer.localPlayer()
        self.localPlayer.authenticateHandler = {(viewController, error) -> Void in
            if ((viewController) != nil) {
                println("LoginCheck: Failed - LoginPageOpen")
                target.presentViewController(viewController, animated: true, completion: nil);
            }else{
                println("LoginCheck: Success")
                if (error == nil){
                    println("LoginAuthentication: Success")
                }else{
                    println("LoginAuthentication: Failed")
                }
            }
        }
    }
}
```
以下のようなログインページが表示できれば成功です。
![login.png](https://qiita-image-store.s3.amazonaws.com/0/70446/268d0cc8-8071-44fd-b2de-ddf89b1458da.png)

### スコア送信機能の実装

「Elapsed Time - To the Hundredth of a Second」を選択しているので、以下のように実装しました。

```swift:GameScene.swift
// Time Interval
self.startDate = NSDate() // StartDate
self.time = NSDate().timeIntervalSinceDate(self.startDate) // Elapsed Time
self.clearTime = self.time // Clear Time

// GameCenter Score Transration
var leaderBoardScore = Int(omitTime(self.clearTime) * 100) // Elapsed Time
GKScoreUtil.reportScore(leaderBoardScore, leaderboardid: gameMode)

func omitTime(time: Double) -> Double {
    return Double(Int(time * 100)) / 100
}時間関連の処理を一部抜粋


```

```swift:GKScoreUtil.swift
import UIKit
import GameKit

struct GKScoreUtil {
    static func reportScore(value: Int, leaderboardid: String){
        var score: GKScore = GKScore()
        score.value = Int64(value)
        score.leaderboardIdentifier = leaderboardid
        var scoreArr:[GKScore] = [score]
        GKScore.reportScores(scoreArr, withCompletionHandler:{(error:NSError!) -> Void in
            if((error != nil)){
                println("ReportScore NG")
            }else{
                println("ReportScore OK")
            }
        })
    }
}
```
### スコア確認機能の実装

```swift:GameScene.swift
// LeaderBoard
var localPlayer = GKLocalPlayer()
let navigationController = self.view?.window?.rootViewController as UINavigationController

if let vc = navigationController.visibleViewController as? ViewController {
    localPlayer.loadDefaultLeaderboardIdentifierWithCompletionHandler({ (leaderboardIdentifier : String!, error : NSError!) -> Void in
        if error != nil {
            println(error.localizedDescription)
        } else {
            let gameCenterController:GKGameCenterViewController = GKGameCenterViewController()
            gameCenterController.gameCenterDelegate = vc
            gameCenterController.viewState = GKGameCenterViewControllerState.Leaderboards
            gameCenterController.leaderboardIdentifier = self.gameMode
            vc.presentViewController(gameCenterController, animated: true, completion: nil)
        }
    })
}
```

## 動作確認
### サンドボックスユーザの作成
- iTunesConnectにログインし、ユーザと役割を選択します。
![user.png](https://qiita-image-store.s3.amazonaws.com/0/70446/2bd9cc2f-f011-f32a-3f02-aeebf57fbcbc.png)

- Sandboxテスターを選択し、テスターを作成します。
この際、1アカウントにつき1メールアドレス必要になってくるので、Gmailのエイリアス機能（+tester1)を用いて登録すると良いかもしれません。
![user2.png](https://qiita-image-store.s3.amazonaws.com/0/70446/f2983e22-e36c-8a27-1502-75862a95f77a.png)

### 実機もしくはシミュレータでの動作確認
- Settings - GameCenterから先ほど作成したユーザでログインし、Sandboxにチェックをいれておきます。
![iOS Simulator Screen Shot 2015.04.01 16.46.16.png](https://qiita-image-store.s3.amazonaws.com/0/70446/b2464ead-c2e3-d092-5314-aacff5c8f14b.png)

- アプリを立ち上げると、画面上部にWelcomBackのメッセージが表示されます。
![sand.png](https://qiita-image-store.s3.amazonaws.com/0/70446/d76a52fd-2a73-375a-da3a-71d615213e85.png)

- スコア送信処理を行った後、LeaderBoardを起動し、下記画面が表示されれば成功です。
![leaderboard.png](https://qiita-image-store.s3.amazonaws.com/0/70446/da4fb8ba-55b0-d2a4-068e-7d8122ca61a4.png)


## 参考
[Swiftサラリーマン - GameCenterのGKLocalPlayerでログイン認証](http://swift-salaryman.com/gklocalplayerutil.php)