Game Development Reference
In-Depth Information
The task layoutScores: from Listing 3-10 takes a Score object as an argument. This Score object
represents the most recent score the player has achieved. This allows HighscoreController to mark
the newest score in blue; the other scores will be drawn in black. The first loop in layoutScores:
simply removes all sub-views from the UIView highscoreView . The next three lines inspect the size
of highscoreView and pre-compute some size values that will be used later.
The second loop in layoutScores: iterates through all of the Score objects contained in the
highscores object. For each Score , two UILabels are created. The first UILabel , called dateLabel is
created with the CGRect dateFrame , which defines the region where the UILabel should be drawn.
Basically, dateFrame specifies the left half of a row on highscoreView . The text for dateLabel is set
based on the date property of the Score object. Similarly, this process is repeated for the UILabel
scoreLabel ; however, it will display the score the user achieved and will be placed on the right.
Lastly, we check to see if the score we are displaying is the object latestScore . If it is, we adjust the
colors of the UILabel s to blue.
If we take a look back at Listing 3-9, we see that the high scores are saved before we update the
views by calling the task saveHighscores , as shown in Listing 3-11.
Listing 3-11. HighscoreController.m (saveHighscores)
-(void)saveHighscores{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSData* highscoresData = [NSKeyedArchiver archivedDataWithRootObject: highscores];
[defaults setObject:highscoresData forKey: KEY_HIGHSCORES];
[defaults synchronize];
}
The saveHighscores task, shown in Listing 3-11, is responsible for archiving the highscores object
and writing it somewhere permanent. The strategy here is to stick the highscores object into the
user's preferences for this application. This way, the high scores will be preserved if the user deletes
the app after a sync with iTunes. To know the user's preferences, we call standardUserDefaults on
the class NSUserDefaults . Objects of type NSUserDefaults are basically maps for storing key value
pairs. The keys are NSStrings and the values must be a property list. This includes NSData , NSString ,
NSNumber , NSDate , NSArray , and NSDictionary —basically the core iOS objects types. We want to
store an object of type Highscores , which is not included in this list. In order accomplish this, we
must create an NSData object from the data stored in the highscores object.
To archive an object to an NSData object, we use the class NSKeyedArchiver and pass
the highscores object to the tasks archivedDataWithRootObject: . As the name implies,
archivedDataWithRootObject is designed to archive a graph of objects. In our case, the root object
is highscores and we know it contains a number of Score objects. So it looks like we are on the right
track. In order for an object to be archived by an NSKeyedArchiver , it must conform to the protocol
NSCoding . The final step is to call synchronize on defaults ; this makes sure our changes are saved.
The Highscores Class
Instances of the class Highscores store a sorted list of Score objects and handle the details of
adding Score object to the list. Let's take a look at the header file for the class Highscores and see
how this all works, as shown in Listing 3-12.
 
Search WWH ::




Custom Search