Incorrect argument label in call? - swift

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")
}

Related

class "ViewController' has no initializers [duplicate]

This question already has answers here:
Class 'ViewController' has no initializers in swift
(8 answers)
Closed 6 years ago.
Im trying to build a simply sound app. I want a button press to play a clip pretty much like a soundboard. problem is when I go to build it says class "ViewController' has no initializers
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func playSound(sender:UIButton){
// Set the sound file name & extention
let audioFilePath = Bundle.main.path(forResource: "emp_learntoknow", ofType: "mp3")
if audioFilePath != nil {
let audioFileUrl = URL.init(fileURLWithPath: audioFilePath!)
do {
audioPlayer = try AVAudioPlayer(contentsOf: audioFileUrl)
audioPlayer.play()
} catch {
print("audio file is not found")
}
}
}
Because it has no initializers. You have a property:
var audioPlayer: AVAudioPlayer
...but you are not initializing it. You have, of course, given it a type, but a type is not a value. All properties must have initial values.
Like Matt has mentioned, it's happening because the property is not initialized.
In Swift, you have to use optionals for variables that could be nil at any point. You'll have to either initialize audioPlayer from the beginning or use an optional type, including the implicitly unwrapped optional if you know it will be set later on and stay that way.

SWIFT : Incorrect argument label in call Xcode 7.3.1

import SpriteKit
import AVFoundation
class HGBackgroundMusic: SKScene {
var audioPlayer = AVAudioPlayer()
func getSoundReady() {
var plop = NSURL(fileURLWithPath:NSBundle.mainBundle().pathForResource("Plop", ofType: "mp3")!)
var audioPlayer = AVAudioPlayer()
audioPlayer = AVAudioPlayer(contentsOfURL: plop, error: nil)
audioPlayer.prepareToPlay()
}
func playSound() {
audioPlayer.play()
}
}
In the
error:nil
line, an error is coming up stating: Incorrect argument label in call(have 'contentsOfURL:error:', expected'contentsOfURL:fileTypeHint:'). So I replace "error" with "fileTypeHint", and that brings up another error stating: Call can throw, but is not marked with 'try' and the error is not handled. I cannot fix this though I have spent hours trying to find what to do to solve it.
Replace your arc4random call with arc4random_uniform.

How to throw and handle an error in swift?

here is my code (Swift):
import UIKit
import AVFoundation
class PlaySoundViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if var filePath = NSBundle.mainBundle().pathForResource("movie_quote",ofType: "mp3"){
var filePathUrl = NSURL.fileURLWithPath(filePath)
AVAUdioPlayer audioPlayer = AVAudioPlayer(contentsOfURL:filePathUrl) throws
}
else{
print("filePath is empty")
}
}
#IBAction func playSlowAudio(sender: UIButton) {
}
func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
this is the method I found on my "Documentation and API References" to play audio:
``
initWithContentsOfURL:error:
init(contentsOfURL url: NSURL) throws
So, I return a String as source path, then conver it to NSURL. Now i want to play the audio but the method I am using needs to throw the error and handle it. How should I throw and handle the error ?
Swift 2.0
AVAudioPlayer will throw an exception if its initializer fails. Catch the error by wrapping its initialization in a do/catch clause.
do {
let audioPlayer = try AVAudioPlayer(contentsOfURL: filePathUrl)
// use audioPlayer
} catch {
// handle error
}
As you can see, the keyword try is inserted before any method call that can throw exceptions. As long as the try statement doesn't throw, you can continue your code as normal. If the try statement does throw, you program will jump to the catch clause.
Examining the error
If you'd like to examine the error, you can convert it to an NSError by writing your catch statement like so (as seen in Apple's Objective-C/Swift Interoperability Docs):
do {
let audioPlayer = try AVAudioPlayer(contentsOfURL: filePathUrl)
// use audioPlayer
} catch let error as NSError {
// error is now an NSError instance; do what you will
}
Converting to NSError is only necessary if you want to examine an error thrown by one of Apple's Cocoa objects. Native Swift code, throwing native ErrorType errors, require no conversion.
I recommend you read Apple's new docs on error handling in Swift.
Swift 1.2
If you are using Swift 1.2, then there is no error handling available. Instead, AVAudioPlayer's initialization method will fail and return nil.
If you are using Swift 1.2, I would recommend initializing the audio player like this:
var initError: NSError?
if let audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: &initError) {
// use audioPlayer
} else {
println(initError) // handle error
}
Since Swift 1.2, you cannot throw/handle exceptions. While it is available in swift2 (need XCode7 support) which is still in beta. See this article for detail (https://www.hackingwithswift.com/new-syntax-swift-2-error-handling-try-catch).

Why the AVAudioPlayer var equals nil? - Swift

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!

Expression resolves to an unused function

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 :)