How to control AVAudioPlayer using earPods remote control? - swift

I'm using AVAudioPlayer to play music
I want to control playing from remote controls which are part of using headphones.
I've already this:
override func remoteControlReceivedWithEvent(event: UIEvent?) {
let rc = event!.subtype
print(rc.rawValue)
//rc.rawValue: 101 = pause, 100 = play
switch rc {
case .RemoteControlPlay:
playButtonClicked("")
case .RemoteControlPause:
pauseButtonClicked("")
default:break
}
}
It's working great from this menu
But clicks on headphones are ignored. How can I fix it?

I believe that the headphones send the TogglePlayPauseCommand event:
https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPRemoteCommandCenter_Ref/index.html#//apple_ref/occ/instp/MPRemoteCommandCenter/togglePlayPauseCommand
Because I see you're using Xamarin, RemoteControlTogglePlayPause should be of interest
https://developer.xamarin.com/api/type/MonoTouch.UIKit.UIEventSubtype/

Related

Game Center Turn Timeout for Multiplayer GAmes

I have created a turn based multiplayer board game using Swift and Game Center that works pretty well. One of the last items I would like to add is a way to keep a player from abandoning a game near the end if they know they are going to lose. It seems like the turnTimeout portion of the endTurn function is built in especially for this purpose, but I cannot get it to work. My endTurn function is below:
func endTurn(_ model: GameModel, completion: #escaping CompletionBlock) {
guard let match = currentMatch else {
completion(GameCenterHelperError.matchNotFound)
return
}
do {
let currenParticipantIndex: Int = (match.participants.firstIndex(of: match.currentParticipant!))!
let nextPerson = [match.participants[(currenParticipantIndex+1) % match.participants.count]]
print("end turn, next participant \(String(describing: nextPerson[0].player?.alias))")
match.endTurn(
withNextParticipants: nextPerson,
turnTimeout: 15,
match: try JSONEncoder().encode(model),
completionHandler: completion
)
} catch {completion(error)}
}
This function takes into account the advice from Anton in the comment of the answer to this question:
Trying to set a time limit on my Game Center game
to update the array of nextParticipant players so that the end of the array is never reached. I've also tried to account for this in my testing by having both player 1 and player 2 delay the end of their turn to see if it would fire (The game is a 2 player game only)
This should also answer this question:
Game Center turn timeouts
The documentation says:
timeoutDate: The time at which the player must act before forfeiting a turn. Your game decides what happens when a turn is forfeited. For some games, a forfeited turn might end the match. For other games, you might choose a reasonable set of default actions for the player, or simply do nothing.
https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/GameKit_Guide/ImplementingaTurn-BasedMatch/ImplementingaTurn-BasedMatch.html
Unfortunately I am unable to get the turnTimeout function to fire at all. I have done a fair amount of research and I found no definitive answer to what function is actually called when it fires (i.e. the player takes longer than the allotted time to take their turn). I would expect that the same function is called for a timeout as a regular call of the endTurn function and the below player listener is called:
func player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch, didBecomeActive: Bool) {
if let vc = currentMatchmakerVC {
currentMatchmakerVC = nil
vc.dismiss(animated: true)
}
print("received turn event")
if !didBecomeActive {
print("\n\n\n player listener did become active")
print("match did change")
NotificationCenter.default.post(name: .matchDidChange, object: match)
} else if didBecomeActive {
print("present game")
NotificationCenter.default.post(name: .presentGame, object: match)
}
}
I am able to get the player listener (received turn event) to fire when endTurn is specifically called from the game, but I do not see anything that is called when the turnTimeout event triggers. If it was the player listener I would see the print statements in the console as well as the notification on the next player's device.
The GKTurnTimeoutDefault is 604,800 and is a Time Interval which I did some research on and arrived at the conclusion that it is in seconds, which is 7 days. I changed it to 0.00001, 15, 2000 and a few values in between but I wasn't able to get it to fire.
I also found the below, but the first has no answer and the second only says the turn timeouts probably warrants its own full answer:
Game Center Turnbased Game turn timeout
How to detect when Game Center turn based match has ended in iOS9?
I am thinking that my mistake is probably that I am unable to find the function that is called when the turn timeout fires, although I might be mistaken on the Time Interval values that I'm putting in there as well.
Thank you for taking the time to review my question :)

If the user is using their mouse left-handed, are .leftMouseDown and .rightMouseDown swapped?

I want to know that the system handles this for me. I really hope it does.
If the user is left-handed, and so the left and right mouse buttons' meanings are swapped, then do all NSEvent things related to these two buttons also swap?
For an in-code example, I want to know if this is left-handed-user-friendly:
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
performPrimaryEvent()
}
override func rightMouseDown(with event: NSEvent) {
super.rightMouseDown(with: event)
performSecondaryEvent()
}
The official documentation says nothing and Google searches are futile...
I plugged in a mouse just to test this. It turns out the answer is yes! All these values and callbacks are automatically flipped.

AKPanner node not affecting output

I've been struggling with this for a while now.
I've got an array of AKPlayers.
var players = [AKPlayer]()
Then I create an AKPanner node, set the pan, and connect it into the input of an AKMixer
let playerNode = AKPlayer(audioFile: c.audioFile!)
playerNode.pan = 0
var pannerNode = AKPanner(playerNode, pan: 1)
self.audioMixer.connect(input: pannerNode)
players.append(playerNode)
panners.append(pannerNode)
I also throw the nodes into an array due to this
Then I do the following:
do {
AudioKit.output = audioMixer
try AudioKit.start()
} catch {
print(error.localizedDescription)
}
I am able to hear sound, but it is in both ears. Not in my right ear.
Any help would be greatly appreciated. Thank you.
My problem was not with the code at all, but rather, with a setting on my phone.
Make sure that Mono Audio is turned off in the iOS settings under:
General > Accessibility > Mono Audio
**Note: Mono Audio is under the Hearing section

corona sdk iphone 4s 5.1.1 no sound

I don't have sound in apps on iphone 4s 5.1.1
tested my app + 2 (unmodified)examples from sample code
even when i send notifications - i get vibration (if with sound) - without sound i don't get vibration but in both cases sound does not play. not it notification not in app
Help!
I tried using ggmusic and ggsound libs by Glitched Games. Both of witch implement the new audio api.
here is some code so i meet the QUALITY STANDARTS
local supportedAudio = {
["Simulator"] = { extensions = { ".aac", ".aif", ".caf", ".wav", ".mp3", ".ogg" } },
["IOS"] = { extensions = { ".aac", ".aif", ".caf", ".wav", ".mp3" } },
["Android"] = { extensions = { ".wav", ".mp3", ".ogg" } },
}
Ok guyz, the thing is - you should check that switch on the right side that turns off sounds. Your media playback will play via loudspeker, but sounds dont. Turn sounds on and it fixes it.
Lame apple user I am.
Cheers!

how to run vibrate continuously in iphone?

In my application I'm using following coding pattern to vibrate my iPhone device
Include: AudioToolbox framework
Header File:
#import "AudioToolbox/AudioServices.h"
Code:
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
My problem is that when I run my application it gets vibrate but only for second but I want that it will vibrate continuously until I will stop it.
How could it be possible?
Thankfully, it's not possible to change the duration of the vibration. The only way to trigger the vibration is to play the kSystemSoundID_Vibrate as you have. If you really want to though, what you can do is to repeat the vibration indefinitely, resulting in a pulsing vibration effect instead of a long continuous one. To do this, you need to register a callback function that will get called when the vibration sound that you play is complete:
AudioServicesAddSystemSoundCompletion (
kSystemSoundID_Vibrate,
NULL,
NULL,
MyAudioServicesSystemSoundCompletionProc,
NULL
);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Then you define your callback function to replay the vibrate sound again:
#pragma mark AudioService callback function prototypes
void MyAudioServicesSystemSoundCompletionProc (
SystemSoundID ssID,
void *clientData
);
#pragma mark AudioService callback function implementation
// Callback that gets called after we finish buzzing, so we
// can buzz a second time.
void MyAudioServicesSystemSoundCompletionProc (
SystemSoundID ssID,
void *clientData
) {
if (iShouldKeepBuzzing) { // Your logic here...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
} else {
//Unregister, so we don't get called again...
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
}
}
There are numerous examples that show how to do this with a private CoreTelephony call: _CTServerConnectionSetVibratorState, but it's really not a sensible course of action since your app will get rejected for abusing the vibrate feature like that. Just don't do it.
Read the Apple Human Interaction Guidelines for iPhone. I believe this is not approved behavior in an app.
iOS 5 has implemented Custom Vibrations mode. So in some cases variable vibration is acceptable. The only thing is unknown what library deals with that (pretty sure not CoreTelephony) and if it is open for developers. So keep on searching.
The above answers are good and you can do it in a simple way also.
You can use the recursive method calls.
func vibrateTheDeviceContinuously() throws {
// Added concurrent queue for next & Vibrate device
DispatchQueue.global(qos: .utility).async {
//Vibrate the device
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
self.incrementalCount += 1
usleep(800000) // if you don't want pause in between, remove this line.
do {
if let isKeepBuzzing = self.iShouldKeepBuzzing , isKeepBuzzing == true {
try self.vibrateTheDeviceContinuously()
}
else {
return
}
} catch {
//Exception handle
print("exception")
}
}
}
To stop the device vibration use the following line.
self.iShouldKeepBuzzing = false
ios swift