NSDate initWithString: returns zero

I use Stig Brautaset. The JSON structure serializes some objects, including NSDates (which are not directly supported).

I decided to use the NSDate description as a representation of the JSONFragment date (I don't care about the slight loss in accuracy caused by this).

To extend the Stig Brautaset JSON Framework to include NSDates, I defined a category:

@interface NSDate (NSDate_JSON) <JSONInitializer> -(NSString *) JSONFragment; @end 

To recreate NSDate (and other classes) from JSON, I defined a protocol with the following initializer:

 @protocol JSONInitializer <NSObject> -(id) initWithJSONRepresentation: (NSString *) aJSONRepresentation; @end 

I am having problems with this initializer. In the case of NSDate, it just calls initWithString :, and I got into trouble: it always returns zero. This is the implementation:

 #import "NSDate+JSON.h" @implementation NSDate (NSDate_JSON) -(NSString *) JSONFragment{ NSString *strRepr = [self description]; return [strRepr JSONFragment]; } -(id) initWithJSONRepresentation:(NSString *)aJSONRepresentation{ return [self initWithString: aJSONRepresentation]; //returns nil! } @end 

I'm not sure what is going on. In addition, the compiler warns me that the initWithString: method in initWithJSONRepresentation: could not be found.

Does anyone know what might happen?

The full source code for the test case is available here .

0
objective-c cocoa nsdate protocols categories
Apr 29 2018-11-21T00:
source share
3 answers

Your test program:

 NSDate *d1 = [[[NSDate alloc] init] autorelease]; NSString *repr = [d1 JSONFragment]; NSDate *dd = [[[NSDate alloc] initWithString:[d1 description]] autorelease ]; NSDate *d2 = [[[NSDate alloc] initWithJSONRepresentation:repr] autorelease]; 

Your category method is -JSONFragment :

 -(NSString *) JSONFragment{ NSString *strRepr = [self description]; return [strRepr JSONFragment]; } 

What happens in this method is that you get a string representation of this date with -description , and then a JSON representation of that date with -JSONFragment .

In SBJSON, -JSONFragment returns a representation of the specified object as JSON data. The JSON specification requires strings to be specified. In your program:

 NSString *repr = [d1 JSONFragment]; 

repr contains a string like @"\"2011-04-29 10:20:30 -0600\"" . Because of quotation marks, this string is not a valid string to be used with -[NSDate initWithString:] .

If you change:

 NSString *repr = [d1 JSONFragment]; 

at

 NSString *repr = [[d1 JSONFragment] JSONFragmentValue]; 

so SBJSON parses this fragment and returns a string without quotes, it should work.

+2
Apr 29 2018-11-23T00:
source share

You should always use NSDateFormatter when trying to convert a string to a date or vice versa. -initWithString: exists on Mac, but not on iOS. It requires the string to be in extremely accurate format. Using date formatting is certainly an excellent solution.

And as a note, your code will break if Apple ever decides to change the format -[NSDate description] .

+3
Apr 29 2018-11-21T00:
source share

Unable to find the reason for initWithString: if you do not import Foundation and show us here, your code cannot see NSDate.h, so it does not know that initWithString: exists.

Dave is right in relying on description and using NSDateFormatter . It does not look like description will change, but there is no guarantee that it will remain valid input for initWithString: which has strict input requirements :

The string that indicates the date and time value in the international string representation format is YYYY-MM-DD HH:MM:SS ±HHMM , where ±HHMM is the time zone offset in hours and minutes from GMT (for example, " 2001-03-24 10:45:32 +0600 ").

You must specify all the fields in the format string, including the time zone offset, which must have a plus or minus sign prefix.

If your string is different in any way (including, as it turned out, the presence of quotes in it), you will get nil .

+1
Apr 29 2018-11-22T00:
source share



All Articles