Multi Timer free until the end of the month
October 17, 2013
My app, Multi Timer, will be free until the end of October 2013 at which point it will (probably) go back to the usual price of $0.99
October 17, 2013
My app, Multi Timer, will be free until the end of October 2013 at which point it will (probably) go back to the usual price of $0.99
October 8, 2013
When Apple releases new versions of iOS they often add new default fonts, and iOS 7 is no different - although maybe especially notable for its thin variants of Helvetica Neue, which is one of almost 40 new font styles added in iOS 7. The following list was generated by listing the fonts on an iOS 6 device with a couple of handy methods on UIFont, doing the same on iOS 7, finding the differences with a simple Python script and then creating a simple table view which I screen shotted. I’ve also got the full lists on my GitHub account.

October 6, 2013
The following category method will allow you to iterate over the characters of an NSString with a block:
-(void)enumerateCharacters:(EnumerationBlock)enumerationBlock
{
const unichar * chars = CFStringGetCharactersPtr((__bridge CFStringRef)self);
//Function will return NULL if internal storage of string doesn't allow for easy iteration
if (chars != NULL)
{
NSUInteger index = 0;
while (*chars) {
enumerationBlock(*chars, index);
chars++;
index++;
}
}
else
{
//Use IMP/SEL if the other enumeration is unavailable
SEL sel = @selector(characterAtIndex:);
unichar (*charAtIndex)(id, SEL, NSUInteger) = (typeof(charAtIndex)) [self methodForSelector:sel];
for (NSUInteger i = 0; i < self.length; i++)
{
const unichar c = charAtIndex(self, sel, i);
enumerationBlock(c, i);
}
}
}October 4, 2013
I’ve added the following new features to Keep Calm 2.31:
October 2, 2013
One of the more annoying parts of working on iOS project is generating all of the appropriate artwork - there are up to 13 different images that you have to create just for the app icon. Several apps exist for this, however I figured a simpler solution would be to have a simple shell script:
#!/bin/sh
ITUNES_ARTWORK="$1"
FOLDER=$(dirname "$ITUNES_ARTWORK")
sips -z 57 57 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon.png"
sips -z 114 114 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon@2x.png"
sips -z 120 120 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-60@2x.png"
sips -z 29 29 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-Small.png"
sips -z 58 58 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-Small@2x.png"
sips -z 40 40 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-Small-40.png"
sips -z 80 80 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-Small-40@2x.png"
sips -z 50 50 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-Small-50.png"
sips -z 100 100 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-Small-50@2x.png"
sips -z 72 72 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-72.png"
sips -z 144 144 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-72@2x.png"
sips -z 76 76 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-76.png"
sips -z 152 152 "$ITUNES_ARTWORK" --out "${FOLDER}/Icon-76@2x.png"Here’s what you need to do to set it up:
In case you haven’t come across it before, sips is a really simple way of quickly resizing images on the command line on OSX.
October 2, 2013
After seeing a successful opening weekend, I’ve updated Blurred Camera with the following new features:
September 28, 2013

Blurred Camera is a new free iOS app that I’ve been working on that makes it really easy to create blurry photos that you can use as your wallpaper. The app allows you to vary how much the image is blurred by pinching and also allows you to adjust the brightness and saturation by swiping.
The app is really quite simple (I threw it together in a couple of evenings) and based off of GPUImage.
September 24, 2013
I’m pleased to announce that if you want to use ObjectiveGumbo, my Objective-C wrapper around Google’s awesome HTML5 parser Gumbo, in your iOS projects you can now install it via CocoaPods. Simply add the following to your podfile to get started:
platform :ios, '6.0'
pod "ObjectiveGumbo", "0.1"
You will then need to run pod install and open the Xcode workspace file, not your project. You can then import the ObjectiveGumbo.h file into your project to begin working with it.
I soon plan to publish a guide that will help you get started using ObjectiveGumbo with AFNetworking 2.
September 24, 2013
Now that AFNetworking 2 is out and ObjectiveGumbo is now available on CocoaPods I thought I would write a simple guide showing you how you can build a simple app that uses HTML files as a data source through AFNetworking. This post shows how to write an app that will find the top read articles on BBC News, list them and allow the user to visit them. You can find the source in the ObjectiveGumbo demos repository.
AFNetworking 2 currently requires iOS 7 due to its new reliance on NSURLSession (a new iOS 7 framework for working with URL requests and connections), so you’ll need to add the following to your Podfile and execute ‘pod install’ to download the dependencies:
platform :ios, '7.0'
pod "ObjectiveGumbo", "0.1"
pod "AFNetworking", "2.0.0-RC3"
If you are unfamiliar with CocoaPods, they have a setup guide on their website.
One of the great new features of AFNetworking 2 is that serializers are now abstracted away from the core URL requesting code. This means that you can easily write a response serialiser that will take an NSData object and convert it into something useful - AFNetworking ships with classes that you can subclass that will serialize XML or JSON into NSDictionarys for example.
To build a custom response serializer to decode the NSData response from the web server into an OGDocument (the base class of a document parsed by ObjectiveGumbo) you will need to subclass AFHTTPResponseSerializer into HTMLResponseSerializer and implement the following method:
-(id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
return [ObjectiveGumbo parseDocumentWithData:data];
}(The full code for the .h and .m files are in the repo linked above)
Whilst having the data as an OGDocument might be fine for your application, you will probably want to feed it back custom objects that are relevant to your application. In this example I’m going to parse the list on the BBC site of most read articles and put it into an Article class with a link and title.
You will need to subclass the HTMLResponseSerializer into BBCResponseSerializer, and again implement the responseObjectForResponse:data:error: method:
-(id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
//1
OGDocument * document = [super responseObjectForResponse:response
data:data
error:error];
//2
NSArray * panels = [document select:@".panel"];
NSMutableArray * articles = [NSMutableArray new];
//3
//The list of most read articles is in the second panel
OGElement * list = (OGElement*)[panels[1] first:@"ol"];
//4
for (OGElement * listItem in [list select:@"li"])
{
//5
OGElement * link = (OGElement*)[listItem first:@"a"];
NSString * href = link.attributes[@"href"];
//Whitespace and the span are the first two elements
NSString * title = [link.children[2] text];
//6
Article * article = [Article new];
article.title = title;
article.link = [NSURL URLWithString:href];
[articles addObject:article];
}
//7
return articles;
}Now that we’ve written methods for parsing the data, presenting it is fairly trivial. Here is the code for my master view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://bbc.co.uk/news"]];
AFHTTPRequestOperation * operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [BBCResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
self.articles = (NSArray*)responseObject;
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"%@", error.localizedDescription);
}];
[operation start];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.articles.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
Article * article = self.articles[indexPath.row];
cell.textLabel.text = article.title;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Article * article = self.articles[indexPath.row];
[[segue destinationViewController] setDetailItem:article];
}
}September 21, 2013
Apple has now approved the updated version of another of my apps, Multi Timer. The new update to Multi Timer vastly enhances the UI on iOS 7, fixes a few bugs and adds a few more icons for your timers.
Head over to the App Store to download Multi Timer for $0.99.
| ← Newer | Older → |