How to add NSDate+BSJSONAdditions to the BSJSON project - iphone

I need to know how to get BSJSON to handle the NSDate that is in coredata
in the json it returns null for the date, what needs to go into the category to make this work?

Assuming you're talking about http://github.com/blakeseely/bsjsonadditions, there's really no easy way to get a JSON object and dump it into NSDate. You need some intervening logic - like asserting a common date format, and then do the NSDate <-> String conversion yourself, and letting the JSON format represent the string.
Common methods for doing this are to use "# of seconds since Epoch" to represent the time, or to just fully qualify out an ISO-8601 time string. Which is easier often depends on what other systems you're working with and which they can easily convert and use. The first is accomplished super-easy with Objective-C by using NSDate dateWithTimeIntervalSince1970:
Going in and out of an ISO-8601 string is a bit more work, and you'll head into the realm of NSDateFormatter

Related

How to print all available information of a locale?

The locale object must contain more information than apple talks about in the documentation. i.e. it must contain several date format strings. How can I print all this stuff to see where they are? Is there a method that would print out all information about an object?
Why do you believe the NS/CFLocale object has date format strings in it? I would assume these strings are stored in the NSDateFormatter class, probably as static data rather than instance data. Just my guess, but based on my experience with NSCalendar.

Easy way to feed in a decimal number as string into an NSDecimalNumber?

Reading the documentation, I would have to do something ugly like this:
NSLocale *usLocale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease];
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:#"0.00001" locale:usLocale];
But: Isn't there a nicer way of telling that NSDecimalNumber class to look out for the period (.) instead of anything else? Locales feel so unsafe to me. What if one day a new president thinks to be so cool to change the period symbol from . to ,? Then my app crashes. Sure this won't happen so likely. But there is a little chance it could. Enough to scare me using a locale for this ;-)
Any idea? Or is that my only option? And if it is the only option: Is the above approach correct? Or is there even a better one?
And: If I get that right, the NSDecimalNumber object will read that string, parse it and create the mantissa, exponent and isNegative values out of it for internal use, right?
EDIT: I should have mentioned that I add those values programmatically / manually (in my code), they're not user input.
Specifying the locale is only necessary if you're passing in a string that isn't a valid decimal number in the default locale. If your users are creating the strings, it's highly likely that they'll format them properly for the locale they're using.
Using locales is far safer than not using them. Trying to parse the "." out of "1,50" is not likely to succeed.
And considering that
[NSDecimalNumber decimalNumberWithString:#"0.00001" locale:usLocale]
is described in the docs as
Creates and returns an NSDecimalNumber
object whose value is equivalent to
that in a given numeric string.
I think it's a safe bet that it creates and returns an NSDecimalNumber whose value is equivalent to that of the string.
Locales are a Good Thing; if the president were to change the decimal point from . to ,, the en_US locale would be updated by the next release of the OS -- you don't explicitly mention the locale's decimal point in the above code, so you're OK there. That being said you might want to get the system locale instead of specifying en_US explicitly, which will be wrong anywhere outside the US.
If you're worried about the string, it should be coming from a user in which case they'll use their locale-specific decimal point, which should match up. If you're trying to initialize an NSDecimalNumber this way I suppose you could, but I would imagine there are easier ways to skin that cat.
And yes, if you get it right, the result will be an NSDecimalNumber object whose value is equivalent to the string you passed in.
Locales are a Good Thing. Changeable locales applied to static internal data are a Bad Thing, and you're right (if possibly paranoid :D) to be concerned about applying a locale to data you (rather than the user) provides. Here are some solutions that do not rely on applying locales to your internal data.
number = [NSDecimalNumber decimalNumberWithMantissa:1 exponent:-5 isNegative:NO];
number = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:0.00001] decimalValue];
The second would be very easy to turn into a NSDecimalNumber category implementing -decimalNumberWithDouble:. Probably quite useful.

How to convert an NSTimeInterval into an date with time?

I have an NSTimeInterval value, or more precisely an NSTimeInterval "since reference date". I think that's a value in seconds from 1970 or something like so. Pretty standard in most programming languages, I think.
So now I have that ugly value which the user doesn't understand, and I'd like to display a date + time. Is there a useful method or function that would do that, maybe by specifying formats or a locale as well? Maybe the iphone also has built-in support for this kind of stuff so that the date+time is displayed automatically like the user likes it in his/her settings?
You want to create an NSDate with +[NSDate dateWithTimeIntervalSince1970:]. You can then get the date's -descriptionWithLocale: or use the Date and Time Programming Guide from the iPhone library to find out more options for displaying the date.

HTTP date format to NSDate

I have a date string (well, NSData, but that's easy to convert to a string) that's in what I believe is the format the HTTP standard uses:
Mon Apr 17 19:34:46 UTC 2006
Is there any better (i.e. less error-prone) way to parse that than specifying the format string by hand in an NSDateFormatter?
(My application is an iPhone app, but I suspect standard Cocoa solutions will work too, since NSDate and NSDateFormatter are part of Foundation.)
No, I don't think there is a better way.
If you have some outside input, you must know the format of your input beforehand, and you can only prepare for problems, i.e. a fail over parser with an alternate NSDateFormatter.

NSDictionary initWithContentsOfFile: messes up NSDecimalNumbers, why?

In my iPhone app I employ NSDecimalNumber to store some some currency rate values.
I pull the data from the web the first time the app is launched and then again when they become obsolete, and I store them in a NSDictionary; then I use writeToFile:atomically:.
When the app is launched for the first time, my rate conversion method works allright. Yet, when I launch the app a second time, and the rates get loaded with -(NSDictionary*) initWithContentsOfFile: the conversion methos stops working, and I get weird results.
I did some debug with breakpoints in the incriminated method, and I found out that the rates data are seen as NSCFNumber, rather than as NSDecimalNumber. So it appears that initWithContentsOfFile doesn't assign the right class to my objects. For the record, the actual value of these objects, as shown in the description method, corresponds to the expected rate value.
I also checked the plist file generated by writeToFile:atomically:, and saw that the rates are stored as real; I wonder whether this is the right type.
Any idea of whats going on?
Thanks in advance,
Davide
Property lists don't distinguish between decimal numbers and floating-point numbers. The real element holds a floating-point number. (Indeed, the serialization itself may simply be NSNumber sending floatValue to itself, unaware that the instance is actually of a subclass. That would mean the conversion to floating-point happens when you generate the plist data, not when you read it back in.)
You'll have to store it as a string, I think. Hopefully, that's lossless.
Plists only work with certain data types and NSNumber is one of those. If you want the NSDecimalNumber then you have two ways to go about it. The first is to keep using plists and then convert all the NSNumbers to NSDecimalNumbers after load. The second is to switch to using NSKeyedArchiver for storing data. This requires more code but means that if you save an NSDecimalNumber, you'll get an NSDecimalNumber back.