RemoteControlReceivedWithEvent in iOS 7 issue - iphone

I am having a hard time trying to figure out why in iOS 7 the remote controls don't work. In iOS 7, in the lock screen or even in the Control Center, the buttons are unresponsive and the funny thing is that it works fine on iOS 6.
Here is the code I use:
- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
if (receivedEvent.type == UIEventTypeRemoteControl) {
switch (receivedEvent.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
if (player.playbackState == MPMusicPlaybackStatePlaying) {
[player pause];
}
else {
[player play];
}
break;
case UIEventSubtypeRemoteControlPreviousTrack:
break;
case UIEventSubtypeRemoteControlNextTrack:
break;
default:
break;
}
}}
This is where I found the information about how to perform this:
https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/Remote-ControlEvents/Remote-ControlEvents.html
Any ideas why this is happening? It works on iOS 6 but not iOS 7.
Thanks

I ran into this same problem and I ended up removing the case statement UIEventSubtypeRemoteControlTogglePlayPause and added case statements UIEventSubtypeRemoteControlPlay and UIEventSubtypeRemoteControlPause individually. I don't have an good explanation for why this changed.
*UPDATE*
I found that UIEventSubtypeRemoteControlTogglePlayPause is called when the user is using their headset to control the player. Just a FYI.

I think its a better solution:
case UIEventSubtypeRemoteControlTogglePlayPause:
case UIEventSubtypeRemoteControlPlay:
case UIEventSubtypeRemoteControlPause:
if (_paused) {
[self play:self];
} else {
[self pause:self];
}
break;

Related

UILongPressGestureRecognizer is not working

I am trying to create an app where UIButtons can be draged and dropped when a UILongPressGestureRecognizer gesture is fired. Actually my app is working fine in any iPad. it creates problem in iPhone only and lower than iOS 5.0 menas its work fine in iPhone with iOS 5.0.
UILongPressGestureRecognizer * gesture = [[UILongPressGestureRecognizer alloc] initWithTarget: self action: #selector(moveActionGestureRecognizerStateChanged:)];
gesture.minimumPressDuration = 0.5;
gesture.delegate = self;
[self.dragView addGestureRecognizer: gesture];
[gesture release];
- (void) moveActionGestureRecognizerStateChanged: (UILongPressGestureRecognizer *) recognizer
{
switch ( recognizer.state )
{
default:
case UIGestureRecognizerStateFailed:
{
dragView.alpha=1.0;
[dragView release];
dragView=nil;
break;
}
case UIGestureRecognizerStatePossible:
{
dragView.alpha=0.8;
dragView.frame=CGRectMake(dragView.frame.origin.x, dragView.frame.origin.y, dragView.frame.size.width, dragView.frame.size.height);
}
case UIGestureRecognizerStateCancelled:
{
dragView.alpha=1.0;
[dragView release];
dragView=nil;
break;
}
case UIGestureRecognizerStateEnded:
{
//Set dragView on target position
break;
}
case UIGestureRecognizerStateBegan:
{
//NSLog(#"Began");
dragView.alpha=0.8;
dragView.frame=CGRectMake(dragView.frame.origin.x, dragView.frame.origin.y, dragView.frame.size.width, dragView.frame.size.height);
[self bringSubviewToFront:dragView];
break;
}
case UIGestureRecognizerStateChanged:
{
[self.view bringSubviewToFront:dragView];
CGPoint offset = [recognizer locationInView: self.scrollView];
dragView.frame=CGRectMake(offset.x, offset.y, dragView.frame.size.width, dragView.frame.size.height);
}
break;
}
}
I have 2 devices iPhone 3G with iOS 4.2.1 and iPhone 4 with 5.0. This functionality is working fine in iPhone 4 with iOS 5.0 but its not working properly in iPhone 3g with iOS 4.2.1. Sometimes it working in iPhone 3g but sometimes its not calling delegate methods.
Let me know if you have any solution for that.
Thanks!
Is the delegate method not called at all, or is no case selected? I don't know if this really solves your problem, but you should fix your switch (take a loot at the default case):
switch ( recognizer.state )
{
case someCase:
{
// ...
break;
}
default:
break;
}

Background Audio - Image on Lock Screen

There is a way to add an image to the lock screen for Background Audio, along with setting the Track and Artist name. It was also mentioned in a WWDC 2011 video, but nothing specific to go off of. I have looked everywhere in the docs and cannot find it. I know it is an iOS5 only thing, and Spotify's newest version has this feature. Does anyone know where they can point me in the right direction?
Thank You,
Matthew
Here's an answer I found for you:
(1) You must handle remote control events. You can't be the Now
Playing app unless you do. (See the AudioMixer (MixerHost) sample) code.)
(2) Set the Now Playing info:
MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter];
infoCenter.nowPlayingInfo =
[NSDictionary dictionaryWithObjectsAndKeys:#"my title", MPMediaItemPropertyTitle,
#"my artist", MPMediaItemPropertyArtist,
nil];
This is independent of whichever API you are using to play audio or
video.
as per Michaels answer above, simply append
#{MPMediaItemPropertyArtwork: [[MPMediaItemArtwork alloc] initWithImage:[UIImage ...]]}
to the nowPlayingInfo dict
the full options of available keys are ...
// MPMediaItemPropertyAlbumTitle
// MPMediaItemPropertyAlbumTrackCount
// MPMediaItemPropertyAlbumTrackNumber
// MPMediaItemPropertyArtist
// MPMediaItemPropertyArtwork
// MPMediaItemPropertyComposer
// MPMediaItemPropertyDiscCount
// MPMediaItemPropertyDiscNumber
// MPMediaItemPropertyGenre
// MPMediaItemPropertyPersistentID
// MPMediaItemPropertyPlaybackDuration
// MPMediaItemPropertyTitle
To make controls work....
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void)viewWillDisappear:(BOOL)animated {
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
[super viewWillDisappear:animated];
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
if (receivedEvent.type == UIEventTypeRemoteControl) {
switch (receivedEvent.subtype) {
case UIEventSubtypeRemoteControlPlay:
[player play];
break;
case UIEventSubtypeRemoteControlPause:
[player pause];
break;
case UIEventSubtypeRemoteControlTogglePlayPause:
if (player.playbackState == MPMoviePlaybackStatePlaying) {
[player pause];
}
else {
[player play];
}
break;
default:
break;
}
}
}
It only works on a real iOS Device, not on the simulator

On shake... iOS

So I have an IBAction yesNo that I want to be ran on a shake event. Not all too sure why this is not working. Have followed all the documentation.
-(BOOL)canBecomeFirstResponder
{
return YES;
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if (event.subtype == UIEventSubtypeMotionShake)
{
[self yesNo];
}
}
And then the IBAction itself:
- (IBAction)yesNo
{
int rNumber = rand() % 26;
NSUserDefaults *def=[NSUserDefaults standardUserDefaults];
if ([[def objectForKey:#"activeVersion"] isEqualToString:#"0"])
{
switch (rNumber) {
case 0:
result.text = #"Never";
break;
case 1:
result.text = #"If you're lucky...";
break;
case 3:
result.text = #"Think twice";
break;
...
default:
break;
}
}
else if ([[def objectForKey:#"activeVersion"] isEqualToString:#"1"])
{
switch (rNumber) {
case 0:
result.text = #"Never1";
break;
case 1:
result.text = #"If you're lucky...1";
break;
...
case 25:
result.text = #"Very doubtful2";
break;
default:
break;
}
}
else if ([[def objectForKey:#"activeVersion"] isEqualToString:#"3"])
{
switch (rNumber) {
case 0:
result.text = #"Never3";
break;
...
case 25:
result.text = #"Very doubtful3";
break;
default:
break;
}
}
}
Basically what I have is a fortune ball type thing and when the iPhone is shaken I need that IBAction run.
Have you made that view the first responder? I.e. [yourView becomeFirstResponder]; (probably from some viewDidAppear: method).
You might want to check if it actually is the first responder when you shake your device.
When I was switching from defining everything graphically in IB to programmatically inline in Xcode, I forgot to make the view the first responder at all. Here's the code that ultimately fixed it:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self becomeFirstResponder];
NSLog(#"self is first responder %i",[self isFirstResponder]);
}
First thing I would question is whether this should be defined as an IBAction. If you only call it from code then you might want to consider using (void) instead (Simply a style choice).
Secondly, are you sure that the method is actually being called? Throw an NSLog in there to make sure.
Thirdly, are you sure that [def objectForKey:#"activeVersion"] returns a string? Is the value returned what you would expect? Throw an NSLog in there to make sure.
My guess is that one of the NSLogs will give you the answer to your question as the rest of your code seems fine.

iOS: How to get my audio app to register in the multitask controls?

When a user double clicks the home button and swipe right, some audio controls shows.
How do I get use them?
I've searched but havn't found anything that helps me.
Try this
- (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
switch (receivedEvent.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
[self playTapped];
break;
case UIEventSubtypeRemoteControlPreviousTrack:
[self previousTapped];
break;
case UIEventSubtypeRemoteControlNextTrack:
[self nextTapped];
break;
default:
break;
}
PlayTapped is the method for playing the music.
nextTapped is the method for the next song to be played.
previousTapped is for playing the previous track.
All the best

NSLog InterfaceRotation doesn't work on simulator?

I want to know why thereĀ“s no console output when testing on the iOS simulator by tracing that code in my UIViewController - it only traces by testing on a device.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
NSLog(#"willRotateToInterfaceOrientation: ", toInterfaceOrientation);
}
And how do i print out that UIInterfaceOrientation value (type of enum)?
Would be great to get your help on that..Thanks
Where is your format specifier?
UIInterfaceOrientation is a typedef enum, not an object, so you cannot use %# as the format specifier.
Should look like this:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
NSLog(#"willRotateToInterfaceOrientation: %d", toInterfaceOrientation);
}
If you really need this kind of "pretty print" functionality, you can run it through a switch, like this:
NSString *orient;
switch(toInterfaceOrientation) {
case UIInterfaceOrientationLandscapeRight:
orient = #"UIInterfaceOrientationLandscapeRight";
break;
case UIInterfaceOrientationLandscapeLeft:
orient = #"UIInterfaceOrientationLandscapeLeft";
break;
case UIInterfaceOrientationPortrait:
orient = #"UIInterfaceOrientationPortrait";
break;
case UIInterfaceOrientationPortraitUpsideDown:
orient = #"UIInterfaceOrientationPortraitUpsideDown";
break;
default:
orient = #"Invalid orientation";
}
NSLog(#"willRotateToInterfaceOrientation: %#", orient);