Archive for May 2015


Unpredictable Date Formatting

May 27th, 2015 — 5:24pm

Daniel Jalkut posted about his recent issues with NSDateFormatter. Having run into the same issue last month (rdar:/20512790 for you Apple folks keeping score at home), I’ve found that the issue is more confusing than that.

For one, it’s not just the 12/24-hour clock affecting HH in date formats. It seems that in some circumstances, in some locales, literal characters, like period (.), will be changed to colon (:). Not only that, this happens (at least in the case I found it) depending on whether you use hh or HH in your pattern.

Observe this output from my test program:

LOCALE: en_UA

FORMAT: MMMM d, hh.mm.ss a

January 1, 13:00:00

FORMAT: MMMM d, HH.mm.ss a

January 1, 13.00.00 PM

“en_UA” is English as the language, but Ukraine as the region. It’s important to note that there are two components here, the language and region, encoded in the locale. This is important because Apple’s suggestion to use “US_en_POSIX” is incorrect. That only works if English is your language. To do it correctly for the user’s language (not every date format uses numerical months), you need to get the locale for their current language, grab the identifier, tag “-posix” to the end and get a new locale from that. I’m not sure if this type of scheme works for all languages (anyone have documentation to this effect?) so it’s possible this won’t work for some language out there. All in all, a bit of a pain and a bit fragile for something that worked properly before.

And before some of you bring up some argument about respecting the user’s preferences, in the case where I use it, the user is specifying the pattern in the UI and wants to specify a different pattern than the one that they used in their preferences. Also, this API is at a much lower level and should respect the literal pattern provided the developer. I’d suggest the current behavior only mangle the format string when you explicitly use +dateFormatFromTemplate:options:locale: leaving format strings that don’t use that method as-is. In the very least, provide a “literal” mode when it comes to interpreting the format string.

 

1 comment » | Cocoa, OS X, Programming

Delegates vs Blocks

May 15th, 2015 — 12:58pm

This was something that came up at last night’s Cocoaheads so I thought I’d share my thoughts on it here. I’m way overdue for a post anyways.

Both delegates and blocks allow for callbacks, a way to allow an API user to provide custom logic to what is otherwise a black box. With the advent of blocks, there’s a temptation by some to use them everywhere. But as with anytime you have a new toy (ok, not so new in this case but newer), you must resist the temptation to stop using old stuff when is still better suited for the situation.

So, when do you use delegates? Delegates are for when there will be a closer, long term relationship between objects. There is usually a well defined interface for the delegate to follow. The delegate itself is probably maintaining state and consolidating logic for this purpose. From the point of view of the object using the delegate, it is a one-to-one relationship (the delegate might not actually be monogamous in this relationship and be a delegate to several objects). You can rely on one object to know how to handle these cases and expect some level of self consistency.

How about block callbacks? These are best suited for more ad hoc cases. Usually these blocks are called immediately or up to a few times in the not too distant future. An example of the former is having a block called on the elements in an array, after which, control is returned to the caller. For the latter, completion or progress handlers are typical examples, where you initiate some longer running process and want to specify behavior for certain events. The reason blocks are good for this situation is that they can capture the immediate context and use that in the custom code. This is also why blocks are less well suited for longer term relationships as they end up creating undesired or unintended dependencies that are harder to extricate.

The rules are not cut and dry but hopefully you’ll see that there’s a need for both. It’s both fortunate and unfortunate that blocks came into the Cocoa world as late as they did. While it did allow for the creation of some solid and clean use of delegates, it also allowed for some APIs which should have used blocks from the beginning (basically anything which takes a user-supplied context parameter). Hopefully Apple will clean these up over time but for your own APIs, be mindful of the differences.

Comment » | Cocoa, OS X, Programming

Back to top