1

I've done a bit of Swift and a fair amount of Objective-C on iOS, but basically no real OS X programming, so I haven't used NSSound. I was trying to help someone on a Swift forum, and ... it's not working. I'm not sure why.

In a playground, Swift REPL or even a script (#!/usr/bin/env swift), I can instantiate an NSSound successfully:

NSSound(named:"Hero")

In REPL / Playground or printing from the script, I can see that the optional has an NSSound inside. But when I call play(), I don't hear anything:

NSSound(named:"Hero")!.play()

Why?

This is a very small piece of code, it seems pretty simple, but obviously I'm missing something. It's not a big deal because it's not code that I need, but it's bugging me because it seems so simple and yet it's not working.

Geoffrey Wiseman
  • 5,459
  • 3
  • 34
  • 52
  • 1
    Why don't you test your sound in a real project? Playground it is not meant to test UI. Your code should work but you should prefer using it like this `NSSound(named:"Hero")?.play()` so you don't force unwrap your sound – Leo Dabus Jan 22 '16 at 02:41
  • Yeah, I thought about that -- that's why I tried the REPL and script too. NSSound isn't truly UI, but maybe it doesn't work in any of those environments? – Geoffrey Wiseman Jan 22 '16 at 02:43

2 Answers2

2

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()
}
Jim Correia
  • 7,064
  • 1
  • 33
  • 24
  • Ah, great -- that explanation seems more reasonable than "doesn't work and doesn't complain", and sure enough, I can hear the NSSound if I do that. – Geoffrey Wiseman Jan 22 '16 at 13:25
1

It seems as if NSSound, being a cocoa class, doesn't work properly in any of the environments I had tested:

  • Playground
  • Swift Script
  • Swift REPL

If I put the same tiny piece of code in a skeleton OS X app, works fine.

Thanks to @Leo for pushing me to actually try it. I'd considered the possibility, but hadn't tried it until he suggested it.

Geoffrey Wiseman
  • 5,459
  • 3
  • 34
  • 52