I'm trying to create a custom view controller to display active games to the user (similar to what Letterpress does).
I am currently trying to subclass GKTurnBasedMatchmakerViewController except I don't know how to hide the default elements (for inviting/showing existing games) and to add my own. I have currently been playing around with logging things to ensure I can access the active matches, current player IDs, etc (which I have recently figured out) but I am stuck on how to start with the interface.
Not sure what code, if any would be relevant at this point. Please let me know.
Looking to: Hide current elements. I'm assuming I can build the interface as I would for any other application after that.
Thanks,
Steven
I don't think its a good idea to subclass. Start with a clean UIViewController and build the UI from there. Then implement all the necessary methods.
Set yourself as delegate:
[GKTurnBasedEventHandler sharedTurnBasedEventHandler].delegate = self;
so you get delegate event, such as:
handleInviteFromGameCenter
handleTurnEventForMatch
handleMatchEnded
etc.
Add a UITableView, and load all matches from Game center:
[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error) {
// Add matches to table view
}];
Don't forget to authenticate the player first:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *loginVC, NSError *error)
{
};
Star a match programatically:
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
[GKTurnBasedMatch findMatchForRequest:request withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
{
}];
etc. Look at the doc for the full API.
Related
I've implemented Game Center features like achievements and leaderboards, and now I'm working on the challenges. I was under the impression that I didn't have to add any additional code - if I had achievements or leaderboards, players would be able to send challenges to their friends. But now, in iOS10, you no longer have the ability to add players as friends - the challenges are handled through iMessages. The problem is - I don't see that feature anywhere in the GKViewController screen. If you select an achievement/leaaderboard score, you can tap on 'Challenge Friends', but it only suggests the players you already have in your friends list rather than in your contact list. Apple has also deprecated GKChallengesViewController, so I'm not sure where to look on how to do this.
Does anyone know how to add the iMessage Challenges feature to Game Center in iOS 10?
Update: I have seen that this feature lives within the GKMatchmakerViewController, but that seems to be for multiplayer type things. I'm still not sure how to use this to just send challenges.
From the Apple Docs:
Issuing a challenge does not display a user interface to the player issuing the challenge; this is code you need to implement yourself.
There are also a few examples on how to issue challenges and how to find players you can invite, such as:
- (void) challengePlayersToCompleteAchievement: (GKAchievement*) achievement
{
[achievement selectChallengeablePlayers:[GKLocalPlayer localPlayer].friends withCompletionHandler:^(NSArray *challengeablePlayerI, NSError *error) {
if (challengeablePlayers)
{
[self presentChallengeWithPreselectedPlayers: challengeablePlayers];
}
}];
}
...or:
- (void) challengeLesserMortalsForScore: (int64_t) playerScore inLeaderboard: (NSString*) leaderboard
{
GKLeaderboard *query = [[GKLeaderboard alloc] init];
query.leaderboardIdentifier = leaderboard;
query.playerScope = GKLeaderboardPlayerScopeFriendsOnly;
query.range = NSMakeRange(1,100);
[query loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
NSPredicate *filter = [NSPredicate predicateWithFormat:#"value < %qi",playerScore];
NSArray *lesserScores = [scores filteredArrayUsingPredicate:filter];
[self presentChallengeWithPreselectedScores: lesserScores];
}];
}
By the looks of it you still can only invite players that are already part of game center, i.e. no arbitrary "contacts" from the contact list (which makes sense), but this is only an assumption.
Been searching around for this, but can't seem to find an appropriate answer. Currently I have a system in my app in place to opt for a PIN to enter the app. I'd like to incorporate Touch ID instead, but can't figure out what to do for non-Touch ID phones.
Question: Can we use the Touch ID API to request the user enter their phone PIN to enter the app for those who do not have the Touch ID hardware?
The following code is to to test if we can evaluate the policy, this test will tell us if Touch ID is available and enrolled. If NO you can use your own PIN view for authorization.
LAContext *context = [[LAContext alloc] init];
NSError *error;
BOOL test = [context canEvaluatePolicy: LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];
if (test) {
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:#"For some reasons" reply:^(BOOL success, NSError *error) {
if (success) {
// authorized successfully
}
}];
} else {
NSLog(#"%#", error);
// use a pin code
}
As I have tried, you can't access to the built-in PIN and need to use a custom view instead.
I am developing a board game. Using Game Center for multiplayer, but currently stuck at how to send or receive invitations of GKTurnBasedMatch. I am creating match programmatically using:
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.defaultNumberOfPlayers = 2;
[GKTurnBasedMatch findMatchForRequest:request
withCompletionHandler:
^(GKTurnBasedMatch *match, NSError *error) {
if(error) {
NSLog(#"%#", error.localizedDescription);
return;
}
[self.delegate startGameForMatch:match];
}];
The GKTurnBasedMatch instance in parameter of above block, has only local player with other player as nil and I need to display details of opponent in the game.
NSMutableArray *participantIds = [[NSMutableArray alloc] init];
NSLog(#"%#", match.participants);
for (GKTurnBasedParticipant *participant in match.participants) {
if(participant.playerID) [participantIds addObject:participant.playerID];
}
[GKPlayer loadPlayersForIdentifiers:participantIds
withCompletionHandler:^(NSArray *players, NSError *error) {
NSMutableString *string = [[NSMutableString alloc] init];
for (GKPlayer *player in players) {
[string appendFormat:#"---- Alias: %# DisplayName: %#", player.alias, player.displayName];
}
NSLog(#"%#", string);
}];
Am I missing something or Game Center works like this?
I read that participants of the match wont get invitations until that GKTurnBasedParticipant is GKTurnBasedMatch.currentParticipant but I need to display the details of opponent when game started.
Thanks for the help. Point me in correct direction.
This happens when you create a match against a random opponent. Try creating a second test user in iTunesConnect and signing into that user on a second device.
Then, send that second test player an invite to be your friend. This will allow you to more easily test your game with multiplayer features without having to wait for a random match to be found.
After the friend request is accepted, try creating a new game once more. Now, invite your 'Friend' to your game and start your turn. You will now notice that the (null) variables will - for the most part - be filled in. Something like this should now appear in your log-
GKTurnBasedParticipant 0xb9432e0 - playerID:G:123456789 status:Invited matchOutcome:None lastTurnDate:(null) timeoutDate:(null)
I make the turn-based game on Game Center.
When I search another user through auto-match function, does GameCenter search another user that this game was installed or user that have free time?
Because when I implement auto match feature on turn based game, it returns null value,
I want to know more detail about the auto match feature.
If GameCenter searches the user that game was installed and the game is not famous, then I think that auto-match can't run.
How can I implement auto-match feature programmatically?
Following codes doesn't return any user of game center.
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
[GKTurnBasedMatch findMatchForRequest: request withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
{
if (match){
//[self performSegueWithIdentifier:#"GamePlayScene" sender:match];
NSLog(#"match id: %#", match.matchID);
}
}];
Because it has very little info on sites for auto-match feature, so please help me for auto-match.
Thanks for your help.
I want to implement ranking by using Game Center.
So , I implement like this .
-(void)authenticateLocalPlayer
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *vc,NSError *err){
[self setLastError:err];
if ([CCDirector sharedDirector].isPaused){
[[CCDirector sharedDirector] resume];
}
if (localPlayer.authenticated){
_gameCenterFeaturesEnabled = YES;
// get localplayer's score.
GKLeaderboard *board = [[GKLeaderboard alloc] init];
// make a query
board.timeScope = GKLeaderboardTimeScopeAllTime;
// I want to get all player's score.
board.playerScope = GKLeaderboardTimeScopeToday;
// set my game category.
board.category = #"com.nobinobiru.shooting";
// I want to show top 3 score data.
board.range = NSMakeRange(1, 3);
[board loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
NSString *s = [NSString stringWithFormat:#"%lld",board.localPlayerScore.value];
[ud setObject:[NSString stringWithFormat:#"%#",s] forKey:#"bestScore"];
if (scores){
// I want to 3 items but it returned only 1 item.
NSLog(#"score is %#",scores);
}
}];
}else if (vc){
[[CCDirector sharedDirector] pause];
[self presentViewController:vc];
}
};
}
Then, I create 3 sandbox's user account , and I test it.
But it always only show current user's best score.
I want to show 3 sandbox's data.
I don't know why it happened like that.
My code works well in not sandbox environment?
Do you have any idea?
Thanks in advance.
All.
It works perfectly after 6 hours...
I think that the reason why it happened is my created game center account was not reflect immediately.