ack ack - 1 year ago 83
Objective-C Question

NSDateFormatter.dateFromString is returning null after iOS9 upgrade

One of my apps is having a problem after running on a device which has just upgraded to iOS9 (app's target is 8.1).

The app is working fine on pre iOS9, however, after ONLY upgrading to iOS9 on device the following problem is happening.

The variable below called 'anObsDate' is now returning null. I have no idea why. It seems the standalone upgrade of iOS9 on the host device has triggered this problem to happen.

NSDate *anObsDate = [[self bomDateFormatter] dateFromString:[anObs timeStamp]];

When I run the app with the following debug, we have this output:

NSLog(@"Timestamp %@", [anObs timeStamp]);
NSLog(@"Formatter %@", [self bomDateFormatter]);
NSDate *anObsDate = [[self bomDateFormatter] dateFromString:[anObs timeStamp]];

Timestamp 2015-09-17 00:01:10
Formatter <NSDateFormatter: 0x7fe7abc653c0>

I set my date formatter up as follows:

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_AU"];
NSDateFormatter *countDownFormatter = [[NSDateFormatter alloc] init];
[countDownFormatter setLocale:locale];
[countDownFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Australia/Melbourne"]];
[countDownFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss"];
return countDownFormatter;

Again to make this clear, if I run my app on a pre iOS9 device, everything works fine, and dateFromString returns a NSDate. After upgrading to iOS9 dateFromString returns null.

Any suggestions?


Answer Source

It appears that NSDateFormatter has changed in behavior in iOS 9 such that single quoted characters in the date format must match the characters in the string exactly. Previously it would accept any character (searched the docs, but couldn't find any mention of this change).

The timestamp string is missing the "T" that's defined in the date format. Try changing your date format to:

// Note the "T" has been removed
[countDownFormatter setDateFormat:@"yyyy'-'MM'-'dd' 'HH':'mm':'ss"];

Your other option would be to add the "T" into the timestamp string:

// Note the "T" has been added

This should be backwards compatible with previous versions of iOS.