I have an app where I play a system sound to indicate to the user that they can begin recording. I currently use the code below.
AudioServicesPlaySystemSoundWithCompletion(1117) {
DispatchQueue.main.async {
self.setupRecordingViews()
}
// beging recording
}
However the user could cancel wanting to record something once this function has begun and I need to a way to be able to cancel it in order to stop my UI changing to begin recording.
Any ideas how I could do this using a system sound? is there a way I can add an observer or delegate?
I'm not sure if I completely understand the issue, but just before you call setupRecordingViews() could you check a self.didCancel flag?
In your handler for whatever cancel button you have you would just set that:
self.didCancel = true
Related
I am trying to build an Audio Player App! I can not figure out, how I can get my app responsible to Play/Pause forward/backward volume up/down button tap or click from any headphone or headset!
I found this page from apple! but it is not understandable for me! I like to have an example code!
Link: https://developer.apple.com/documentation/mediaplayer/mpremotecommand
Assuming that you already have the class that will handle the media playback the rest is rather easy.
As mentioned in the link you provided, any event related to media is sent for the apps that are listening it doesn't matter where the event comes from (control center, headset...) that part is handled by the Media Player Framework
On the class you need to grab the command center of the MPF (Media player framework) and set the functions that will be triggered by the events, I will only show the one in the link you provided.
class MediaPlayer {
let commandCenter = MPRemoteCommandCenter.shared()
init() {
// this is for the play command, check the docs for more commands
commandCenter.playCommand.addTarget { [unowned self] event in
if self.player.rate == 0.0 { // <- is stopped?
// do your stuff and say to the OS that everything worked
return .success
}
// if the command does not run properly you must inform the OS
return .commandFailed
}
}
}
There's some missing code that depends on your implementation, but what you want is here, now when something triggers the "play" command your app will detect it and if the player is not reproducing any media it will start.
You can see on the docs more info about the MPRemoteCommandCenter and for more commands, that follow the same pattern.
I want my app to have the ability to run my pause function when the user clicks home. When I exit the app, it pauses, but then runs the view did load function when I enter the app again. Does anyone know how to have the view did load function only run the first time the view loads before it is termitated?
Here is my pause function:
func pauseGame322() {
ThreeTime = 3
CountdownUntillGameLabel.text = String(ThreeTime)
if PlayButton.isHidden == true &&
ContinueButton.isHidden == true{
timer.invalidate()
timer10.invalidate()
TotalSecondsForPause.isHidden = false
PauseView.isHidden = false
UnpauseButton.isHidden = false
TotalSecondsForPause.text = String(time)
}
}
Call your pause function from applicationWillResignActive(_:) in the App Delegate (emphasis mine):
You should use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. An app in the inactive state should do minimal work while it waits to transition to either the active or background state.
If you need access to the current view controller, follow this question. But updating the UI here is pointless. Your app is about to enter the background, the users won't see any UI changes. You display the pause menu when the user comes back, in applicationWillBecomeActive(_:).
You cannot limit the call of viewDidLoad. Every time the ViewController will be initialised, viewDidLoad will be called. To handle such scenario, what you can do is, put your code in a separate method, and call that method from viewDidLoad after performing the check for first time. To know that this is the first time or not, you can simply put a flag variable in UserDefaults.
Further, when you say 'User Exists', it may have different meanings. Did you mean that user kills the app, or you mean that user puts the app in background? For the first case, you should put the check for first time in applicationDidFinishLaunching method, while for the second case (i.e. background), call the pause function from applicationWillEnterBackground, and play from applicationDidEnterForeground.
Try using the application's life cycle methods in more efficient way.
I'm working on an app and I need it to take input from two solid buttons connected from the earphone jack. I need the app to count how much time it take to finish pressing the button 10 times. I have the timer working now but I can't figure out how to make it take the input. Also, if I have this figured out, is there a way to stimulate? Can you guys give me a hand, please?
remoteControlReceivedWithEvent is used get the audio controls (play/pause), probably it's same as your audio jack device. You need to enable your application with Background audio capability and should add code to start audio session for your app so that you can get call backs when any button pressed in headphones to the function
try this:
override func remoteControlReceivedWithEvent(event: UIEvent?) {
let rc = event!.subtype
print("does this work? \(rc.rawValue)")
}
My problem is having several buttons in flash that play sounds when clicked, and I want only one button/sound to be active at a time. Problem is that if the mouse button is released outside of the flash window the last button's sound keeps sounding til the end, and if another button is pressed in the meantime it too starts sounding simultaneously, and so on.
So I thought of checking if the SoundChannel assigned to any other button than the currently pressed one is playing, and if so, stop that SoundChannel to only let the current button's SoundChannel play.
But if this Actionscript SoundChannel is a single object for all the buttons, this won't work, and then I don't see a solution to preventing multiple sounds sounding simultaneously other than adding a 'warning' box, which seems redundant and ineffective. So can you have a separate SoundChannel for each button or object in a flash movie, otherwise how can I bulletproof this so that only one button sound can sound at once no matter where the mouse is released, inside as or outside of the flash window?
Can you put the buttons in a container and addEventListener for MouseEvent.MOUSE_UP and in the handler to check if it cursor is outside the container like so:
private static function onMouseDownOutside(event:MouseEvent) : void {
var mouseDownInsideComponent : Boolean = false;
mouseDownInsideComponent = yourContainer.hitTestPoint(event.stageX, event.stageY, false);
if (!mouseDownInsideComponent) {
//stop the sound
}
}
and just to stop the sound when it gets out of the container? Seems like a possible workaround.
I'm building a game for iOS using Cocos2D. In my game I have a pause menu that can be pulled up when playing the game. A simple tap will return from the pause menu to the game. What I would like to implement is a clean way to resume the game on the pause menu if the method applicationDidBecomeActive is called. The problem is that only the appDelegate receives the call to applicationDidBecomeActive, and my pause menu is many layers deeper than that. Right now I'm essentially passing the applicationDidBecomeActive call through about 4 different layers to get it down to the pause menu. There must be a cleaner way?
Sure is. Just add an observer for the UIApplicationDidBecomeActiveNotification from anywhere that's convenient. Application state changes can be hooked that way as well as via the app's delegate.
(Docs here.)
Read about the NSNotificationCenter
here and at Apple or just receive the UIApplicationDidBecomeActiveNotification anywhere.
take a BOOL variable in appdelegate.h with property and synthesised it then when pause button pressed from any scene set this variable to yes.
in applicationDidBecomeActive method of appdelegate check if(self.pause == YES) then don't resume ccdirector else resume it
i used this in my game and it work fine when i press pause and then press home button and when come back the app is still pause. try this