Handle IOS app open from tapping on Now Playing - ios

I'm using SwiftAudio to play audio, I want to detect when audio playing in background mode and app become active from tapping on Now Playing.
NotificationCenter
.default
.addObserver(self, selector: #selector(applicationDidBecomeActive),
name: UIApplication.didBecomeActiveNotification,
object: nil)
#objc func applicationDidBecomeActive() {
print("applicationDidBecomeActive")
}
right now I'm trying this way but it trigger applicationDidBecomeActive even when user open app from icon.
If there any other ways to know when user tapping on Now Playing, please let me know.
I'm very new to IOS development and Swift
Edit: I guess I can detect how app is entered foreground from NowPlaying by passing the expected objectsender to addObserver instead of passing nil object. I tried many times but still don't know what sender object it it.

You should look into MPNowPlayingInfoCenter
When your app is active again, you can check the nowPlayingInfo and playbackState to customise what you actually want to do in your app.
What is the difference between launching from Notification or Now Playing in your case? Maybe clarifying this a bit more will allow us to craft a better solution to your problem.

Related

IOS Monitor audio route changes in background

Is it possible to monitor changes to the Audio route without playing music? I have found this question, but it seems to rely on audio being played.
My current setup looks something like this:
NotificationCenter.default.addObserver(self, selector: #selector(routeChange), name: .AVAudioSessionRouteChange, object: nil)
#objc
func routeChange(n: Notification) {
...
}
The background mode "Audio, AirPlay and Picture in Picture" is enabled.
My setup seems to work fine as long as the app is in foreground. As soon as it is in the background, routeChange will not be called anymore.

Detect when app is closed, terminated but ignore when the phone is turned off

I want to know when someone closes my app (taps the home button) or terminates my app (double tap swipe up) however I do not want to know when the user is using my app and simply turns their phone off because when they turn their phone back on it will still be on my app.
I have tried using the applicationWillResignActive, applicationDidEnterBackground, applicationWillTerminate and registering it in my view controller
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)
These either didn't tell me when my app wasn't the focus or if they did work they also told me when my app was still open just the phone was closed.
You cannot draw the distinction you are asking to draw. Whether the user clicks the Home button or turns off the screen, your app is deactivated and backgrounded and you are told so — and that is all you are told.
However, you do not need to draw this distinction. When your app is backgrounded, just do whatever is appropriate. You’ll be told when your app is foregrounded again, even if that is just because the user turned the screen back on.
So after some research the only possible way I found was:
func DidUserPressLockButton() -> Bool
{
let oldBrightness = UIScreen.main.brightness
UIScreen.main.brightness = oldBrightness + (oldBrightness <= 0.01 ? (0.01) : (-0.01))
return oldBrightness != UIScreen.main.brightness
}
func applicationDidEnterBackground(_ application: UIApplication)
{
if (DidUserPressLockButton())
{
//User pressed lock button
}
else
{
//user pressed home button
}}
This method works by seeing if the app can change the brightness however some say this will get rejected by apple because they don't want you to do which makes sense why there isn't a built in function for it however there are apps on the App Store that know how you left the app so there you go

How to prevent SpriteKit game from crashing when Notification Center is opened

I am having a weird issue with a SpriteKit game. The app crashes when a user opens Notification center or Control Center. I want the worldNode layer to be paused and the menuNode layer to be presented when the applicationWillResignActive is called, which is working fine when the home button is pressed. I've tried pausing my game from within the AppDelegate functions applicationWillResignActive and I've tried pausing when applicationDidBecomeActive is called if the game has started. I've tried using the NotificationCenter approach from within the ViewController both work when the Home Button/Home Gesture is used. How Should I handle this? Or is this just a bug in iOS 11?
I have this in the viewDidLoad method of my ViewController
NotificationCenter.default.addObserver(self, selector: #selector(appWillResignActive), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
Then each one of those selectors
It crashes on both if trying to present the menu when the appDidBecomeActive and appWillResignActive
#objc func appDidBecomeActive() {
print("appDidBecomeActive")
if GameScene.sharedInstance != nil {
print("presentingMenu")
GameScene.sharedInstance.presentMenuNode()
}
}
#objc func appWillResignActive() {
print("appWillResignActive")
if GameScene.sharedInstance != nil {
print("presentingMenu")
GameScene.sharedInstance.presentMenuNode()
}
}
I feel like I may be trying to approach this the wrong way, but what I don't understand is why does it work when the Home button/Home gesture is fired?
Edit:
After more testing I found that everything works as expected when running on iOS 10 devices. However when I run the DemoBots app that apple provides from their sample code it doesn't crash on iOS 11 and basically does what I want to do, so there has got to be a better way to handle the transitions of the game state, any input is appreciated.

How can I tell when the device screen is locked?

Is there anyway I can know if a user has locked the screen or not? I have two AVPlayers playing music, but I only want one of them to be able to play in the background. If I hooked up the lock screen to call a method, I could stop the AVPlayer before it plays in the background. Any direction would be much appreciated.
When the device is locked, -(void)applicationWillResignActive is called
followed by -(void)applicationDidEnterBackground.
Write your code in the second method.
When the screen is being locked, applicationDidEnterBackground will be called.
You can do your work there :)
So I tried both suggestions of -(void)applicationWillResignActive and -(void)applicationDidEnterBackground, and it may work for you but for some reason it didn't even trigger my NSLogs in the console when i locked the screen. What would Trigger however is if I used NSNotifcationCenter.
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleEnteredBackground)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
and then put the code I needed to run inside the selector.
-(void)handleEnteredBackground{
NSLog(#"This Shows inside the Console!");
}
I don't know if this is the best way to handle things, but it works for me, and might work for anyone else with the same issue, it is triggered by BOTH the Lock Screen Button and the Home Button on my iphone currently running iOS 7.0.4 which is just what I needed.

Cancel a push notification sound while it is playing

Tried to find this already but can't find any questions which are asking quite the same thing.
Basically I have set up my push notifications, everything works fine and they are received both when the app is open and closed. However, the push noise we are using is quite long and I'm not sure if it's possible to cancel the sound once they press the "ok" button on the alert.
I have tried to utilise the mute toggle switch, but this only seems to come into play at the moment that sound starts to play, if it's off the sound plays, if it's on then it doesn't. If I toggle the switch mid-sound it has no effect. However, if I just play a regular sound clip in my app (not a push notification sound) and use the toggle switch then the sound stops/starts as you would expect.
Is there a way to cancel the sound? Or is it treated differently as a system sound of some kind?
Edit: I've been trying to work this out myself for the last few days, and I'm coming to the conclusion that there is no way to cancel the push alert sound mid-sound. Can anyone confirm that this is definitely the case?
Edit2: For some reason the xcode tag has been removed - with the reason being that it is nothing to do with xcode. I feel maybe my issue was not clear - I AM using xcode to build the app, and I am looking for a way to programatically control whether the push notification sound is heard or not. Thanks.
No answers given, having tried and failed over the last few months I can only assume this is not possible (just in case anyone has the same issue in the future).
It works for me:
[[UIApplication sharedApplication] cancelAllLocalNotifications]
As of iOS 10, you can remove all notifications from Notification Center by calling
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
The audio stops playing and all the notifications are removed from Notification Center.
Alternatively, to stop the sound for only a specific notification, you can use:
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [String])
This stops the audio for only the given notifications, and removes them from Notification Center.
To get the ids for all the delivered notifications, use
UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
let ids = notifications.map { $0.request.identifier }
}

Resources