Chris' Blog.

My occasional thoughts on iOS development, developers careers, trying to make an income from the App Store, and updates on life in general.

iOS8 CoreLocation Permissions

Have you been stung by Core Location when you ported your iPhone app to iOS8? Here was my experience: All calls to locationManager:didUpdateLocations: stopped occurring (eg no more location events came in), and the prompt to the user asking for permission for location access stopped popping up. Something was definitely up. Hopefully I can help you here.

TL;DR -> Jump to the 'How to update your app' subheading below.

Unfortunately, there's no mention of any changes to CoreLocation in the Xcode6 release notes. Indeed, at the time of writing, even apple's class reference does not describe what you need to be doing yet: CLLocationManager.

This is a real shame, because they've overhauled the permissions system, rendering your old apps lifeless. I presume any apps compiled against Xcode 5's iOS7 SDK will continue to work in some kind of 'compatability mode', however once you start compiling in Xcode6, you'll need to deal with this.

New permissions system

It appears that they're basically fed up with people bringing their iPhones into Genius bars, complaining about their battery life, and finding some lousy app that's leaving the GPS turned on while it's in the background.

So they've separated location permissions into two parts: the ability to get locations while the app is activated, and the ability to get location updates while your app is in the background. I guess Apple figures this will make it more obvious to users when an app is going to kill their battery in the background, and save a few trips to the Genius bar.

So now one of the authorisation status enums is deprecated, and two more are in its place:

Deprecated, for iOS7 and below:
kCLAuthorizationStatusAuthorized

For iOS8+
kCLAuthorizationStatusAuthorizedAlways <- For background battery-killers.
kCLAuthorizationStatusAuthorizedWhenInUse <- For sensible apps.

Also, there are now methods you need to call to request permission, instead of the permission prompt automatically appearing as it did in iOS7 and below:

requestAlwaysAuthorization <- 'May I please kill your battery?'
requestWhenInUseAuthorization <- For sensible apps.

How to update your app

So, here's what you need to do. I'm assuming below that you only want foreground access.

Firstly, wherever your app checks the authorizationStatus value, you'll need to compare against the two new enums. To keep your app working across iOS7 and 8, I recommend that before you create a CLLocationManager instance, you should check that authorizationStatus is neither kCLAuthorizationStatusRestricted nor kCLAuthorizationStatusDenied, and disregard the authorised states. If you really need to directly check the authorised states, keep in mind that iOS7's kCLAuthorizationStatusAuthorized == iOS8's `kCLAuthorizationStatusAuthorizedAlways'.

Next, after you instantiate your CLLocationManager, you'll need to call requestWhenInUseAuthorization (or requestAlwaysAuthorization) so that iOS can prompt the user for access. To keep your app compatible with iOS7, do a responds check first. See below:

if ([myLocationManager respondsToSelector:
    @selector(requestWhenInUseAuthorization)]) {
    [myLocationManager requestWhenInUseAuthorization];
}

You can call the above every time you create a location manager, if you've already got permission it won't prompt again, making your code simpler.

Lastly, you need to update your app's info.plist file to have the correct permission prompt. You'll need two keys, the first for iOS7 and the next for iOS8. See below:

<key>NSLocationUsageDescription</key>
<string>My App would pretty please like to use your GPS.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>My App would pretty please like to use your GPS.</string>

Now that step above is dastardly, as that key is undocumented (as far as I can tell) in the CoreLocation reference. If anyone from Cupertino sees this, please nudge your tech writers!

Anyway, hope this gets you un-stuck and enjoying iOS8/Xcode 6. Good luck if you're trying Swift, however I'll give it until at least Xcode 6.1 before I trust it.


A common issue I've encountered with AFNetworking is that, unless you delve into the internals, you get no straightforward way of accessing the response body in the failure callbacks. Now this can be a big issue when your iPhone app is talking to an API that sends you errors with 400 or 500 responses, and you're interested in grabbing the actual error message (or other details) from the response. There are numerous solutions to this, but most of them involve giving up on AFNetworking's convenience methods, which (for me) really is a shame. This solution inserts the response into the NSError that is returned, for minimal impact to the way you deal with AFNetworking 2, in a similar way as used to work with AFNetworking 1.

All told, here is how you would use my solution, if you apply my steps further down this post:

[[MySessionManager sharedManager] POST:@"my-api" parameters:myParams success:^(NSURLSessionDataTask *task, id responseObject) {
    ...
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    id responseObject = error.userInfo[kErrorResponseObjectKey];
    ... great! You've got the response for an error now ...
}];

AFHTTPSessionManager subclass

First for a bit of groundwork. I've found it to be a good practice to subclass AFHTTPSessionManager, and manage your session manager singleton in said subclass. This subclass will come in handy later for capturing the error response bodies. So lets get started with the below:

//  MySessionManager.h

#import "AFHTTPSessionManager.h"

#define kErrorResponseObjectKey @"kErrorResponseObjectKey"

@interface MySessionManager : AFHTTPSessionManager

/// The singleton. Use this to talk to your API.
+ (instancetype)sharedManager;

@end

...

//  MySessionManager.m

#import "MySessionManager.h"

#if DEBUG
    static NSString *kBaseUrl = @"http://testapi.myapp.com/v1/";
#else
    static NSString *kBaseUrl = @"https://api.myapp.com/v1/";
#endif

@implementation MySessionManager

+ (instancetype)sharedManager {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] initWithBaseURL:[NSURL URLWithString:kBaseUrl]];
    });
    return instance;
}

@end

Tip: You could use initWithBaseURL:sessionConfiguration: above if you'd like to customise your configuration, eg have a common HTTP header that you'd like to send with all your API requests.

To use the above singleton to access your API's (this will not capture errors yet, but it gives you the idea), you can do the below:

[[MySessionManager sharedManager] GET:@"some-endpoint" parameters:myParams success:^(NSURLSessionDataTask *task, id responseObject) {
    ...
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    ...
}];

Which, in itself, is quite a neat and tidy way of using AFNetworking 2. I hope the above, in and of itself, is useful for you :)

Grabbing the errors

Next, we want to override dataTaskWithRequest:completionHandler: in the subclass, so that it wraps the completion handler with a 'shim' which puts the response body into the NSError, before calling the original completion handler. Here it is below:

//  MySessionManager.m continued...

/// This wraps the completion handler with a shim that injects the responseObject into the error.
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
                            completionHandler:(void (^)(NSURLResponse *, id, NSError *))originalCompletionHandler {
    return [super dataTaskWithRequest:request
                    completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {

        // If there's an error, store the response in it if we've got one.
        if (error && responseObject) {
            if (error.userInfo) { // Already has a dictionary, so we need to add to it.
                NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
                userInfo[kErrorResponseObjectKey] = responseObject;
                error = [NSError errorWithDomain:error.domain
                                            code:error.code
                                        userInfo:[userInfo copy]];
            } else { // No dictionary, make a new one.
                error = [NSError errorWithDomain:error.domain
                                            code:error.code
                                        userInfo:@{kErrorResponseObjectKey: responseObject}];
            }
        }

        // Call the original handler.
        if (originalCompletionHandler) {
            originalCompletionHandler(response, responseObject, error);
        }
    }];
}

And that's it! Your failure callbacks will now be able to access errors as described at the start of this article, as follows:

id responseObject = error.userInfo[kErrorResponseObjectKey];

Hope it's helpful :)


Say you've got a form, such as a 'sign up' form on your iPhone app, and this view controller is basically a screenful of UITextFields. How do you best make the fields scroll out of the way of the keyboard so that they are visible, as you tab between them? Here's my favourite way to do so. It's effective and simple, animates perfectly, and the code is very clean as it takes care .

If you're just after the code and don't want to read this whole article, here it is: ScrollingFormDemo

Basically the gist of it is to create a UIViewController whose root view is a subclass of UIScrollView. This scroll view contains many UITextFields. The UIViewController listens to the keyboard appearance notifications, and adjusts the UIScrollView's contentInset to suit. And UIKit automagically scrolls the scroll view so that the focused UITextField is in the visible area - you get that part for free!

The views

And here it is in some more detail. Here's how I create my UIScrollView subclass, which is to become the root view of my UIViewController:

//  MyFormView.h
//  This is the root view for MyFormViewController.

#import <UIKit/UIKit.h>

@interface MyFormView : UIScrollView

@property(nonatomic, readonly) UITextField *topField;
@property(nonatomic, readonly) UITextField *bottomField;

@end

Nothing much to report on in the above code, just a UIScrollView subclass, with the two fields exposed as readonly properties. Now, these fields actually get created in the .m file, below:

//  MyFormView.m

#import "MyFormView.h"

static int kMargin = 10;
static int kFieldHeight = 40;

@implementation MyFormView

- (id)init {
    if (self = [super init]) {
        self.backgroundColor = [UIColor lightGrayColor];

        // Make the top field.
        _topField = [[UITextField alloc] init];
        _topField.borderStyle = UITextBorderStyleRoundedRect;
        _topField.placeholder = @"Top field";
        _topField.returnKeyType = UIReturnKeyNext;
        [self addSubview:_topField];

        // Make the bottom field.
        _bottomField = [[UITextField alloc] init];
        _bottomField.placeholder = @"Bottom field";
        _bottomField.borderStyle = UITextBorderStyleRoundedRect;
        _bottomField.returnKeyType = UIReturnKeyDone;
        [self addSubview:_bottomField];
    }
    return self;
}

Again, no magic above: just the init method of the UIScrollView subclass creates the fields and adds them to itself. So the hierarchy will be: UIViewController -> UIScrollView as root view -> UITextField, except that I've created a UIScrollView subclass.

And MyFormView is also responsible for positioning the fields at the top and bottom of the screen, shown below. In real life, you'd likely stack the UITextFields on top of each other, rather than tracking the bottom of the screen. However, if i made a dozen different text fields then this sample code would be too long for illustrative purposes. See below:

//  MyFormView.m continued...

- (void)layoutSubviews {
    [super layoutSubviews];

    int w = self.bounds.size.width;
    int h = self.bounds.size.height;
    int t = self.contentInset.top; // Size of the nav+status bars.

    // Pin this field to the top. No need to take account for the nav bar height, as the
    // scroll view's contentInset takes care of that.
    _topField.frame = CGRectMake(kMargin, kMargin, w - 2*kMargin, kFieldHeight);

    // Pin this to the bottom. We do need to take account for the content inset height
    // here so that it's not offscreen.
    _bottomField.frame = CGRectMake(kMargin, h - t - kFieldHeight - kMargin,
                                    w - 2*kMargin, kFieldHeight);

    // Set the content size to fit the bottom field plus some padding.
    self.contentSize = CGSizeMake(w, CGRectGetMaxY(_bottomField.frame) + kMargin);
}

@end

So that's it for the views. Next up, the view controllers.

The view controller

The view controller is simple enough. Here is the header file:

//  MyFormViewController.h
//  This demonstrates a form with many fields that needs to scroll them to visibility when the keyboard appears.

#import <UIKit/UIKit.h>

@interface MyFormViewController : UIViewController <UITextFieldDelegate>

@end

The only interesting thing is that the above implements UITextFieldDelegate. As you'll see later, this isn't used for the purposes of the scrolling effect that is the main point of this article, it is just so that there is the ability to tap 'next' to jump to the next UITextField, and 'done' to close the keyboard.

Below is the code for creating the view controller in such a way that my UIScrollView subclass is its root view:

//  MyFormViewController.m
//  This demonstrates a form with many fields that needs to scroll them to visibility when the keyboard appears.

#import "MyFormViewController.h"

#import "MyFormView.h"

@implementation MyFormViewController {
    MyFormView *_view;
}

- (id)init {
    if (self = [super init]) {
        self.title = @"My Form";
    }
    return self;
}

- (void)loadView {
    _view = [[MyFormView alloc] init];
    self.view = _view;
}

You could achieve the same view hierarchy with a XIB / Storyboard quite simply I imagine, however I'll leave that as an exercise to the reader if you prefer to use interface builder. Basically in the loadView method, we instantiate a MyFormView and set it as the root view with self.view = _view. You may note that nowhere is the frame being set, because it'll be set by the containing UINavigationController for us.

Once the view has loaded, we want to subscribe to keyboard notifications. You can see that below:

//  MyFormViewController.m continued...

- (void)viewDidLoad {
    [super viewDidLoad];

    _view.topField.delegate = self;
    _view.bottomField.delegate = self;

    // Listen for the keyboard.
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

And exactly what we do with those keyboard notifications is probably the most interesting part of this article, and is shown below:

//  MyFormViewController.m continued...

#pragma mark - Keyboard notifications

- (void)keyboardWillShow:(NSNotification *)notification {
    // Figure out the size of the keyboard.
    CGRect frame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];

    // Add the keyboard size to the bottom content inset of the scroll view.
    UIEdgeInsets inset = _view.contentInset;
    inset.bottom = frame.size.height;
    _view.contentInset = inset;

    // Same for the scroll inset, so it looks right.
    UIEdgeInsets scrollInset = _view.scrollIndicatorInsets;
    scrollInset.bottom = frame.size.height;
    _view.scrollIndicatorInsets = scrollInset;
}

- (void)keyboardWillHide:(NSNotification *)notification {
    float duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];

    // Animate the scroll insets away, with an animation that matches the keyboard sliding down.
    [UIView animateWithDuration:duration animations:^{
        // Remove the insets.
        UIEdgeInsets inset = _view.contentInset;
        inset.bottom = 0;
        _view.contentInset = inset;

        // Same for the scroll inset, so it looks right.
        UIEdgeInsets scrollInset = _view.scrollIndicatorInsets;
        scrollInset.bottom = 0;
        _view.scrollIndicatorInsets = scrollInset;
    }];
}

Here's what the above code does: When the keyboard is about to appear, we increase the bottom content insets so that even though the scroll view still goes under the keyboard, it scrolls far enough so that the lowest content is above the keyboard. This doesn't need to be animated, as the UITextField animates itself into a visible position automagically.

When the keyboard hides, we re-set the bottom insets to zero. Now this needs to be animated, because if it wasn't it would force the content to jump quickly. The animation duration is matched to the keyboard animation so that it all looks perfect.

And there's a little more code to handle the text delegate, as you can see none of the scrolling logic is involved here:

//  MyFormViewController.m continued...

#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if (textField == _view.topField) {
        [_view.bottomField becomeFirstResponder];
    }
    if (textField == _view.bottomField) {
        [textField resignFirstResponder];
    }
    return NO;
}

@end

Launching

To launch this demo, i've included a little boilerplate in the app delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Make the view controller stack.
    MyFormViewController *form = [[MyFormViewController alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:form];

    // Make the window.
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];

    return YES;
}

And that's it! If you'd like to see it all, here it is on github: ScrollingFormDemo


You can see older posts in the right panel, under 'archive'.

Archive

Getting Core Location / CLLocationManager to work on iOS8 14 Sep 2014

Accessing the response body in failure blocks with AFNetworking 2 10 Sep 2014

How to allow your UITextFields to scroll out of the way of the keyboard 8 Sep 2014

How to subclass UIButton in iOS7 and make a UIButtonTypeSystem 4 Sep 2014

New season 1 Aug 2014

House finished 17 Jun 2014

WebP decoding on iOS 9 Feb 2014

Moving on again 22 Jan 2014

Lossy images for retina iPads - JPEG vs WebP 30 Nov 2013

Career options I wish I knew about when I was younger 20 Oct 2013

Positivity and your friends 7 Oct 2013

Tactility 26 Jul 2013

WWDC-induced narcolepsy 15 Jul 2013

Back on rails 31 May 2013

Full circle 6 May 2013

Programmatic UI on iOS 3 May 2013

Screencasts and positivity 8 Apr 2013

Year of positivity 14 Mar 2013

iOS Dev State of the Union 6 Feb 2013

Adventures with IAPs 3 Feb 2013

No longer a Googler 23 Dec 2012

Localising iPhone apps with Microsoft Translator 8 Dec 2012

Fight back (app biz update 13) 12 Nov 2012

Sent to the backburner (app biz update 12) 25 Oct 2012

Lisi Schappi 7 Oct 2012

Today's happy plateau (app biz update 11) 26 Aug 2012

First week's sales of Today (app biz update 10) 19 Aug 2012

Today launch! And a difficult decision made... (app biz update 9) 15 Aug 2012

Approved! (app biz update 8) 5 Aug 2012

Creating a graph in Objective-C on the iPhone 3 Aug 2012

Hurry up and wait (app biz update 7) 30 Jul 2012

Today app marketing site 27 Jul 2012

Today app submitted 25 Jul 2012

UIAlertView input wrapper 24 Jul 2012

Mentoring 23 Jul 2012

This is too hard! (app biz update 6) 20 Jul 2012

Perspectives (app biz update 5) 9 Jul 2012

4th starting-my-own-biz update 1 Jul 2012

ScrumFox landing page 28 Jun 2012

Server Scope landing page 27 Jun 2012

Telstra Calls and Data Usage 26 Jun 2012

Service History + Dropbox 26 Jun 2012

Impromptu Presenter 26 Jun 2012

Fertility Tracker 26 Jun 2012

Baby Allergy Tracker 26 Jun 2012

Starting my own business, update 3 22 Jun 2012

Starting my own business, update 2 17 Jun 2012

Starting my own business - First update 10 Jun 2012

I must be crazy 6 Jun 2012

Finding your location on an iPhone 7 May 2012

A generous career 4 May 2012

Skeleton Key Cocoaheads presentation 3 May 2012

CHBgDropboxSync - Dropbox auto-sync for your iOS apps 1 May 2012

That book about that Steve Jobs guy 30 Apr 2012

Another app marketing idea 23 Apr 2012

Sweet grouped tables on the iPhone 17 Apr 2012

Skeleton Key App 11 Apr 2012

Another app marketing idea... 5 Apr 2012

Quickly check for any missing retina graphics in your project 3 Apr 2012

Skeleton Key Password Manager with Dropbox 2 Apr 2012

RC Boat motor finally mounted 2 Apr 2012

Promoting apps presentation slides 1 Apr 2012

How i just wasted a month on my latest app, and how you don't need to 26 Mar 2012

The Finishing Line 20 Mar 2012

Using Launchd to run a script every 5 mins on a Mac 20 Feb 2012

Generating AES256 keys from a password/passphrase in ObjC 20 Feb 2012

Indie iPhone app marketing, part 2 19 Feb 2012

My App Manifesto: Syncing + Dropbox + YAML = Awesome 15 Feb 2012

Indie iPhone App Marketing part 1 7 Feb 2012

Perspectives 2 Feb 2012

Accountability and Free Will 1 Feb 2012

Badassery 31 Jan 2012

Sacrifice 30 Jan 2012

Lead Yourself First 29 Jan 2012

How to ping a server in Objective-C / iPhone 26 Jan 2012

iOS Automated Builds with Xcode4 16 Jan 2012

Xcode 4 - Command line builds of iPhone apps 15 Jan 2012

Guest post by Jason McDougall 13 Jan 2012

Scouts, Games and Motivation 10 Jan 2012

2011 Re-cap 8 Jan 2012

Ruby script to increment a build number 4 Jan 2012

Turning 30? All ideas, no execution? 18 Dec 2011

CHDropboxSync - simply sync your iOS app's documents to Dropbox 14 Dec 2011

Deep-enumerating a directory on the iphone, getting file attributes as you go 10 Dec 2011

Getting a date without the time component in objective-c 6 Dec 2011

Memory management in Objective-C 4 Dec 2011

Starting small 29 Nov 2011

Dictionary Types Helper 29 Nov 2011

Observer Pattern in Objective-C 16 Nov 2011

Why you should give presentations 13 Nov 2011

How to get a programming or design job in Sydney 9 Nov 2011

Custom nav bar / toolbar backgrounds in iOS5 8 Nov 2011

Stuck 27 Oct 2011

Dead easy singletons in Obj-C 19 Oct 2011

JSON vs OCON (Objective-C Object Notation) 18 Oct 2011

In defence of Objective-C 16 Oct 2011

Update the MessagePack objective-c library to support packing 12 Oct 2011

Icons 11 Oct 2011

How to host a site on Amazon AWS S3, step-by-step 7 Oct 2011

Drawing a textured pattern over the default UINavigationBar 6 Oct 2011

Markdown Presentations 1 Oct 2011

More MegaComet testing: Ruling out keepalives 15 Sep 2011

MegaComet test #4 - This time with more kernel 14 Sep 2011

Building People 10 Sep 2011

Half way there: Getting MegaComet to 523,000 concurrent HTTP connections 5 Sep 2011

Making a progress bar in your iPhone UINavigationBar 22 Aug 2011

Hacker News Reader 20 Aug 2011

How to programmatically resize elements for landscape vs portrait in your iphone interface 16 Aug 2011

MegaComet testing part 2 3 Aug 2011

Australian Baby Colours 28 Jul 2011

Boat prop shaft 25 Jul 2011

Megacomet with 1 million queued messages 24 Jul 2011

Installed the strut and rudder 18 Jul 2011

Painted the inside of the boat 17 Jul 2011

Fuzzy iphone graphics when using an UIImageView set to UIViewContentModeCenter 13 Jul 2011

My 3 Data and Calls Usage 11 Jul 2011

Reading a line from the console in node.js 10 Jul 2011

Trim whitespaces on all text fields in a view controller 9 Jul 2011

Final finish 9 Jul 2011

MessagePack parser for Objective-C / iPhone 30 Jun 2011

Lacquering the starboard side 25 Jun 2011

What do do with EXC_ARM_DA_ALIGN on an iPhone app 23 Jun 2011

Lacquering the hull 23 Jun 2011

Staining the boat 22 Jun 2011

NSMutableSet with weak references in objective-c 20 Jun 2011

Iphone gesture recogniser that works for baby games 20 Jun 2011

Image manipulation pixel by pixel in objective C for the iphone 19 Jun 2011

Baby Allergy Tracker 12 Jun 2011

Power sanding the deck 10 Jun 2011

Planing the edge of the deck 2 Jun 2011

Figured out the deck 2 Jun 2011

Boat bulkheads 2 Jun 2011

Simulating iOS memory warnings 31 May 2011

Putting a UIButton in a UIToolbar 29 May 2011

How to allow closing a UIActionSheet by tapping outside it 29 May 2011

Finding the currently visible view in a UITabBarController 24 May 2011

Random Chef 17 May 2011

Centered UIButton in a navigation bar on the iphone 16 May 2011

Little Orchard 13 May 2011

Boat update 13 May 2011

How to get the current time in all time zones for the iphone / obj-c 12 May 2011

Design portfolio 10 May 2011

Tricks with grand central dispatch, such as objective-c's equivalent to setTimeout 9 May 2011

How to make an iphone view controller detect left or right swipes 5 May 2011

Centered section headers on a UITableView 5 May 2011

Christmas in may 4 May 2011

Finished trimming the boat (its floatable now!) and got some parts 29 Apr 2011

How to make a multiline label with dynamic text on the iphone and get the correct height 27 Apr 2011

Forcing an image size on the image in a table view cell on an iphone 20 Apr 2011

Git on the Mac 19 Apr 2011

Build a url query string in obj-c from a dictionary of params like jquery does 12 Apr 2011

Rendering a radial gradient on the iphone / objective-c 11 Apr 2011

Skinning the port side of the boat 8 Apr 2011

Skinning the side of the boat 5 Apr 2011

Sending a UDP broadcast packet in C / Objective-C 5 Apr 2011

How to talk to a unix socket / named pipe with python 4 Apr 2011

Skinning the bottom of the boat 31 Mar 2011

Service discovery using node.js and ssdp / universal plug n play 30 Mar 2011

Extremely simple python threading 29 Mar 2011

New rescue boat 26 Mar 2011

HttpContext vs HttpContextBase vs HttpContextWrapper 5 Nov 2010

Simple C# Wiki engine 30 Sep 2010

Simple way to throttle parts of your Asp.Net web app 29 Sep 2010

How to implement DES and Triple DES from scratch 4 Aug 2010

How to use sessions with Struts 2 30 Jul 2010

How to use Cookies in Struts 2 with ServletRequest and ServletResponse 30 Jul 2010

Using Quartz Scheduler in a Java web app (servlet) 27 Jul 2010

Javascript date picker that Doesn't Suck!(tm) 27 Jul 2010

Using Oracle XE with Hibernate 20 Jul 2010

A simple implementation of AES in Ruby from scratch 29 Jun 2010

Asp.Net Forms authentication to your own database 28 May 2010

AS2805 (like ISO8583) financial message parser in C# 7 May 2010

Ruby hex dumper 4 May 2010

Using Spring to manage Hibernate sessions in Struts2 (and other web frameworks) 13 Jan 2010

Emails in C#: Delivery and Read receipts / Attachments 12 Jan 2010

Using Java libraries in a C# app with IKVM 16 Dec 2009

Learning Java tutorial 27 Nov 2009

Using generic database providers with C# 17 Nov 2009

Scheduled task executable batch babysitter 29 Oct 2009

Working with query strings in Javascript using Prototype 30 Sep 2009

Still fighting with String.Format? 9 Sep 2009

How I'd build the next Google 24 Aug 2009

Getting IIS and Tomcat to play nicely with isapi_redirect 24 Aug 2009

Using the new ODP.Net to access Oracle from C# with simple deployment 11 Aug 2009

C# Cryptography - Encrypting a bunch of bytes 14 Jul 2009

Sorting enormous files using a C# external merge sort 10 Jul 2009

Reconciling/comparing huge data sets with C# 9 Jul 2009

Some keyboard-friendly DHTML tricks 10 Jun 2009

How to figure out what/who is connected to your SQL server 18 Mar 2009

Adding a column to a massive Sql server table 16 Mar 2009

Multithreading using Delegates in C# 10 Mar 2009

Using C# locks and threads to rip through a to-do list 6 Feb 2009

Using threads and lock in C# 3 Feb 2009

Setting a form name and onsubmit using form_for in rails 2 14 Jan 2009

Compressing using the 7Zip LZMA algorithm in C# beats GZipStream 14 Jan 2009

Bare minimum HTML that validates 22 Dec 2008

MS Sql Server 2005 locking 17 Dec 2008

Simple Comet demo for Ruby on Rails 19 Nov 2008

Geocoding part 2 - Plotting postcodes onto a map of Australia with C# 24 Oct 2008

Using evolutionary algorithms to make a walkthrough for the light-bot game with C# 20 Oct 2008

How to tell when memory leaks are about to kill your Asp.Net application 16 Oct 2008

C# version of isxdigit - is a character a hex digit? 15 Sep 2008

Geocoding part 1 - Getting the longitude and latitude of all australian postcodes from google maps 26 Aug 2008

Converting HSV to RGB colour using C# 14 Aug 2008

Opening a TCP connection in C# with a custom timeout 11 Aug 2008

Oracle Explorer - a very simple C# open source Toad alternative 31 Jul 2008

Linking DigitalMars' D with a C library (Mongrel's HTTP parser) 23 Jun 2008

Connecting to Oracle from C# / Winforms / Asp.net without tnsnames.ora 16 Jun 2008

A simple server: DigitalMars' D + Libev 6 Jun 2008

Travelling from Rails 1 to Rails 2 9 Apr 2008

Rocketsale 9 Apr 2008

Online Rostering System 9 Apr 2008

DanceInforma 9 Apr 2008

Client Analyser 9 Apr 2008

How good is this??? 16 Dec 2007

Using RSS or Atom to keep an eye on your company's heartbeat 10 Nov 2007

Easy Integrated Active Directory Security in ASP.Net 24 Oct 2007

First post 17 Oct 2007