Useful iPhone Code Snippets


How to reorder the table data source after the rows were rearranged

This simple method on NSMutableArray does the trick.
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
    [self.data exchangeObjectAtIndex:fromIndexPath.row withObjectAtIndex:toIndexPath.row];
    [self save];
}
 

Easy way to encode URL parameters

This will return the following URL: http://www.wopata.com/do?q=foo%20bar. Hmm not sure if it encodes spaces only though.
NSURL *theURL = [[NSURL alloc] initWithScheme:@"http" host:@"www.wopata.com" path:@"/do?q=foo bar"];

Limiting Text Field Input

This delegate method prevents more than 10 characters.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *s = [textField.text stringByReplacingCharactersInRange:range withString:string];
    return !([s length] > 10);
}


Load a html file resource into a UIWebView

NSData *info = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"info" ofType:@"html"]];
[webView loadData:info MIMEType:@"text/html" textEncodingName:@"utf8" baseURL:nil];

Check a time delay has passed

This checks if 10 minutes have passed since lastDate was set to [NSDate date] which is the current time.
if([ [NSDate date]  timeIntervalSinceDate: lastDate] > 600){
}

Private properties

This code is from this Apple article.
// MyClass.h
 
@interface MyClass : NSObject
{
    float value;
    NSTextField *textField;
@private
    NSDate *lastModifiedDate;
}
 
@property float value;
@property (retain) IBOutlet NSTextField *textField;
@end
 
// MyClass.m
// Class extension to declare private property
 
@interface MyClass ()
@property (retain) NSDate *lastModifiedDate;
@end
 
@implementation MyClass
@synthesize value;
@synthesize textField;
@synthesize lastModifiedDate;
// implementation continues
@end

Gettting the home folder

On the iPhone every application has its own home folder with a Documents folder inside it. The following snippet uses the NSHomeDirectory function to build a path to an example log file name:
NSString *ds = [NSString stringWithFormat:@"%d", [[NSDate date] timeIntervalSinceReferenceDate]];
NSString *f = [NSString stringWithFormat:@"%@/Documents/log_%@.txt", NSHomeDirectory(), ds];

And another way:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"filename.here"];

Loading an image

The imageNamed: method caches the image, but in many cases that's going to help with memory use. For example, if you load an image 10 times to display along with some text in a table view, UIImage will only keep a single representation of that image in memory instead of allocating 10 separate objects. On the other hand, if you have a very large image and you're not re-using it, you might want to load the image from a data object to make sure it's removed from memory when you're done. A blog post about problems with imageNamed is here.
[UIImage imageNamed:resourceFileName]
 
or
NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
NSData *imageData = [NSData dataWithContentsOfFile:fileLocation];
[UIImage imageWithData:imageData];
 

Support initialisation from code and nibs

If you create a custom view then when you use it from code you would use initWithFrame. But if you use a nib then that isn't called, initWithCoder is used instead. To allow your class to have an initialisation routine done no matter how it is used do the following:
- (void)commonInit
{
    self.userInteractionEnabled = YES;
}
 
- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame])
    {
        [self commonInit];
    }
    return self;
}
 
- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder])
    {
        [self commonInit];
    }
    return self;
}

Singleton

Classes that return one and only one instance of themselves (singletons) are named and implemented as follows:
@implementation MyClass
 
+ (MyClass *)sharedMyClass
{
    static MyClass* shared = nil;
    if (!shared)
        shared = [[MyClass alloc] init];
    return shared;
}

Deselect Table Row

How to deselect a row at the right time. So that it unhighlights the previously selected row when you pop the view controller you were just on. You only need this if you are not using a UITableViewController because it does this automatically.
- (void)viewWillAppear:(BOOL)animated
{
    NSIndexPath *tableSelection = [tableView indexPathForSelectedRow];
    [tableView deselectRowAtIndexPath:tableSelection animated:YES];
}