HiveBrain v1.2.0
Get Started
← Back to all entries
patternswiftModerate

Piano app in Swift

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
swiftpianoapp

Problem

I'm making my first app in Swift: a Piano app. I'd like to get your feedback especially about how I can make codes shorter. I maybe have to use arrays and loops and something, and searched by myself but couldn't get it.

view controller.swift

```
import UIKit
import AVFoundation

class ViewController: UIViewController {

var pianoSoundC3 = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("C3", ofType: "mp3")!)
var audioPlayerC3 = AVAudioPlayer()

var pianoSoundCS = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("C#", ofType: "mp3")!)
var audioPlayerCS = AVAudioPlayer()

var pianoSoundD = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("D", ofType: "mp3")!)
var audioPlayerD = AVAudioPlayer()

var pianoSoundDS = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("D#", ofType: "mp3")!)
var audioPlayerDS = AVAudioPlayer()

var pianoSoundE = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("E", ofType: "mp3")!)
var audioPlayerE = AVAudioPlayer()

var pianoSoundF = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("F", ofType: "mp3")!)
var audioPlayerF = AVAudioPlayer()

var pianoSoundFS = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("F#", ofType: "mp3")!)
var audioPlayerFS = AVAudioPlayer()

var pianoSoundG = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("G", ofType: "mp3")!)
var audioPlayerG = AVAudioPlayer()

var pianoSoundGS = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("G#", ofType: "mp3")!)
var audioPlayerGS = AVAudioPlayer()

var pianoSoundA = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("A", ofType: "mp3")!)
var audioPlayerA = AVAudioPlayer()

var pianoSoundAS = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("A#", ofType: "mp3")!)
var audioPlayerAS = AVAudioPlayer()

var pianoSoundB = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("B", ofType: "mp3")!)
var audioPlayerB = AVAudioPlayer()

var pianoSoun

Solution

I think this should work. The key (pun intended) to making this work is to take advantage of the tag property of UIButton. In Interface Builder, set a different tag to each piano key. Start with 0 for "C3", 1 for "C#", up to 12 for "C4". Wire all of those keys to playKey.

import UIKit
import AVFoundation

class ViewController: UIViewController {

    let pianoKeys = ["C3", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C4"]
    var audioPlayers:[AVAudioPlayer] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        for key in pianoKeys {
            let pianoSoundURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(key, ofType: "mp3")
            let audioPlayer = AVAudioPlayer(contentsOfURL: pianoSoundURL, error: nil)
            audioPlayer.prepareToPlay()
            audioPlayers.append(audioPlayer)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func playKey(sender: UIButton) {
        let keynum = sender.tag
        audioPlayers[keynum].currentTime = 0
        audioPlayers[keynum].play()
    }
}

Code Snippets

import UIKit
import AVFoundation

class ViewController: UIViewController {

    let pianoKeys = ["C3", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C4"]
    var audioPlayers:[AVAudioPlayer] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        for key in pianoKeys {
            let pianoSoundURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(key, ofType: "mp3")
            let audioPlayer = AVAudioPlayer(contentsOfURL: pianoSoundURL, error: nil)
            audioPlayer.prepareToPlay()
            audioPlayers.append(audioPlayer)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func playKey(sender: UIButton) {
        let keynum = sender.tag
        audioPlayers[keynum].currentTime = 0
        audioPlayers[keynum].play()
    }
}

Context

StackExchange Code Review Q#64842, answer score: 17

Revisions (0)

No revisions yet.