Tutorial details

Swifting with BaasBox | App Code for Sale | Preview

Swifting with BaasBox - Part 3 | Building a quiz app with BaasBox | iOS Tutorial

Part 3 | Building a quiz app with BaasBox

Overview PAGE TOP

In the first part of this series you have learned how to use the BaasBox SDK in Swift. In the second part you have learned how to fetch questions from the backend and run the game.

In this third part we are going to learn how to save the score of each game on the backend and how to load the ranking.

Saving the Score PAGE TOP

In the current version of the application we already have all the game logic in place. The "play" function detects when a round is over and dismisses the view controller. Before doing that, we need to update the score of the user on the backend. This is pretty easy to do. Here is the outline of what we need to do:



  • fetch "fresh" data about the current user
  • update the score field
  • perform an update on the backend


We can fetch data about the currently logged in user as follows:

var currentUser = BAAUser();



BAAUser.loadCurrentUserWithCompletion({(object:AnyObject!, error: NSError!) -> () in

                    currentUser = object as BAAUser;



                    })


This returns a fully parsed instance of BAAUser representing the logged in user. Each user in BaasBox has four dictionaries with different visibilities. The one we are interested in is "visibleByRegisteredUsers", which means visible by all the users that have an account on the platform. We are going to create/update the property named "score" within that dictionary as follows:

if let score = currentUser.visibleByRegisteredUsers["score"] as? Int {



  currentUser.visibleByRegisteredUsers["score"] = score + self.points



} else {



  currentUser.visibleByRegisteredUsers["score"] = self.points



}


This code creates the property if it does not exist (some user might have an account but have never played) or updates its current value. Once we are done we can call updateWithCompletion which will save the updates user on the backend. Summing up here is the full new function play()<br>

func play() {



        if (questions.count == 0) {



            if (points > 0) {



                var currentUser = BAAUser();

                BAAUser.loadCurrentUserWithCompletion({(object:AnyObject!, error: NSError!) -> () in

                    currentUser = object as BAAUser;



                    if let score = currentUser.visibleByRegisteredUsers["score"] as? Int {

                        currentUser.visibleByRegisteredUsers["score"] = score + self.points

                    } else {

                        currentUser.visibleByRegisteredUsers["score"] = self.points

                    }



                    currentUser.updateWithCompletion({(object:AnyObject!, error: NSError!) -> () in



                        if (error == nil) {

                            println("score updated")

                            self.dismissViewControllerAnimated(true, completion: nil)

                        } else {

                            println("error in updating score \(error)")

                        }



                        })



                    })



            } else {



                dismissViewControllerAnimated(true, completion: nil)



            }

            return



        }



        let question = questions[0] as Question

        questionLabel.text = question.question

        questionLabel.hidden = false

        var i = 0;

        for button in buttons {

            button.setTitle(question.answers[i], forState: .Normal)

            button.hidden = false

            i++

        }

        timerValue = 10

        timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "update", userInfo: nil, repeats: true)

    }

 Now build and run the application and make sure that you see the "score updated" log statement when you finish a game with more than zero points. The next step is to show the rankings for the game.

Building the Score View Controller PAGE TOP

The Score View Controller will load user profiles sorted by score, from the highest to the lowest, and display them in a table view. Let's see how easy it is. Create a new class named

ScoreTableViewController as a subclass of UITableViewController. Now drop a Table View Controller in the Storyboard and set its class to ScoreTableViewController. Next select the table view cell, set "scoreCellID" as cell reuse identifier and set its style to subtitle. Now open ScoreTableViewController.swift and make the following changes:

  • add var to hold the list of users returned by the backend 
  • implement table view data source methods 


At this point the code should look like this:

import UIKit



class ScoreTableViewController: UITableViewController {



    var users:BAAUser[] = []



    init(style: UITableViewStyle) {

        super.init(style: style)

    }



    init(coder aDecoder: NSCoder!) {

        super.init(coder: aDecoder)

    }



    override func viewDidLoad() {

        super.viewDidLoad()

    }



    // #pragma mark - Table view data source



    override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {

        return 1

    }



    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {

        return self.users.count

    }



    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {



        let cell = tableView.dequeueReusableCellWithIdentifier("scoreCellID", forIndexPath: indexPath) as UITableViewCell

        let user = self.users[indexPath.row]

        cell.textLabel.text = user.username();

        if let score = user.visibleByRegisteredUsers["score"] as? Int {

            cell.detailTextLabel.text = String(score)

        } else {

            cell.detailTextLabel.text = "0"

        }



        return cell



    }



    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }



}


The last step is to perform the fetch request to the server. The query will retrieve the list of registered users sorted by the value of the score property. This is as easy as injecting the following dictionary in the parameters of the request.

let parameters = ["orderBy" : "visibleByRegisteredUsers.score DESC"]


The key "orderBy" is required by the server and the value specifies the property of the BAAUser class that we want to use as a criterion for sorting. We will perform the call in viewDidLoad() so change it as follows:

override func viewDidLoad() {

    super.viewDidLoad()

    let parameters = ["orderBy" : "visibleByRegisteredUsers.score DESC"]

    BAAUser.loadUsersWithParameters(parameters, {(users: AnyObject[]!, error: NSError!) -> () in



        if (error == nil) {

            self.users = users as BAAUser[]

            self.tableView.reloadData()

        } else {

            println("error loading users %@", error)

        }



        })

}


In case the call is successful we cast and cache the result in the array, otherwise we print the error. Finally, we need a way to show the newly implemented view controller. Open the Storyboard and add a new button named "Scores" to the HomeViewController. Control-drag from the navigation controller to ScoreTableViewController and select "show" as a segue type. Then select the segue and name it "showScores". Finally hook up the "Scores" button to an IBAction defined as follows:

@IBAction func scoreButtonTapped(sender: UIButton) {

        navigationController.performSegueWithIdentifier("showScores", sender: nil)

    }


We are done! Run the application and tap the scores button. It will trigger a request to fetch registered users sorted by score and show it in the table view.

Conclusion PAGE TOP

In this third part of the series you have learned how to create the view to display the ranking of users in the game. You have seen how it is easy to create a table view controller in Swift and to perform a request with parameters to the BaasBox backend. In the fourth part we will wrap up the key points of the tutorial and provide you a link with the complete application, graphics included!

4 Comments Leave a comment

Please login in order to leave a comment.

Newest first
  • dsalza 2015-02-17 05:12:19 Thread #429

    When will you be posting part 4?

    • dsalza 2015-02-17 05:13:09

      Great tutorial

    • Chupa Team 2015-02-18 12:39:39

      We will keep you updated. Thanks.

    • dsalza 2015-03-03 20:43:55

      Update on the tutorial?

!

Sign-in to your Chupamobile Account.

The Easiest way to Launch your next App or Game.

Join Chupamobile and get instant access to thousands of ready made App and Game Templates.

Creating an account means you’re okay with Chupamobile’s Terms of Service and Privacy Policy.