Swift - 游戏中心不可用
Posted
技术标签:
【中文标题】Swift - 游戏中心不可用【英文标题】:Swift - Game Center not available 【发布时间】:2014-08-29 13:12:43 【问题描述】:我正在尝试在我的 Swift 游戏中实现 Game Center。我有一个菜单视图控制器,用户可以在其中按下“分数”按钮,这会将他们带到 Game Center 视图控制器。
这是在菜单 vc 中运行的代码,当按下按钮时:
var gcViewController: GKGameCenterViewController = GKGameCenterViewController()
gcViewController.gameCenterDelegate = self
gcViewController.viewState = GKGameCenterViewControllerState.Leaderboards
gcViewController.leaderboardIdentifier = "VHS"
self.presentViewController(gcViewController, animated: true, completion: nil)
我在 Game Center vc 中有代码,但我认为它没有机会运行。应用程序在此代码后停止执行(没有断点或错误,只是不会让我点击任何东西)并显示一条弹出消息,内容如下:
Game Center Unavailable
Player is not signed in
我得到的唯一其他响应是在 Xcode 中,其中将以下行打印到日志中:
2014-08-29 14:10:33.157 Valley[2291:304785] 17545849:_UIScreenEdgePanRecognizerEdgeSettings.edgeRegionSize=13.000000
我不知道这意味着什么,也不知道 Game Center 为何不工作。有人可以帮忙吗??
【问题讨论】:
【参考方案1】:假设您在应用中启用了 Game Center,并且还在 iTunes Connect 中添加了排行榜,那么您需要先验证您的玩家身份,然后才能显示 GC。此外,请确保您已在 iTunes Connect 中创建了一个测试用户,您可以在出现提示时使用该用户登录 Game Center。
您的MenuViewController
应该像这样在 viewDidLoad 中验证本地播放器:
class MenuViewController: UIViewController,
GKGameCenterControllerDelegate
var leaderboardIdentifier: String? = nil
var gameCenterEnabled: Bool = false
override func viewDidLoad()
super.viewDidLoad()
//Your code that sets up your scene or other set up code
//HERE IS WHERE YOU AUTHENTICATE
authenticateLocalPlayer()
func authenticateLocalPlayer()
var localPlayer = getLocalPlayer() // see GKLocalPlayerHack.h
localPlayer.authenticateHandler =
(viewController : UIViewController!, error : NSError!) -> Void in
if viewController != nil
self.presentViewController(viewController, animated:true, completion: nil)
else
if localPlayer.authenticated
self.gameCenterEnabled = true
localPlayer.loadDefaultLeaderboardIdentifierWithCompletionHandler
(leaderboardIdentifier, error) -> Void in
if error != nil
print("error")
else
self.leaderboardIdentifier = leaderboardIdentifier
print("\(self.leaderboardIdentifier)") //in your example "VHS" should be returned
else
print("not able to authenticate fail")
self.gameCenterEnabled = false
if error
print("\(error.description)")
else
print( "error is nil")
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController!)
gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
在您成功通过身份验证后,您应该可以展示 Game Center。
注意这一行:
var localPlayer = getLocalPlayer() // see GKLocalPlayerHack.h
要让它工作,你需要做一些小技巧来让 GKLocalPlayer 在 Swift 中正确实例化。
在 Objective-C 中创建一个新类并将文件命名为 GKLocalPlayerHack.h/m
在标题中放置:
// GKLocalPlayerHack.h
// Issue with GameKit and Swift
// https://***.com/questions/24045244/game-center-not-authenticating-using-swift
#import <GameKit/GameKit.h>
@interface GKLocalPlayerHack : NSObject
GKLocalPlayer *getLocalPlayer(void);
@end
在实现文件中放:
// GKLocalPlayerHack.m
// Issue with GameKit and Swift
// https://***.com/questions/24045244/game-center-not-authenticating-using-swift
#import "GKLocalPlayerHack.h"
@implementation GKLocalPlayerHack
GKLocalPlayer *getLocalPlayer(void)
return [GKLocalPlayer localPlayer];
@end
一定要加上:
#import "GKLocalPlayerHack.h"
到您的桥接头。 感谢@marmph 对这个问题的回答:Game Center not authenticating using Swift
【讨论】:
这看起来不错,尽管我在使用scene
变量的行上遇到错误,因为它尚未被声明。我该怎么做?
编辑了答案以包含场景变量。
好的,应用程序在尝试执行这 4 行时似乎一直在崩溃。我将它们注释掉,我收到一些错误,说它无法验证,但我的分数已添加到游戏中心,我可以查看它。这是为什么呢?
您正在运行 Xcode beta 6 吗?在早期的 GC 和 Swift 测试版中,存在一个已知的身份验证问题。
那么您能否再次澄清一下您的应用程序现在发生了什么?您是否收到 GC 提示登录? GC 视图控制器是否显示?你说查看分数是指你可以在GC中看到分数吗?【参考方案2】:
我用这种方式解决了 TEST MODE 的这个问题:
转到 Game Center 应用程序选项卡“朋友”点击屏幕末尾的设置:SANDBOX 和 LOGGING 必须处于开启模式
希望对大家有用
【讨论】:
【参考方案3】:你可以使用它,我在 github 上为 ios 游戏中心创建了一个 Easy Game Center https://github.com/DaRkD0G/Easy-Game-Center-Swift
来自法国的消息,圣诞快乐
开始
(1) 添加FrameWork GameKit.framework
(2) 创建两个文件:
GKLocalPlayerHack.h
#import <GameKit/GameKit.h>
@interface GKLocalPlayerHack : NSObject
GKLocalPlayer *getLocalPlayer(void);
@end
GKLocalPlayerHack.m
#import "GKLocalPlayerHack.h"
@implementation GKLocalPlayerHack
GKLocalPlayer *getLocalPlayer(void)
return [GKLocalPlayer localPlayer];
@end
(3) 在您的 Swift Bridging Header.h(Objectic-c 导入)中
#import "GKLocalPlayerHack.h"
下一步
class GameCenter
// Game Center
let gameCenterPlayer=GKLocalPlayer.localPlayer()
var canUseGameCenter:Bool = false
didSetif canUseGameCenter == true // load prev. achievments form Game Center
gameCenterLoadAchievements()
var gameCenterAchievements=[String:GKAchievement]()
/**
builder
*/
init(uiControlNow : UIViewController)
// Do any additional setup after loading the view.
self.gameCenterPlayer.authenticateHandler=(var gameCenterVC:UIViewController!, var gameCenterError:NSError!) -> Void in
if gameCenterVC != nil
//showAuthenticationDialogWhenReasonable: is an example method name. Create your own method that displays an authentication view when appropriate for your app.
//showAuthenticationDialogWhenReasonable(gameCenterVC!)
uiControlNow.presentViewController(gameCenterVC, animated: true, completion: () -> Void in
// no idea
)
else if self.self.gameCenterPlayer.authenticated == true
self.self.canUseGameCenter = true
else
self.canUseGameCenter = false
if gameCenterError != nil
println("Game Center error: \(gameCenterError)")
/**
Load prev achievement granted to the player
*/
func gameCenterLoadAchievements()
// load all prev. achievements for GameCenter for the user to progress can be added
var allAchievements=[GKAchievement]()
GKAchievement.loadAchievementsWithCompletionHandler( (allAchievements, error:NSError!) -> Void in
if error != nil
println("Game Center: could not load achievements, error: \(error)")
else
for anAchievement in allAchievements
if let oneAchievement = anAchievement as? GKAchievement
self.gameCenterAchievements[oneAchievement.identifier]=oneAchievement
)
/**
Add progress to an achievement
:param: Progress achievement Double
:param: ID Achievement
*/
func gameCenterAddProgressToAnAchievement(progress:Double,achievementID:String)
if canUseGameCenter == true // only update progress if user opt-in to use Game Center
// lookup if prev progress is logged for this achievement = achievement is already know (and loaded) form Game Center for this user
var lookupAchievement:GKAchievement? = gameCenterAchievements[achievementID]
if let achievement = lookupAchievement
// found the achievement with the given achievementID, check if it already 100% done
if achievement.percentComplete != 100
// set new progress
achievement.percentComplete = progress
if progress == 100.0 achievement.showsCompletionBanner=true // show banner only if achievement is fully granted (progress is 100%)
// try to report the progress to the Game Center
GKAchievement.reportAchievements([achievement], withCompletionHandler: (var error:NSError!) -> Void in
if error != nil
println("Couldn't save achievement (\(achievementID)) progress to \(progress) %")
)
else // achievemnt already granted, nothing to do
println("DEBUG: Achievement (\(achievementID)) already granted")
else // never added progress for this achievement, create achievement now, recall to add progress
println("No achievement with ID (\(achievementID)) was found, no progress for this one was recoreded yet. Create achievement now.")
gameCenterAchievements[achievementID] = GKAchievement(identifier: achievementID)
// recursive recall this func now that the achievement exist
gameCenterAddProgressToAnAchievement(progress, achievementID: achievementID)
/**
Remove One Achievements
:param: ID Achievement
*/
func resetAchievements(achievementID:String)
var lookupAchievement:GKAchievement? = gameCenterAchievements[achievementID]
if let achievement = lookupAchievement
GKAchievement.resetAchievementsWithCompletionHandler( (var error:NSError!) -> Void in
if error != nil
ToolKit.log("Couldn't Reset achievement (\(achievementID))")
else
ToolKit.log("Reset achievement (\(achievementID))")
)
else
println("No achievement with ID (\(achievementID)) was found, no progress for this one was recoreded yet. Create achievement now.")
gameCenterAchievements[achievementID] = GKAchievement(identifier: achievementID)
// recursive recall this func now that the achievement exist
self.resetAchievements(achievementID)
【讨论】:
以上是关于Swift - 游戏中心不可用的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 坐标不可用:从 iOS 7 开始不推荐使用 API
Swift 参数标签 '(_:, destination:)' 不匹配任何可用的重载
Swift 3.0:参数标签 '(_:) 不匹配任何可用的重载