Definitive answer to what playersToInvite is for - objective-c

The Game Center documentation indicates that the
playersToInvite parameter is non-nil
when your application is launched
directly from the Game Center
application to host a match.
A few people have asked how this works exactly, i.e. there doesn't appear to be a way to select a friend from the Game Center application and invite them to play from Game Center; it only works when you invite in-game. Is this documentation dated or is there a secret way to start a game-specific match from Game Center? I'd like to test my inviteHandler but I've been unable to determine how this parameter is passed to the application.
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite)
{
// clean up games in progress here
if (acceptedInvite)
{
NSLog(#"acceptedInvite %#", acceptedInvite);
// The acceptedInvite parameter is non-nil when the application receives an
// invitation directly from another player.
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
mmvc.matchmakerDelegate = self;
[self disableHomeUI];
[self presentModalViewController:mmvc animated:YES];
}
else if (playersToInvite)
{
NSLog(#"playersToInvite %#", playersToInvite);
// playersToInvite parameter is non-nil when your application is launched
// directly from the Game Center application to host a match
[self disableHomeUI];
[self doPresentMatchMakerUIWithPlayersToInvite:playersToInvite];
}
};

I think the docs do not reflect the current state of affairs. As far as I can tell, the Game Center App does not even offer an interface for inviting friends to play, currently.
Also, check the developer forums (apparently you have ;) ). Someone from Cupertino seems to think it is not possible. So...

After launching my application Cee-lo into production, the playersToInvite code became active. This seems to be because the Sandbox version of the Game Center app itself does not allow you to start a game with a player from there, but the production version does. Not a very good test environment if you ask me!

There is now a way to use the Game Center app to invite a Game Center friend. It ONLY works if your game calls registerListener: on the localPlayer GKPlayer:
Game Center App
-> games tab
-> your game
-> Players section
-> select a player
-> "Play a Game"
This will send a push notification invite to the other player. Game does not have to be running on either device. As of iOS7.
This flow also works:
Game Center App
-> friends tab
-> tap a friend
-> tap a game in common (your game)
-> tap the "..." in the top right corner
-> tap "Play"

I could be wrong, but i think it is just the "simulator" that can not invite particular friends to play.
I have been able to use 2 or more iPhones running in the sandbox to invite particular friends to play, and it has worked wonderfully for debugging the invite handler piece of code.
As another poster mentioned, there does not appear to be at this time a way of inviting particular friends to play a particular game from Game Center.
Happy gaming!

Related

background location iOS 8

Hello Devs: I am working on an app where I would like to fetch users location in background and send push notifications to him as soon as the user arrives at that particular location. Here is what I have done so far with my locatioManager in my app delegate
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
if (IS_OS_8_OR_LATER) [locationManager requestAlwaysAuthorization];
[locationManager startUpdatingLocation];
I have set up my info.plist to always request location. I also get the message that my app will be using location in the background when I install the app on my device. However when I close the app and arrive at the specific location I don't get any push notifications or alerts until I launch the app. I turned on Background mode --> location updates under capabilities section and then everything works absolutely fine. I receive notification seamlessly without launching the app. This is all good but when I close the app I see a blue bar on my status bar saying that my app is tracking the location in background. How do I hide that blue bar on the top? I am pretty sure this is going to scare away my users and they will remove my app instantly. To make long story short how do I accomplish this? I know this question has been asked and answered several times in past but all those answers are 2-3 years old and don't seem to work with new iOS 8. I need to get the user location in background in order for my app to work or else its useless. I will really appreciate any help or suggestions to this.
Thanks!
What you want to do is called (background) Geofencing. Your app doesn't need to calculate it by itself since CoreLocation already offers this feature.
Please have a look at this answer from Daniel.
The Geofencing feature will wake up your app when the users gets into the target zone, and will not display the blue bar.

Receive remote control events without audio

Here is some background information, otherwise skip ahead to the question in bold. I am building an app and I would like it to have access to the remote control/lock screen events. The tricky part is that this app does not play audio itself, it controls the audio of another device nearby. The communication between devices is not a problem when the app is in the foreground. As I just found out, an app does not assume control of the remote controls until it has played audio with a playback audio session, and was the last do so. This presents a problem because like I said, the app controls ANOTHER device's audio and has no need to play its own.
My first inclination is to have the app play a silent clip every time it is opened in order to assume control of the remote controls. The fact that I have to do this makes me wonder if I am even going to be allowed to do it by Apple or if there is another way to achieve this without fooling the system with fake audio clips.
QUESTION(S): Will Apple approve an app that plays a silent audio clip in order to assume control of the remote/lock screen controls for the purpose of controlling another device's audio? Is there any way of assuming control of the remote controls without an audio session?
P.S. I would prefer to have this functionality on iOS 4.0 and up.
P.P.S I have seen this similar question and it has gotten me brainstorming but the answer provided is not specific to what I need to know.
NOTE: As of iOS 7.1, you should be using MPRemoteCommandCenter instead of the answer below.
You create various system-provided subclasses of MPRemoteCommand and assign them to properties of the [MPRemoteCommandCenter sharedCommandCenter].
I'm keeping the rest of this around for historical reference, but the following is not guaranteed to work on recent iOS versions. In fact, it just might not.
You definitely do need an audio player but not necessarily an explicit session to take control of the remote control events. (AVAudioSession is implicit to any app that plays audio.) I spent a decent amount of time playing with this to confirm this.
I've seen a lot of confusion on the internet about where to set up the removeControlEventRecievedWithEvent: method and various approaches to the responder chain. I know this method works on iOS 6 and iOS 7. Other methods have not. Don't waste your time handling remote control events in the app delegate (where they used to work) or in a view controller which may go away during the lifecycle of your app.
I made a demo project to show how to do this.
Here's a quick rundown of what has to happen:
You need to create a subclass of UIApplication. When the documentation says UIResponder, it means UIApplication, since your application class is a subclass of UIResponder. In this subclass, you're going to implement the remoteControlReceivedWithEvent: and canBecomeFirstResponder methods. You want to return YES from canBecomeFirstResponder. In the remote control method, you'll probably want to notify your audio player that something's changed.
You need to tell iOS to use your custom class to run the app, instead of the default UIApplication. To do so, open main.m and change this:
return UIApplicationMain(argc, argv, nil, NSStringFromClass([RCAppDel`egate class]));
to look like this:
return UIApplicationMain(argc, argv, NSStringFromClass([RCApplication class]), NSStringFromClass([RCAppDelegate class]));
In my case RCApplication is the name of my custom class. Use the name of your subclass instead. Don't forget to #import the appropriate header.
OPTIONAL: You should configure an audio session. It's not required, but if you don't, audio won't play if the phone is muted. I do this in the demo app's delegate, but do so where appropriate.
Play something. Until you do, the remote controls will ignore your app. I just took an AVPlayer and gave it the URL of a streaming site that I expect to be up. If you find that it fails, put your own URL in there and play with it to your heart's content.
This example has a little bit more code in there to log out remote events, but it's not all that complicated. I just define and pass around some string constants.
I bet that a silent looping MP3 file would help work towards your goal.
Moshe's solution worked great for me! However one issue I noticed is when you paused the audio, the media controls would go away and you won't be able to play it again without going back into the app. If you set the Media Info on the lock screen when you play the audio then this won't happen:
NSDictionary *mediaInfo = #{MPMediaItemPropertyTitle: #"My Title",
MPMediaItemPropertyAlbumTitle: #"My Album Name",
MPMediaItemPropertyPlaybackDuration: [NSNumber numberWithFloat:0.30f]};
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:mediaInfo];

Home Button doesn't terminate multiplayer match on Game Center / Gamekit

First of all I have to say I am new to iOS development.
My problem is during a multiplayer game using Game Center. I don't now how to get a notification from Game Center if the other player (my game is a 2 player game) leaves the game with the home button of the device.
I need to know when one player closes the game since the game always starts from scratch when re-opened, this means, it will show the splash screen and go directly to the main menu. I've tried re-matching but Game Center seems to be creating a new connection and looking for new players, meanwhile player 2 keeps 'playing' with player 1 without any response happening, so his match will never end.
Any method, didChangeState, matchmakerViewControllerWasCancelled nor authenticationChanged, the latter being under a notification, seem to do anything when the home button is pressed.
Any help would be appreciated
Try subscribing to NSNoficationCenter to find out when your app goes to the background:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(userPressedHomeButton:)
name:UIApplicationDidEnterBackgroundNotification object:nil];
In your userPressedHomeButton: function you can decide how to notify the other player or suspend the game. BUT, you must take action quickly, because iOS will not allow your app to run more than a few seconds after it has been suspended.
As an alternate to subscribing to NSNotificationCenter, you can do your implementation in your AppDelegate:
- (void)applicationWillResignActive:(NSNotification *)notification { }

How do you know when a user chooses to play a video through AirPlay?

I have a custom video player set up with custom controls, and I utilize MPVolumeView to provide an airplay button. When a user chooses to use AirPlay, they interact with that Apple UI and there is no event (that I can find) that says "hey, the video is now playing over AirPlay".
The problem is that, if I close the player and reopen it, it loads the movie (load state changes to MPMovieLoadStatePlayable), I play it, and I immediately get a playback did finish notification with reason being MPMovieFinishReasonPlaybackEnded, and the video continues to try to play through AirPlay. I'm certain the movie stops and is deallocated whenever I close the player.
If anyone has any advice on how to handle this, knows some events to listen for, or has any ideas about this whatsoever, please let me know. Thanks!
The answer here turns out to be that, at least up to 4.3, there is no way to get an answer to this through code.
The problem in this case is how you dispose of the MPMoviePlayerController when you're finished with it. Even if the video plays through, before you finally release it, you have to call pause and then stop. Like this:
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] init];
// use the player. then when done with it:
[mp pause];
[mp stop];
[mp release];
If you don't do this then the next time you create a MPMoviePlayerController, certain properties are somehow ghosted in the framework. Playing a video progressively caused audio from the previous mp to play while the new mp did its initial buffering. Also, if the previous video was playing over airplay, the next video would get a notification that the video finished right after it starts and some other weirdness.
Long story short, dispose of your video players with the above sequence to avoid issues with later movie players.

How would I play songs or make a splash screen for my cocoa app?

How would I play songs or make a splash screen for my cocoa app? I know it's a simple question but I am a complete noob when it comes to cocoa.
You want to create an application delegate class and implement the -applicationWillFinishLaunching and -applicationDidFinishLaunching methods to display/hide your splash screen or start/stop your audio. You can connect an instance of this class as the application's delegate in Interface Builder in the project's MainMenu.xib.
Keep in mind that it's generally considered bad form to have to display a splash/load screen in Mac apps. If your app can start instantly and lazily load resources or load them in a background thread, it provides a much nicer experience for your users.
Barry is right, you have to get rid of this idea to use splash screens.. it's mainly a M$ Windows concept and it is kind of frustrating for the user to wait for the app to load itself, and I bet you won't load a thing and you just want to show a splash screen so you can feel important, but I'm telling you: apps with "marketing-only" splash screens are trash right from the beginning, because the user waits for absolutely nothing to load, and he/she will immediatelly get sick of seeing it every single time the app starts..
Now, about the songs.. I'll help you on this one, but I'm telling you again: it's useless, can't see the usefullness in having a sound play on every startup... so putting sound and a splash screen to your app startup will scare most users away, and your app won't made it!
So, to load a song you use the NSSound class like this:
NSSound *s = [[NSSound alloc] initWithContentsOfFile:songPath byReference:YES];
and then you can control it with the following methods:
[s play]
[s pause]
[s resume]
[s stop]