I am able to play a sound in swift with NSSound:
var path ="/path/to/file.mp3"
mysound = NSSound(contentsOfFile: path, byReference: false)
mysound!.play() // works!
if (mysound!playing)
{
mysound!.pause() //works, sort of
}
mysound!playing // is still true.
How do I check to see if it's paused?
The docs show that pause() is supposed to return false if playback already paused, but this doesn't seem to be the case, or I am doing something wrong
I'd like to be able to do this:
var path ="/path/to/file.mp3"
mysound = NSSound(contentsOfFile: path, byReference: false)
if (mysound!playing)
{
var state = mysound!.pause()
if(state == false)
{
mysound!.resume() //never gets executed - why?
}
} else {
mysound!.play()
}
I could use some help figuring this out! thanks!
The sound will only be paused if you called pause() and it returns true. The documentation doesn't qualify, but a paused NSSound might technically still return true for playing. This would make sense if playing is considered to be "not stopped".
Since you will know if you've called pause(), you can just store another Bool isPaused, and use that.
In your second example, you're not calling play(), so playing will always return false.
Related
I have a function called iCloudIsOn() which checks whether a user has opted to use iCloud with the app by comparing the value of a UserDefaults key with a predefined one, and then I am using this on my initial View Controller to sync iCloud and implement pull to refresh, but only if the user is using iCloud, otherwise this code is not needed.
What's strange however is that the function only returns true if I call it right before I need to use it, even with just a print(iCloudIsOn())
The function itself looks like this:
func iCloudIsOn() -> Bool {
if UserDefaults.standard.url(forKey: "UDDocumentsPath") == iCloudPath { return true }
else { return false }
}
Then under viewDidLoad of my initial vc:
override func viewDidLoad() {
super.viewDidLoad()
if iCloudIsOn() {
// sync iCloud
}
}
This will not work however and iCloudIsOn() will return false at that time unless I add a print(iCloudIsOn()) before if iCloudIsOn() { // sync iCloud }
I tried asking iCloudIsOn to print both the value of the UserDefaults key and iCloudPath every time it is called and they are always identical: file:///private/var/mobile/Library/Mobile%20Documents/iCloud~cristian~thrive-storage/Documents/
So there isn't something in my code changing the value for one of them at some point (the value is printed before the return).
Any idea on why this is happening? Is it something to do with how UD works or am I missing something else? I find it a little strange, but I'm sure I'm just making a mistake somewhere.
Thanks in advance.
The problem ended up being that UserDefaults stored a value without a "/" the first time yet when being compared to the original URL, iCloudPath, iCloudPath had the original "/".
UserDefaults.standard.url(forKey: "UDDocumentsPath") = someURL
iCloudPath = someURL/
This would only happen on the first go around. Workaround is to cover both bases as you don't know which one you are on, especially if you are doing multiple checks in one session of the application.
if UserDefaults.standard.url(forKey: "UDDocumentsPath") == iCloudPath || UserDefaults.standard.url(forKey: "UDDocumentsPath").appendPathComponent("/") == iCloudPath
Technically, though, this is odd and unexpected behavior.
I am using swift, xcode 8.3.3, and XCTest. I am trying to wait for an element to exist on the screen using XCTKVOExpectation. It is always returning the result of timedout (2) even though the element exists.
Here is my code:
func waitForElementToAppear(element: XCUIElement) -> Bool {
let expectation = XCTKVOExpectation(keyPath: "exists", object: element,
expectedValue: true)
let result = XCTWaiter().wait(for: [expectation], timeout: 10)
print(element.exists)
print(result.rawValue)
return result == .completed
}
When I print element.exists, it prints true. However the result.rawValue is 2 (.timedout) Increasing the timeout value did not resolve this either.
I am able to successfully use XCTNSPredicateExpectation:
let myPredicate = NSPredicate(format: "exists == true")
let myExpectation = XCTNSPredicateExpectation(predicate: myPredicate,
object: element)
let result = XCTWaiter().wait(for: [myExpectation], timeout: 10)
return result == .completed
Wondering why XCTKVOExpectation doesn't work though?
Not really an answer, but I've been seeing this in Xcode 9.3.1 as well. The exact same predicate combination works well elsewhere in many places but one in particular almost always times out.
I've worked around it for now by checking whether the object exists before issuing the wait, and then also "result == XCTWaiterResultCompleted || object.exists" (Objective C).
I'd love to know if this is a bug or am I doing something wrong?
I was having the same problem with my own code. I was able to get the KVO change to trigger using didChangeValue(forKey: "keyValuePath").
Since XCTKVOExpectation accepts a String for the key path instead of a KeyPath, paired with needing to call didChangeValue(forKey: "keyValuePath"), it seems XCTKVOExpectation is not meant to work with Swift and is more of a legacy objc object. I just don't think this is going to work in Swift
I am trying to write code that waits until a variable equals a certain value. Here is the code I have written:
var i = 0
for i in 1...10 {
playtrial()
repeat {
} while (WasItCorrect=="")
WasItCorrect = ""
}
The idea is that the function will call playtrial, wait until the variable WasItCorrect has a value (other than ""), reset WasItCorrect, and then repeat (for a total of 10 times).
The code produces no errors. However, after plastral is done, the program seems to stop responding and does not allow any new input / button pressing.
I assume the problem is that my repeat/while loop goes forever and never gives a chance for anything else to happen and therefore other functions which change the value of WasItCorrect cannot run. As a VisualBasic 6 programmer who is just starting to learn Swift, I would guess I would need the Swift version of DoEvents. Is that true?
Any advice on how to fix this code would be greatly appreciated.
You can use didSet property of the variable. It will be called whenever the value changed.
var i = 0 {
didSet {
print("Hello World.")
if i == certainValue {
// do something
}
}
}
How do I stop this enumeration? I have the following code and Xcode complaining that I cannot assign a value to let constant. Stopping is probably a simple thing but I'm quite the noobie with Swift, so please bear with me.
self.enumerateChildNodesWithName("//*") {
spaceshipNode, stop in
if (( spaceshipNode.name?.hasSuffix("ship") ) != nil) {
for enemyNode in self.children {
if (enemyNode.name == "enemy"){
if(enemyNode.containsPoint(spaceshipNode.position)){
self.gotoGameOverScene(spaceshipNode)
stop = true // Error: Cannot assign to value: 'stop' is a 'let' constant
}
}
}
}
}
Generally you'd better show your code as text. With which we can easily copy & paste, and test it, or edit it.
In your code, the type of stop should be shown as UnsafeMutablePointer<ObjCBool> in the Quick Help pane of Xcode.
You need to modify the content of the pointer, in Swift2:
stop.memory = true
In Swift 3, the property memory is renamed to pointee:
stop.pointee = true
Apple's documentation suggests that we stop enumeration via stop.initialize(to: true).
With the code below, the local songs variable is never able to be iterated despite all the checks to the contrary ( println shows the value stored ). The other thing is that the Xcode debugger seems to jump all over the place in the init method.
let gLibraryManager = LibraryManager()
class LibraryManager {
var Songs = Dictionary<String, String>()
init() {
println("struct being initialized from NSDefaults")
let userDefaults = NSUserDefaults.standardUserDefaults();
var result:AnyObject = userDefaults.objectForKey(LIKED_LIST)
println(result)
var local = result as? Dictionary<String,String>
if local != nil {
println("local not nil: \(local!)")
for (id,title) in local! {
Songs[id] = title
}
if Songs.count > 0 {
println("NSDefaults detected: \(Songs)")
} else {
println("no NSDefaults detected. Initializing empty")
}
}
}
ok. i figured out what is was.
I had set the Swift Compiler - Code Generation. Optimization level to -Fastest. This was to prevent the extremely slow creation of Dictionaries.
However, it appears this breaks the ability to iterate structures.
It also seems to resolve the weird bouncing around of breakpoints.
This was a needle in a haystack that tooks many hours. I guess the moral of the story is not to mess with compiler flags yet.