Error with NSBundle.mainBundle when adding sound - xcode

I've trying to create a simple sound board for when a button is pressed a sound is made, however when I used this code
let url = NSURL(fileURLWithPath: Bundle.mainBundle().pathForResource(sound, ofType: "mp3")!)
let audioPlayer = try AVAudioPlayer(contentsOfURL: url)
I get an error with "Bundle.mainBundle" orginally it told me to change "Bundle" from "NSBundle" because it has be renamed but when I correct that I get another error saying "Cannot call value for non-function type 'Bundle' "
my entire code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
let soundFilenames = ["60gs", "check", "dada", "danceforme", "eat", "gods", "irelandbaby", "ko'd", "lefthand", "littlewerp", "nocalls", "precision", "sundaymorning", "surprise", "whothefuckisthatguy", "youlldonothing"]
var audioPlayers = [AVAudioPlayer]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for sound in soundFilenames {
do {
let url = Bundle.main.url(forResource:sound, withExtension: "mp3")!
let audioPlayer = try AVAudioPlayer(contentsOfURL: url)
audioPlayer.append(audioPlayer())
}
catch {
audioPlayers.append(AVAudioPlayer())
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonTapped(_ sender: UIButton) {
let audioPlayer = audioPlayers[sender.tag]
audioPlayer.play()
}
}
can anyone help me with this please.

First of all in Swift 3 mainBundle() became main but why not the real short way:
let url = Bundle.main.url(forResource:sound, withExtension: "mp3")!
And the init method has been renamed to
let audioPlayer = try AVAudioPlayer(contentsOf: url)
and change the next line to:
audioPlayers.append(audioPlayer)

Related

Getting a fatal error when trying to play sound in Swift

I have worked my way through this tutorial here. One of the last things you do is have a button make sound when it is pressed. I wanted to then continue using that same logic to make a sound board app. However when I stripped the non-essential parts besides it making noise inside a new project I started getting a fatal error.
Here is my ViewController.swfit file:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var sample : AVAudioPlayer?
func setupAudioPlayerWithFile(file:NSString, type:NSString) -> AVAudioPlayer? {
//1
let path = NSBundle.mainBundle().pathForResource(file as String, ofType: type as String)
let url = NSURL.fileURLWithPath(path!)
//2
var audioPlayer:AVAudioPlayer?
// 3
do {
try audioPlayer = AVAudioPlayer(contentsOfURL: url)
} catch {
print("Player not available")
}
return audioPlayer
}
override func viewDidLoad() {
super.viewDidLoad()
if let sample = self.setupAudioPlayerWithFile("Stomach", type:"aif") {
self.sample = sample
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonPressed() {
sample?.play()
}
}
Here is my project when the fatal error hits
I have also tried this solution but I got errors as well.
I am running on El Capitan 10.11.3 with Xcode 7.3
Have you included the an audio file named "Stomach.aif" in your project? If not, pathForResource will return nil and you'll crash when attempting to force unwrap that path. You can use a safer version of this function, although if it can't locate that file it still won't play the audio On the bright side it shouldn't crash.
func setupAudioPlayerWithFile(file:NSString, type:NSString) -> AVAudioPlayer? {
var audioPlayer:AVAudioPlayer? = nil
if let path = NSBundle.mainBundle().pathForResource(file as String, ofType: type as String) {
let url = NSURL.fileURLWithPath(path)
do {
try audioPlayer = AVAudioPlayer(contentsOfURL: url)
} catch {
print("Player not available")
}
}
return audioPlayer
}

Swift 3D Touch Quick Action not loading requested url

I'm new to Swift, and trying my hands with UIWebView app that loads default url, with option to perform quick action and load a different url.
Problem is when I request the quick action url, code executes but the new url is not loading. So I'm missing something in the flow somewhere.
Here is the code:
import UIKit
import WebKit
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var webView: UIWebView!
override func loadView() {
super.loadView()
self.webView = UIWebView()
self.view = self.webView!
}
override func viewDidLoad() {
print("view did load")
super.viewDidLoad()
let url = NSURL(string: "google.com")
let req = NSURLRequest(URL:url!)
webView.loadRequest(req)
webView.delegate = self
}
func loadUrl2() {
loadView()
let url = NSURL(string: "example.com")
print(url)
let req = NSURLRequest(URL:url!)
self.webView!.loadRequest(req)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I was experimenting and added loadView to loadUrl2, as I was getting
fatal error: unexpectedly found nil while unwrapping an Optional value
before that.
Edited to Include loading secondary link:
Here are the changes and files you'll need to make to the App Delegate
enum ShortcutIdentifier: String {
case OpenNewLink
case OpenBetterLink
init?(fullIdentifier: String) {
guard let shortIdentifier = fullIdentifier.componentsSeparatedByString(".").last else {
return nil
}
self.init(rawValue: shortIdentifier)
}
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsAnnotationKey] as? UIApplicationShortcutItem {
handleShortcut(shortcutItem)
return false
}
return true
}
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
completionHandler(handleShortcut(shortcutItem))
}
private func handleShortcut(shortcutItem: UIApplicationShortcutItem) -> Bool {
let shortcutType = shortcutItem.type
guard let ShortcutIdentifier = ShortcutIdentifier(fullIdentifier: shortcutType) else {
return false
}
return selectLinkForIdentifier(ShortcutIdentifier)
}
private func selectLinkForIdentifier(identifier: ShortcutIdentifier) -> Bool {
guard let mainView = self.window?.rootViewController as? ViewController else {
return false
}
switch identifier {
case .OpenNewLink:
mainView.urlString = "http://www.bing.com"
mainView.loadWebView(mainView.urlString)
return true
case.OpenBetterLink:
mainView.urlString = "http://www.duckduckgo.com"
mainView.loadWebView(mainView.urlString)
return true
}
}
I also made changes in the MainVC
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var webView: UIWebView!
var urlString: String? = nil
override func viewDidLoad() {
super.viewDidLoad()
setUpWebView()
webView.delegate = self
view.addSubview(webView)
}
func setUpWebView() {
webView = UIWebView()
webView.frame = CGRectMake(0, 0, view.frame.width, view.frame.height)
loadWebView(urlString)
}
func loadWebView(var urlString: String?) {
if urlString == nil {
urlString = "http://www.google.com"
}
let url = NSURL(string: urlString!)
let req = NSURLRequest(URL:url!)
webView.loadRequest(req)
}
}
Be sure to add NSAppTransportSecurity dictionary to your .plist and add NSAllowsArbitraryLoads key set to YES.
I tested it and it should work for you.

Sent email, without confirmation using swift (OSX)

I cannot manage to send an email using Swift on OSX.
Its almost do the work, but don't sent the email, and on my personal computer, its opening Google Chrome for some raison.
Here is my code
import Cocoa
class ViewController: NSViewController, NSSharingServiceDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
#IBAction func mag(sender: AnyObject) {
let body = "BODY EMAIL"
let shareItems = [body] as NSArray
var service = NSSharingService(named: NSSharingServiceNameComposeEmail)
service?.delegate = self
service?.recipients = ["email#address.com"]
let subject = "Subject!"
service?.subject = subject
service?.performWithItems(shareItems as [AnyObject])
}
}

Background music not working, but no errors?

Please solve my question, why is the background music not working? This is my code, hope someone can solve it.
// Just to format it..
#IBOutlet var UsernameTextField: UITextField!
#IBOutlet var PasswordTextField: UITextField!
#IBOutlet var EmailTextField: UITextField!
#IBAction func LogIn(sender: AnyObject) {
}
func Login(){
var user = PFUser()
user.username = UsernameTextField.text!
user.password = PasswordTextField.text!
PFUser.logInWithUsernameInBackground(UsernameTextField.text, password: PasswordTextField.text, block: {
(User : PFUser?, Error : NSError?) -> Void in
if Error == nil{
dispatch_sync(dispatch_get_main_queue()){
var Storyboard = UIStoryboard(name: "Main", bundle: nil)
var MainVC : UIViewController = Storyboard.instantiateViewControllerWithIdentifier("MainVC") as! UIViewController
self.presentViewController(MainVC, animated: true, completion: nil)
}
}
else{
NSLog("Sorry, you've typed either username or password wrongly.")
}
})
}
#IBAction func signUpButton(sender: AnyObject) {
signUp() // Calling signUp function here that is declared below.
}
func signUp(){
// Do sign up stuff.
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
playBackgroundMusic("IntroMusic")
backgroundMusicPlayer.play()
let soundFilePath = NSBundle.mainBundle().pathForResource("Background", ofType: "mp3")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
let player = AVAudioPlayer(contentsOfURL: soundFileURL, error: nil)
player.numberOfLoops = -1 //infinite
player.play()
func signUp(){
var user = PFUser()
user.username = UsernameTextField.text!
user.password = PasswordTextField.text!
user.email = EmailTextField.text!
}
let user = PFUser()
user.username = "Name:"
user.password = "Pass:"
user.email = "Email:"
user.signUpInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
if error == nil {
// Hooray! Let them use the app now.
} else {
// Examine the error object and inform the user.
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
var backgroundMusicPlayer: AVAudioPlayer!
func playBackgroundMusic(filename: String) {
//The location of the file and its type
let url = NSBundle.mainBundle().URLForResource("Background", withExtension: "mp3")
//Returns an error if it can't find the file name
if (url == nil) {
println("Could not find the file \(filename)")
}
var error: NSError? = nil
//Assigns the actual music to the music player
backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
//Error if it failed to create the music player
if backgroundMusicPlayer == nil {
println("Could not create audio player: \(error!)")
return
}
//A negative means it loops forever
backgroundMusicPlayer.numberOfLoops = -1
backgroundMusicPlayer.prepareToPlay()
backgroundMusicPlayer.play()
}
As Leo Dabus suggested declare your player instance outside of viewDidLoad method and your code will be:
var player : AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let soundFilePath = NSBundle.mainBundle().pathForResource("Background", ofType: "mp3")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
player = AVAudioPlayer(contentsOfURL: soundFileURL, error: nil)
player.numberOfLoops = -1 //infinite
player.play()
}

Swift / Spring: SoundPlayer.play("string.wav") not working

I try to use the Spring Framework to play a sound when a button is touched.
import UIKit
class ViewController: UIViewController {
//TODO: max, mia, beide arrays und zufallsgenerator und happy day unten mit klick gleich wave
#IBAction func soundButton(sender: AnyObject) {
let mySound : String! = "refresh.wav"
SoundPlayer.play(mySound)
}
#IBOutlet weak var imageView: SpringImageView!
#IBAction func beideButton(sender: AnyObject) {
imageView.image = UIImage(named: "b1")
imageView.animation = "zoomIn"
imageView.animate()
}
#IBAction func maxButton(sender: AnyObject) {
imageView.image = UIImage(named: "max1")
imageView.animation = "slideLeft"
imageView.animate()
}
#IBAction func miaButton(sender: AnyObject) {
imageView.image = UIImage(named: "mia1")
imageView.animation = "slideRight"
imageView.animate()
}
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.
}
}
I get the following error: Cannot invoke 'play' with an argument list of type ('String')
I tried view things like as!, as String, as String!, as? String to unwrap or so but can not figure it out...
Here is the SoundPlayer class (Copyright (c) 2015 James Tang (j#jamztang.com):
import UIKit
import AudioToolbox
public class SoundPlayer: NSObject {
#IBInspectable var filename : String?
#IBInspectable var enabled : Bool = true
private struct Internal {
static var cache = [NSURL:SystemSoundID]()
}
public func playSound(soundFile:String) {
if !enabled {
return
}
if let url = NSBundle.mainBundle().URLForResource(soundFile, withExtension: nil) {
var soundID : SystemSoundID = Internal.cache[url] ?? 0
if soundID == 0 {
AudioServicesCreateSystemSoundID(url, &soundID)
Internal.cache[url] = soundID
}
AudioServicesPlaySystemSound(soundID)
} else {
println("Could not find sound file name `\(soundFile)`")
}
}
#IBAction public func play(sender: AnyObject?) {
if let filename = filename {
self.playSound(filename)
}
}
}
Judging by the code alone (I'm not familiar with Spring), what you need to do is create a SoundPlayer instance and call playSound on it (not play, which uses an internal filename for the sound to play instead of its argument), like this:
#IBAction func soundButton(sender: AnyObject) {
let mySound : String! = "refresh.wav"
let soundPlayer = SoundPlayer()
soundPlayer.playSound(mySound)
}

Resources