Bronze Challenge Solution without State Preservation/Restora


As i have read so far, most of answers for Bronze Challenge solution is achieved by studying Application State Preservation/Restoration with complaint of the author’s mistake to raise such challenge by the end of this chapter. Yet I believe this Challenge can be solved using fundamental knowledge learned in the previous chapters. In fact, to this point of the book, I think most of us are already familiar with NSArray and writeToFile: automatically: method.

So since I did give it a try and succeeded, I would like share this with everyone, and also take the chance to seek improvement for my code, because there are still few things I dont seem to fully understand .

First of all, the logic of the solution (the algorithm)
1. We need an array to hold all the coordinate value of drawn lines
2. Write the array to a file before the Application does terminate (a PROPERTY LIST)
3. During application launch, load the property list and redraw the lines following coordinates that were saved.

*Extra feature: for further testing, I decided to implement a method where a user’s long touch can delete all the lines that has been drawn to the view


  1. Declare 2 voids in BNRDrawView.h, one for saving the lines and the other for reloading them at app launch

@interface BNRDrawView : UIView -(void)saveAllLines; -(void)redrawSavedLines; @end

…and their Implementations:

// Create a new array to hold cordinates of exisiting lines
NSMutableArray *lineToBeSaved = [[NSMutableArray alloc]init];
for (BNRLine *line in self.finishedLines) {
[lineToBeSaved addObject:[[NSNumber alloc]initWithFloat:line.begin.x]];
[lineToBeSaved addObject:[[NSNumber alloc]initWithFloat:line.begin.y]];
[lineToBeSaved addObject:[[NSNumber alloc]initWithFloat:line.end.x]];
[lineToBeSaved addObject:[[NSNumber alloc]initWithFloat:line.end.y]];

// Write all cordinates to a property list
[lineToBeSaved writeToFile:@"/Users/Elderaine/Desktop/Lines/_lines" atomically:YES];

// For every line needs 4 foat values as its cordinate, check to see how many lines saved to the property list
NSLog(@"%lu lines were saved to disk!",(lineToBeSaved.count)/4);


// Create a new array to hold imported saved lines’ coordinate data
NSMutableArray *lineToBeDrawn = [[NSMutableArray alloc]initWithContentsOfFile:@"/Users/Elderaine/Desktop/Lines/_lines"];
if (lineToBeDrawn.count<4) { // If the number of entries is less than 4, then no line should be drawn

// Double check the number of lines imported
NSLog(@"Imported %lu lines from savefile",(lineToBeDrawn.count)/4);

// Adding them to the finishedLines array of self, the method drawRect shall automatically take care of the drawing work
for (int i = 0; i < (lineToBeDrawn.count - 3); i += 4) {
    BNRLine *linex = [[BNRLine alloc]init];
    linex.begin = CGPointMake([lineToBeDrawn[i] floatValue], [lineToBeDrawn[i+1] floatValue]);
    linex.end = CGPointMake([lineToBeDrawn[i+2] floatValue], [lineToBeDrawn[i+3] floatValue]);
    [self.finishedLines addObject:linex];


In BNRDrawViewController.h class extension, create a pointer to BNRDrawView so I can call the newly added method later. Implement them:

[code]@interface BNRDrawViewController ()
@property (nonatomic) BNRDrawView *viewToDraw;

@implementation BNRDrawViewController

  • (void)loadView
    _viewToDraw = [[BNRDrawView alloc]initWithFrame:CGRectZero];
    [_viewToDraw redrawSavedLines]; // call the method to reload all saved lines
    self.view = _viewToDraw;

-(void)viewWillDisappear:(BOOL)animated //before disappearance, call the method to save all drawn lines
if (animated == YES) {
[self.viewToDraw saveAllLines];


In BNRAppDelegate.h, add one more line of code:

- (void)applicationDidEnterBackground:(UIApplication *)application { [self.window.rootViewController viewWillDisappear:YES]; // Call to the line-saving method of BNRDrawViewController }

So far, it works, except one thing: as I run it in the Simulator, everytime I run the app from Xcode and manually terminate it with the Simulator, an exception is thrown without description, pointing to main.h. When I stop the run in Xcode but keep using the app in the Simulator, it works fine. Explain?
Besides, I would like to know if there is any unnecessary line in my code. It seems quite long to me.


You can expand the path to your saved files using for instance:
[@"~/Documents/lines" stringByExpandingTildeInPath]
to make the path more general.