Play musical notes in Swift Playground
You have to enable the asynchronous mode for the Playground.
Add this at the top (Xcode 7, Swift 2):
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
and your sequence will play.
The same for Xcode 8 (Swift 3):
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
Creating and playing a sound in swift
Here's a bit of code I've got added to FlappySwift that works:
import SpriteKit
import AVFoundation
class GameScene: SKScene {
// Grab the path, make sure to add it to your project!
var coinSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "coin", ofType: "wav")!)
var audioPlayer = AVAudioPlayer()
// Initial setup
override func didMoveToView(view: SKView) {
audioPlayer = AVAudioPlayer(contentsOfURL: coinSound, error: nil)
audioPlayer.prepareToPlay()
}
// Trigger the sound effect when the player grabs the coin
func didBeginContact(contact: SKPhysicsContact!) {
audioPlayer.play()
}
}
Swift NSSound plays silently?
NSSound plays its sound asynchronously. By default, a playground exits immediately after executing the its code, so the process terminates before the sound has had a chance to play.
Here's a quick and dirty way to keep the playground alive indefinitely so that you can hear the sound play.
import Cocoa
import XCPlayground
if let sound = NSSound(named:"Hero") {
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
sound.play()
}
How to call function when song finished in a Swift Playground
Set your winPlayer
delegate as,
winPlayer?.delegate = self
and implement the method
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
if flag == true {
// song finished successfully here
}
}
where you will place the delegate is up to you.
SingletonMusicPlayer playing overitself
I think you ran into a form of readers-writers problem here by attempting to simultaneously manipulate instance variables on your singleton from different threads. I don't know what your desired music player behavior is if it's being called from multiple threads at once, but for me one easy improvement would be to give your MusicPlayerManager
singleton it's own DispatchQueue
, where multiple overlapping requests can be handled sequentially.
You could define one like this:
let concurrentQueue = DispatchQueue(label: "com.stackoverflow.gamma", attributes: .concurrent)
And then wrap the code inside the playNotes
function like this:
func playNotes(notes: [UInt8]) {
self.concurrentQueue.async(flags: .barrier) {
...
}
}
Related Topics
System Volume Change Observer Not Working on iOS 15
Use of Undeclared Type 'Attributedstring'
Core Data Predicate Not Working
Save & Retrieve Tableviewcell Checkmark Using Nsuserdefaults in Swift
Swift: Providing a Default Protocol Implementation in a Protocol Extension
How to Cast an Any Value with Nil in It to a Any
Get Bogus Value When Execute Break Point in a Variable
Appearance Proxies/Ui_Appearance_Selector in Swift
Declaring and Using Custom Attributes in Swift
Waiting for Alamofire in Unit Tests
For-In Loop and Type Casting Only for Objects Which Match Type
Physicsbody: Could Not Create Physics Body
How to Say "If X == a or B or C" as Succinctly in Swift as Possible
What's the Best Way to Iterate Over Results from an API, and Know When It's Finished