Rasterizing a UIView

I was doing some work with parsing and visualising SVG files but the views ended up having lots of paths and a lot of memory was consumed. So the idea was to convert the UIView to an image … :)

 
// Doing work to generate the SVG in the schematics view;
// At the end there was no reason to keep all these (SVGView)subviews 
// ******* Rasterize ************
// Create an image from the view
 
    UIGraphicsBeginImageContext(schematicsView.frame.size);
    [schematicsView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
 
// Remove the SVG views to release the memory.
    for (SVGView *view in SVGReferences) 
        [view removeFromSuperview];
 
// Add the image that was created before as a subview
    [self.view addSubview:[[[UIImageView alloc] 
                            initWithImage:viewImage] autorelease]];

I swear pure awesomeness!!! :)

Checking for decimal points?

To check if a number has decimal points you can do the following:

if (floor(value) != value){
// it has decimal points
}

Checking for Null?

To check if a primitive data type is null you can do the following:

if (value != value){
// then is null
}

NSCoder + NSKeyedArchiver

This post is a simple example of NSCoder and NSKeyedArchiver to save and restore the data of an instance.

First of all we need to create our object, in this case an object “Person” with three properties (name, surname, age). The interface looks like normally.

#import <Foundation/Foundation.h>
@interface Person : NSObject { }
@property (retain) NSString *firstName;
@property (retain) NSString *lastName;
@property int age;
@end

The implementation needs some additional code. We need to implement the NSCoding protocol, which means two additional methods. (initWithCoder: and encodeWithCoder:)

#import "Person.h"
@implementation Person
@synthesize age,firstName,lastName;
-(id)initWithCoder:(NSCoder*)decoder{
    if ((self = [super init])) {
        firstName = [decoder decodeObjectForKey:@"firstName"];
        lastName  = [decoder decodeObjectForKey:@"lastName"];
        age           = [decoder decodeIntForKey:@"age"];
    }
    return self;
}
-(void)encodeWithCoder:(NSCoder*)encoder{
    [encoder encodeObject:firstName forKey:@"firstName"];
    [encoder encodeObject:lastName forKey:@"lastName"];
    [encoder encodeInt:age forKey:@"age"];
}
@end

Once we implement the protocol, saving will look like this:

// Save method
// We initialise our object and set the values
Person* p1 = [[[Person alloc] init] autorelease];
p1.firstName = [firstNameTextField stringValue];
p1.lastName  = [lastNameTextField stringValue];
p1.age       = [ageTextField intValue];
 
// We initialise our NSMutableData
NSMutableData *sData = [[NSMutableData alloc] init];
/*And our NSKeyedArchiver initialised to encode stream and version 
information into a given mutable data object.*/
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] 
                      initForWritingWithMutableData:sData];
// Then we encode our object for a key of our choice
[archiver encodeObject:p1 forKey:@"person"];
[archiver finishEncoding];
 
// Finally we can write out the data      
[sData writeToURL:fileURL atomically:YES];

Restoring is the other way around:

// Restore method
NSMutableData *rData = [[NSMutableData alloc]
                         initWithContentsOfURL:locationOfTheFile];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
                         initForReadingWithData:rData];
 
// Initialise the object and use the unarchiver to set the values
Person* p1 = [[[Person alloc] init] autorelease];
p1 =  [unarchiver decodeObjectForKey:@"person"];
 
// set the value on the textfields
[firstNameTextField setStringValue:p1.firstName];
[lastNameTextField setStringValue:p1.lastName];
[ageTextField setStringValue:
                 [NSString stringWithFormat:@"%i",p1.age]];

Here is the source code of the above example with NSSavePanel and NSOpenPanel.