I've built an app for members of an organization I'm in--the app shows the picture of a member with four multiple choice buttons, and the user then tries to guess the member's name. Pretty simple, but this is one of my first major apps.
import UIKit
import Foundation
class ViewController: UIViewController {
@IBOutlet weak var memberPic: UIImageView!
@IBOutlet weak var scoreLabel: UILabel!
@IBOutlet weak var firstChoice: UIButton!
@IBOutlet weak var secondChoice: UIButton!
@IBOutlet weak var thirdChoice: UIButton!
@IBOutlet weak var fourthChoice: UIButton!
@IBOutlet var choiceButtons: Array<UIButton>?
@IBOutlet weak var playAgainButton: UIButton!
@IBAction func guessChosen(sender: AnyObject) {
checkAnswer(sender)
}
let redButton = UIImage(named: "red_button") as UIImage?
let greenButton = UIImage(named: "green_button") as UIImage?
let yellowButton = UIImage(named: "yellow_button") as UIImage?
var rightAnswer:FMResultSet?
var databasePath:String?
var correctName:String?
var correctButton:UIButton?
var memberDatabase:FMDatabase?
var score = 0
var correctRun = 0
var turnCount = 0
var queryParameters = ["None"] //"None" to exclude empty pics, names to be added
var queryHoles = "" //append "?" for each already-seen name
@IBAction func playAgainPressed(sender: AnyObject) {
resetGame()
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background.jpeg")!)
let path = NSBundle.mainBundle().pathForResource("members", ofType:"sqlite3")
playAgainButton.hidden = true
memberDatabase = FMDatabase(path: path)
if memberDatabase!.open(){
println("database is ready")
} else {
println("error finding database")
}
scoreLabel.text = "\(score)"
resetGame()
//close database?
}
func resetGame(){
score = 0
turnCount = 0
correctRun = 0
playAgainButton.hidden = true
queryParameters = ["None"]
queryHoles = ""
displayRandomMember()
}
func displayRandomMember(){
for button in choiceButtons! {
button.setBackgroundImage(yellowButton, forState: .Normal)
button.userInteractionEnabled = true
}
let querySQL = "SELECT name, picture_name from member_data where picture_name is not ? and name not in (\(queryHoles)) ORDER BY RANDOM() LIMIT 1";
rightAnswer = memberDatabase!.executeQuery(querySQL, withArgumentsInArray: queryParameters)
rightAnswer!.next()
correctName = rightAnswer!.stringForColumn("name")!
let correctPicture = rightAnswer!.stringForColumn("picture_name")
let wrongAnswerSQLQuery = "SELECT name from member_data where picture_name is not ? and name is not ? ORDER BY RANDOM() LIMIT 3" //gets three wrong answers
let wrongAnswersResultSet:FMResultSet = memberDatabase!.executeQuery(wrongAnswerSQLQuery, withArgumentsInArray: ["None", correctName!])
var wrongAnswersArray:[String] = []
while wrongAnswersResultSet.next() == true {
wrongAnswersArray.append(wrongAnswersResultSet.stringForColumn("name"))
}
var wrongButtons = [firstChoice, secondChoice, thirdChoice, fourthChoice]
correctButton = wrongButtons.removeAtIndex(Int(arc4random_uniform(4)))
rotateButton(correctButton!, newname: correctName!)
for i in 0..<wrongButtons.count{
rotateButton(wrongButtons[i], newname:wrongAnswersArray[i])
}
memberPic.image = UIImage(named: correctPicture)
queryParameters.append(correctName!) //keep track of names already seen this game
if (count(queryHoles) > 0) {
queryHoles += (",?") //if already has one '?'
} else {
queryHoles += ("?")
}
return
}
func checkAnswer(sender:AnyObject){
let selectedAnswer = sender.currentTitle!
for button in choiceButtons! {
button.userInteractionEnabled = false
}
correctButton!.setBackgroundImage(greenButton, forState: .Normal)
if selectedAnswer! == correctName! {
correctRun += 1
score += (100 * correctRun)
scoreLabel.text = "\(score)"
} else {
sender.setBackgroundImage(redButton, forState: .Normal)
correctRun = 0
}
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC * 1))
dispatch_after(delayTime, dispatch_get_main_queue()){
self.turnCount += 1
if self.turnCount < 10 {
self.displayRandomMember()
} else {
self.checkHighScore()
self.playAgainButton.hidden = false
}
}
}
func checkHighScore(){
let defaults = NSUserDefaults.standardUserDefaults()
var oldHighScore = defaults.integerForKey("highScore")
if (score > oldHighScore) {
defaults.setInteger(score, forKey: "highScore")
}
}
func rotateButton(button:UIButton, newname:String) {
UIView.transitionWithView(
button,
duration: 0.5,
options: UIViewAnimationOptions.TransitionFlipFromLeft | .AllowAnimatedContent,
animations: {button.setTitle(newname, forState:.Normal)},
completion: nil )
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Questions:
- I feel like I am supposed to close the database at some point, but I'm not sure where.
- I hate how I query to make sure I'm not repeating names within a round (10 questions). I append
"?"
toqueryholes
and the name toqueryParameters
; it works, and it's the answer I got from this question but it feels so hackish.