First of all let me say that I am very new to programming. What I'm trying to do is add a button that when pressed plays music, and when pressed again the music stops. Ideally when the button is pressed for a third time the music will have reset. Whilst trying to achieve this I'm getting the error message "Expression resolves to an unused function", as I am very new all the help I find online doesn't make any sense to me.
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet weak var janitor: UIImageView!
var pianoSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("C", ofType: "m4a")!)
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
audioPlayer = AVAudioPlayer(contentsOfURL: pianoSound, error: nil)
audioPlayer.prepareToPlay()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func PianoC(sender: AnyObject) {
audioPlayer.play()
if audioPlayer.playing { audioPlayer.stop} else { audioPlayer.play}
}
}
Swooping in here after Martin R's comment ...
if audioPlayer.playing { audioPlayer.stop} else { audioPlayer.play}
On this line, you are not calling the stop and play functions, but simply accessing them. Resolving to an unused function is trying to tell you that you have an expression that is returning a function type, but you are never calling it (audioPlayer.stop and audioPlayer.play are the expressions in question here).
To rid yourself of this error, and probably produce the correct behavior, try calling the functions.
if audioPlayer.playing {
audioPlayer.stop()
} else {
audioPlayer.play()
}
Swift 4:
Just add the braces '()' next to the method name
override func viewWillAppear(_ animated: Bool) {
addView //error: Expression resolves to an unused function
}
func addView(){
}
Solution:
override func viewWillAppear(_ animated: Bool) {
addView()
}
Here's a simplified version of Brian's answer:
audioPlayer.playing
? audioPlayer.stop()
: audioPlayer.play()
if audioPlayer.playing { audioPlayer.stop} else { audioPlayer.play} is just accessing the member variables. It's not doing anything.
I am sure you're intention was to do audioPlayer.stop() and audioPlayer.start().
However just to explain the ERROR and not to solve your issue:
had you done something like
if audioPlayer.playing { self.playerStatus= audioPlayer.stop} else { self.playerStatus = audioPlayer.play}
Then you were actually doing something you were setting a parameter. accessing or just getting a parameter is stupid in the eyes of the compiler :)
Related
I am writing my application in Swift. Here is the viewDidLoad() function:
override func viewDidLoad() {
super.viewDidLoad()
if !self.check_file() {
print("Missing file to read")
performSegueWithIdentifier("missingfileViewController", sender: nil)
}
}
Here is check_file() function:
func check_file() -> Bool {
let fileManager = FileManager.default
return fileManager.fileExists(atPath:"/Applications/Readfile.app/Contents/Resources/textfile/readthis.txt")
}
I'm receiving this error Cannot find 'performSegueWithIdentifier' in scope.
Can anyone help me with this? Great thanks
EDIT: I have even tried to use self.performSegueWithIdentifier, but another error comes up: Value of type 'ViewController' has no member 'performSegueWithIdentifier'
self.performSegue(withIdentifier: "missingfileViewController", sender: self)
try this
Using Xcode 8, Swift 3 and Interface Builder with Storyboards and a very basic view controller featuring only a button (Play) and a slider (volume).
I'm trying to use my NSSlider while pressing a button at the same time. For instance, I need to be able to keep pressing "Play" while slowly lowering the volume. What happens instead is that only one button can be in use at a time. So, as long as I am pressing "Play" using the return key, I can't adjust the volume and vice versa.
In this example, the Play button is triggered by the "return" key.
Here is the code in ViewController.swift. This is just an example app I created quickly to study the problem.
Is there an Interface Builder setting on the NSSLider that I am missing, or can I do something in my code to achieve what I am trying to do?
import Cocoa
import AVFoundation
class ViewController: NSViewController {
var audioPlayer = AVAudioPlayer()
var sliderValue: Float = 0
#IBOutlet weak var volumeSliderOutlet: NSSlider!
override func viewDidLoad() {
super.viewDidLoad()
do{
audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "bell ding", ofType: "wav")!))
}
catch {
print(error)
}
audioPlayer.prepareToPlay()
// Do any additional setup after loading the view.
}
#IBAction func playButtonAction(_ sender: NSButton) {
if audioPlayer.isPlaying {
audioPlayer.currentTime = 0.0
audioPlayer.play()
} else {
audioPlayer.prepareToPlay()
audioPlayer.play()
}
}
#IBAction func volumeSliderAction(_ sender: NSSlider) {
if audioPlayer.isPlaying {
sliderValue = self.volumeSliderOutlet.floatValue
audioPlayer.volume = sliderValue
} else {
return
}
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
I've also tried this, based on advice from #inspector_60, but it doesn't work either. Still can't handle the slider while continuing to press the shortcut key for the button "return".
override func keyDown(with event: NSEvent) {
if (event.keyCode == 36) {
self.playButtonAction(nil)
}
else {
return
}
}
func playButtonAction(_ sender: NSButton?) {
if audioPlayer.isPlaying {
audioPlayer.currentTime = 0.0
audioPlayer.play()
} else {
audioPlayer.prepareToPlay()
audioPlayer.play()
}
}
IBAction are UI events so not suitable for multiple simultaneous clicks (you have only one mouse pointer). Use handling key events in order to handle keyboard events for simultaneous actions.
You need to also implement the mouse events, these links should help:
Apple document about mouse events and specifically Filtering Out Key Events During Mouse-Tracking Operations
This stack overflow answer on how to implement this approach
This post that will give you more information and example - Ron's answer links to a question not that different from yours
Here is the line of code causing the error
class ViewController: UIViewController, UITextFieldDelegate {
I'm following a tutorial so I can't imagine why this went wrong.
It was working just fine until I added this function into my code:
//Check if user is already logged in when opening app if so display dashboard page
override func viewDidAppear(animated: Bool){
if PFUser.currentUser() != nil{
if self.theUser.user_db_obj.email == "mike#chicagodrumlessons.com"{
self.performSegueWithIdentifier("adminLogin", sender: self) //dislay admin page
}
else{
self.performSegueWithIdentifier("userLogin", sender: self) //display user page
}
}
}
Here is the only lines of code where the delegate is referenced I believe
override func viewDidLoad() {
super.viewDidLoad()
self.email_tf.delegate = self
self.pass_tf.delegate = self
}
Any idea what caused this error and how to fix it?
My guess is you declare non-optional properties and they aren't initialized when the object is. The compiler is telling you you need an init or two to provide the non-optional properties values before the object can be initialized (or make the properties optionals).
Help me, please!!! I've only recently started programming in Swift. This is my first project. I get the errormessage: "Incorrect argument label in call". This is my code:
import UIKit
import AVFoundation
class PlaySoundsViewController: UIViewController {
var audioPlayer:AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if var filePath = NSBundle.mainBundle().pathForResource("psl",ofType: "mp3"){
var filePathUrl = NSURL.fileURLWithPath(filePath)
audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: nil)
}else {
print("the filepath is empty")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func playSoundSlow(sender: UIButton) {
audioPlayer.play()
I'm not sure what went wrong here is another picture of my code so you can also see the errormessage.My Code
I'm trying to get it to play a mp3 called psl.mp3.
Please, help me!!! I just started and don't know what to do.
P.S. Not a native Englishspeaker, so sorry for mistakes.
Swift 2 adds new error handling, meaning you don't even have to pass in an error parameter:
audioPlayer = try! AVAudioPlayer(contentsOfURL: filePathUrl)
This initializer throws, meaning if there is an error, you can catch it in a do-catch statement. However, since you passed nil for the error parameter, I'm assuming you are sure the player is there. That's why I used try! without a do-catch instead of try in a do-catch.
Read about the new error handling here.
Try this
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: NSURL.fileURLWithPath(path))
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch {
print("Catch error in playUsingAudioPlayer")
}
This is my function:
func playMusic(filename :String!) {
var playIt : AVAudioPlayer!
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
if url == nil {
println("could not find \(filename)")
return
}
var error : NSError?
playIt = AVAudioPlayer(contentsOfURL: url, error: &error)
if playIt==nil {
println("could not create audio player")
return
}
playIt.numberOfLoops = -1
playIt.prepareToPlay()
playIt.play()
}
I debugged my app and i saw that the console tells me: could't create audio player
it looks like my playIt var is nil
how do i fix it?
There's another problem with your code: once you find out why playIt is nil and fix that, you'll discover that playMusic runs without errors, but no sound plays. That's because you've declared playIt as a local variable inside playMusic. Just as it starts playing, you reach the end of playMusic, when all its local variables go out of scope and cease to exist. Microseconds after playIt starts to play, it gets wiped out of existence.
To fix this, declare playIt outside playMusic, as an instance variable. Here's the code for a view controller that uses your playMusic method with my one suggested change:
import UIKit
import AVFoundation
class ViewController: UIViewController {
// Declare playIt here instead
var playIt : AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
playMusic("sad trombone.mp3")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonPressed(sender: AnyObject) {
}
func playMusic(filename :String!) {
// var playIt : AVAudioPlayer! *** this is where you originally declared playIt
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
if url == nil {
println("could not find \(filename)")
return
}
var error : NSError?
playIt = AVAudioPlayer(contentsOfURL: url, error: &error)
if playIt==nil {
println("could not create audio player")
return
}
playIt.numberOfLoops = -1
playIt.prepareToPlay()
playIt.play()
}
}
Try it both ways -- with playIt declared as an instance variable, and playIt as a local variable inside playMusic. You'll want to go with the former.
I'm also seconding nhgrif's suggestion: playMusic should take a String or String? parameter; not String!