iOS 24 Hour date format

If you are using NSDateFormatter to send dates back to a server be VERY careful.  Specifying a date format string as follows…


and the time for example is currently  09/10/2013  14:00:00, if the user has set their clock to be a 12-hour clock, instead of the default 24-hour clock. You will get a string back of…

2013-10-09T02:00:00 PM

The users preferences overwrite what you are asking for!!

Read the following documentation -

The following sample code from that article will always return a 24-hour clock value regardless of user preferences

<br /><br />NSDateFormatter *rfc3339DateFormatter = [[NSDateFormatter alloc] init];<br /><br />NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];<br /><br />[rfc3339DateFormatter setLocale:enUSPOSIXLocale];<br /><br />[rfc3339DateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];<br /><br />[rfc3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];<br /><br />NSDate *date = [rfc3339DateFormatter dateFromString:rfc3339DateTimeString];<br /><br />

Open doors effect at App launch

This is a copy of a blog entry I originally wrote for ios-blog

There are a number of apps in the App Store that launch with a set of closed doors, these are then opened to present the actual UI underneath it.

I had to create this effect for an app I wrote for a client

I’d assumed when I started that this would be a relatively simple task, just take the initial default image, cut it in half and a simple bit of animation would move them out of the way. What I hadn’t counted on is getting the orientation of the device from launch is not straightforward. The trick is to remember that the first view that is loaded will always assume it’s in Portrait mode, the view is then informed via the willRotate method that in fact the orientation is different and you can then handle this appropriately. The second trick is knowing that the willRotate takes a little bit of time to fire, so it’s now a simple case of delaying the call to the method that handles the animation.

The viewWillAppear method loads the images assuming that the view is in portrait and sets up a timer to call the openDoors method

-(void)viewWillAppear:(BOOL)animated {
    //All apps start in portrait mode, with the home button at the bottom,
    //If the device is being held with the home button in any other location then a
    //willRotate is fired!
    isPortrait = YES;
    doorsClosed = YES;

    //We assume we are in portrait mode until told otherwise
    self.leftDoor.image = [UIImage imageNamed:@"DoorLeftiPadPortrait.png"];
    self.rightDoor.image = [UIImage imageNamed:@"DoorRightiPadPortrait.png"];
    self.backgroundSplash.image = [UIImage imageNamed:@"SlideBackgroundiPadPortrait.png"];

    //Add a delay to the open doors sequence, this allows the OS to determine
    //the correct orientaion and fire the all important willRotate

    [NSTimer scheduledTimerWithTimeInterval: 3.5
                                     target: self
                                   selector: @selector(openDoors)
                                   userInfo: nil
                                    repeats: NO];

The willRotate method then ensures that the correct image is loaded

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    isPortrait = UIDeviceOrientationIsPortrait(toInterfaceOrientation);
    if (!isPortrait) {
        //If the doors haven't already been opened then change them to the landscape ones
        if (doorsClosed) {
            self.leftDoor.image = [UIImage imageNamed:@"DoorLeftiPadLandscape.png"];
            self.rightDoor.image = [UIImage imageNamed:@"DoorRightiPadLandscape.png"];
        self.backgroundSplash.image = [UIImage imageNamed:@"SlideBackgroundiPadLandscape.png"];
    } else {
        self.backgroundSplash.image = [UIImage imageNamed:@"SlideBackgroundiPadPortrait.png"];

The openDoors method then just works out how far to move the images and kicks of the animation, I’ve included the old UIView beginAnimation and the Blocks way

-(void)openDoors {
    //Determine how far the doors need to move for them to disappear from view
    float adjust = (CGRectGetWidth(self.view.frame) > CGRectGetHeight(self.view.frame)) ? CGRectGetWidth(self.view.frame) : CGRectGetHeight(self.view.frame);
    //Retrieve the original frame and then adjust the X position accordingly
    CGRect leftFrame = self.leftDoor.frame;
    CGRect rightFrame = self.rightDoor.frame;;

    leftFrame.origin.x = -adjust;
    rightFrame.origin.x += adjust;

//Old School Animation

//Set up the animation, change the frames and commit it
//	[UIView beginAnimations:@"swipe" context:nil];
//	[UIView setAnimationDuration:1.2];
//	[UIView setAnimationDelay:0.0];
//	[UIView setAnimationDelegate:self];
//      self.leftDoor.frame = leftFrame;
//	self.rightDoor.frame = rightFrame;
//	[UIView commitAnimations];

    [UIView animateWithDuration:1.2
                        self.leftDoor.frame = leftFrame;
                        self.rightDoor.frame = rightFrame;

    doorsClosed = NO;

Note this effect only works if the app is launching for the first time, i.e. not from the background.

I’ve put together a sample project that puts this all into practice

Hope you find this useful, or if you have a better way of creating the same effect please let me know

See what I do

Mobile Apps – Ballpark Costs

When potential clients ask for a ballpark figure on development costs, these are the questions I ask to help clarify whats required and therefore affect the cost. They are in no particular order…

  • What are the target platforms, iPhone, iPad, Android, Windows Mobile?
  • If they want multiple platforms are they aware that native apps are developed using different languages
  • If iPhone do you want a universal version, i.e. the same app runs on iPhone and iPad (thanks @ithain)
  • Whats the target audience?
  • Do you have an idea of how you want the app to flow?
  • Are there existing apps out there that do something similar, if there are what are they and what will make this one different?
  • Are there existing apps that you like the style of or the way they work?
  • Will you apply for your own developers licences so that the app is submitted under your name?
  • Will the app be free, sold for a one off fee, have in-app purchases or have subscriptions?
  • Who will supply the artwork?
  • Does the app need to be location aware?
  • Ideas of timescale for release? (thanks @MrAntix)
  • Are there any hosting requirements? (thanks @MrAntix)
  • Third party services integration requirements? (thanks @MrAntix)
  • Any social media integration?
  • Any security requirements, OAuth, Encryption, etc? (thanks Gary)
  • What is the lowest version of the operating system for a device that needs to be supported
  • Does the app need to support Push Notifications, if yes how will they be delivered in house or third party (UrbanAirship)

And if the app contains dynamic data the following are also important questions…

  • How will the app access the data?
  • Have the web services that supply the information been designed/written?
  • Would you require a content management system to update information contained in the app?
  • If its a Corporate app, what back end data do you need to access and synchronise (thanks @ithain)

Update 2 Extra items thanks to @adrian_bigland

  • how many languages need to be supported
  • who will do the translation
  • how will translations be tested – often you need to write code to present all the error dialogs etc. for ease of checking.
  • different UI layouts, or will all the languages fit? German always stresses label lengths, and non FIGS languages might need their own screens, in extreme cases.

Offline support:

  • do you need to store data from web services, so that when you are offline, the experience is seamless?
  • can the user upload information from the app? You often need to store events for analytics while offline, for example.
  • are you going to have problems merging external and local changes? (This way, madness lies).

Custom components?

End of update

Obviously the answers to these questions are likely to lead to more specific questions, but it helps with the thought process involved with what might be required

I would be really interested to know if there are any other questions you ask that I’ve not included?

UPDATE: The first question I am going to start asking is if they have a budget in mind, some projects can be completed in 5 days, some in 5 months, but if they think that they can get the next instagram for £1K, they are wasting my time and their own.

UPDATE: Yeeply are currently sponsoring a site that gives rough calculations – its not got all the options and doesn’t allow you to select multiple platforms but it will give you some idea of  cost ranges App cost calculator – lovely interface – needs a few more options –

See what I do

AirPrint – direct to the Printer

If you have an AirPrint enabled printer and an iPhone/iPad running iOS4.2 or above you can print directly to the printer without the need for both devices to be connected through the same WiFi access point. On your iOS device, go to your WiFi settings and in the list of networks you should see an entry that relates to the printer (so long as you are in range), and hey presto it all works

PanGesture with multiple subviews

The following code snippet is based on the iPhone documentation for handling the pan gesture, although theres still used the translate method which has been replaced. The method also caters for panning all of the views subviews so that everything moves.

- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)sender {
	static CGPoint prevTranslate;

    CGPoint translate = [sender translationInView:self.OfficeImage];
		UIView *subView;
	for(subView in self.view.subviews)

		CGRect newFrame = subView.frame;
		newFrame.origin.x += (translate.x - prevTranslate.x);
		newFrame.origin.y += (translate.y - prevTranslate.y);
		subView.frame = newFrame;
	prevTranslate = translate;
    if (sender.state == UIGestureRecognizerStateEnded)
        prevTranslate = CGPointMake(0, 0);

Great tool for iPhone Mockups

Used OmniGraffle to produce mockups for my latest iPhone project, its pretty easy yo use and there are a number of good stencils that allow for most of the UI Kit controls and even the iPad!