Archive for the ‘Mac OS’ Category

CoreData + iCloud, Buyer Beware

Monday, February 4th, 2013

Back when iOS 5 was released, it was introduced having support for Apple’s new “cloud service”, iCloud. Dutifully, Apple provided developers with an API to store and access data in iCloud, and their usual Apple way, attempt to implement the “heavy lifting”.

We can now store small bits of key-value data, quickly and easily, to be shared amongst our devices.

Additionally, documents can be “magically” store with minimal additional effort from previous document support.

Finally, the coup-de-gras, is the ability to sync our Core-Data backed data, again, with only the smallest number of changes to current implementation.

To help its developers along, Apple provides sample projects and code snippets to demonstrate the ease by which these magical technologies may be easily incorporated.

Even at the latest local CocoaHeads meeting, the presenter puts together a demo that shows the wonders of using CoreData plus iCloud, and we all applaud in approval.

Others might have disagreed, however.

  • No Identity apps had their tush bitten by a released application.
  • Notable Mac developer, Bare Bones Software (at this time) is still struggling with getting their app, Yojimbo, to play nice with iCloud (although, in all honesty, they might have come from a slightly different direction with converting the now defunct MobileMe support to iCloud)

Not trying to be a nay-sayer, but this is not comprehensive list of complaints we have heard. We haven’t made the transition on Wooly Tasks yet, so we are not speaking from first-hand knowledge, but best to go into the effort with eyes-wide open.

NSDates and Fractional Seconds

Wednesday, July 18th, 2012

A recent overhaul to Wooly Tasks allowed me to manage and query for Task records quicker, more easily, and more reliably. However, I quickly ran into a silly snap when ordering lists of Tasks based on their due dates.

Would you care for another date?…

The recommended method for adding time to a NSDate is by setting up a NSDateComponents object and adding the components to the date object that you want to change. Behind the scenes, the OS will handle the cases of Daylight Savings time changes and Leap Years correctly. Simply adding a NSTimeInterval does not.

Incorrect:

NSTimeInterval oneHour = 3600; // magic number! 60 seconds * 60 minutes
NSDate *newDate = [date dateByAddingTimeInterval:oneHour];

Correct:

NSDateComponents *components = [NSDateComponents new];
[dateComponents setHour:1];
NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:date options:0];

The NSDateComponents class interface for setting the hour uses a NSInteger, and not a float or double. This is true of all the other components:

...
- (void)setDay:(NSInteger)v;
- (void)setHour:(NSInteger)v;
- (void)setMinute:(NSInteger)v;
...

Dates gone bad…

OK, now we know the correct way to add time to a date, let’s look at something that could bite us in the ass. In the case of Wooly Tasks, we limit due dates to have granularity of every 5 minutes. We also prepopulate a new task with a date that falls on the hour, and is at least 30 minutes from the moment the task was created. So if the current time is 12:34 when we create the task, then we’ll choose 2:00 instead of 1:00 as the due date time. We call this normalizing the due date.

The problem exists, if we create a couple of tasks and normalize the date something like:

NSDate *date = [NSDate date];
NSUInteger unitFlags = NSMinuteCalendarUnit+NSSecondCalenderUnit;
NSDateComponents *components = [[NSCalendar currentCalender] components:unitFlags fromDate:date];
NSInteger hour = ([components minute]<30) ? 1 : 2;
[components setHour:hour];
[components setMinute:-[components minute]];
[components setSecond:-[components second]];
date = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:date options:0];

This will wind the minutes and seconds back to hh:00:00, and the hour ahead by one (two if the date was less than 30 minutes from the next whole hour). Unless you examine the actual NSTimeInterval of these dates, then several created within a short period of time (for our example, within 5.5 seconds of each other) that might appear to be the same time:

Date 1:

July 18, 2012 4:31:39 PM PDT
364347099.942335
July 18, 2012 6:00:00 PM PDT
364352400.942335

Date 2:

July 18, 2012 4:31:45 PM PDT
364347105.456080
July 18, 2012 6:00:00 PM PDT
364352400.456080

Each date above is shown with four values: the raw date, the raw date in seconds*, the normalized date, and the normalized date in seconds*. (* number of seconds since January 1st, 2001 GMT). What you notice is that the seconds display have a fractional part that doesn’t get reflected by the user readable display.

This becomes problematic in applications that want to sort records by dates as the primary sort key, and another criteria for a secondary sort key. Particularly so when the coarseness of the dates is less than at the seconds level. For instance, if we sorted the above normalized dates, then record with Date 2 would appear before record with Date 1, even though to the user they would appear to be the same. In cases where the secondary sort criteria would have put a record with Date 1 before Date 2, this sorting would have failed to do so.

A Good Date…

There is no way to remove these fractional seconds by using -dateByAddingComponents:toDate:options: because -setMinute:, as noted above, accepts a NSInteger and not a floating point value type. We can easily modify our code above to handle that using our handy-dandy function, trunc():

NSDate *date = [NSDate date];
NSTimeInterval seconds = trunc([date timeIntervalSinceReferenceDate]);
date = [NSDate dateWithTimeIntervalSinceReferenceDate:seconds];
NSUInteger unitFlags = NSMinuteCalendarUnit+NSSecondCalenderUnit;
NSDateComponents *components = [[NSCalendar currentCalender] components:unitFlags fromDate:date];
NSInteger hour = ([components minute]<30) ? 1 : 2;
[components setHour:hour];
[components setMinute:-[components minute]];
[components setSecond:-[components second]];
date = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:date options:0];

WWDC 2011 Keynote

Monday, June 6th, 2011

No, I’m not there. :-( As of the time of this writing (9:30am WWDC time), the energy is palatable for this year’s event even 600 miles north of San Francisco (one of my all time favorite places to be) up in Portland.

We already know that Lion (Mac OS X 10.7) will be “announced” (it already really has been, just not the minutia), iOS 5 (same…it exists, no real details), and iCloud (more heavily covered…ie streaming music and a music locker, but free MobileMe services too?). What we don’t yet know is what the “Just one more thing…” is all about.

We know there is something afoot due to this image taken inside Moscone West this morning: (image no longer available)

I originally speculated with @CocoaGeek that this might just be the banners seen already that read “Lion + iOS 5 + iCloud = WWDC11″. However, as @CocoaGeek correctly pointed out to me, this doesn’t make a lot of sense since those have already been announced, even if no details have been given.

So, at 10:00 am (WWDC time) we’ll begin to know that all this is about. All I know is that 2011/2012 is going to be very, very good years to be an Apple developer.

Will update as more information flows in….

10:00 am update…

Mac OS X Lion “announced’ along with 10 new features (out of a claimed 250) being showcased:

  1. Multitouch gestures with trackpads
  2. Full screen apps (meant for smaller screen laptops/devices)
  3. Mission Control (kind of like Exposé + Spaces). A simple gesture gives you a bird’s eye view of everything on your system.
  4. Missed this one…will add it once I can get the skinny on it. Ah, I guess it was the Mac App Store. Nothing terribly new, other than it has become the number one channel for buying PC software.
  5. Launchpad, a new launcher a’la iOS Springboard for the Mac OS. Apparently also employs a sandboxing scheme.
  6. Resume (Nice!) allows you to return to the exact state of the app and its documents
  7. Auto Save (enough said)
  8. Versions… version control for everyone (I wonder if it is based on Git? :-)). Time Machine for all your documents. Who doesn’t want/need that?
  9. AirDrop (Yes!) peer-to-peer WiFi based network (what?! No bluetooth love!?)
  10. Mail.app with updated UI and other enhancements.

Available only via the Mac App Store, and only $29.99!! Wow!

10:34 am update…

OK, that’s the 10 features they chose to show-case. Looking forward to hearing what is in iOS 5. iCloud being saved for last, so I expect great things. Plus, don’t forget our “One last thing…”

iOS 5 Top 10:

  1. Notifications. Yes! This was a mess and very intrusive. Now can swipe down from top to see current list of notifications.
  2. Newsstand, iBookstore for magazine and newspaper publishers. Nice idea. I wonder how many Indie developers this impacted?
  3. Twitter integration! OK, wow. Explains a few moves made by Twitter over the past few months, particularly with authentication and third-party app support. Again, how does this impact the Indies?
  4. Safari (updated). Reader support (as can be found in Safari 5 for Mac), very nice. Reading List, for saving for later. Tabbed browsing, on the iPad anyhow (Excellent!).
  5. Reminders (Hmmmm… Wooly Tasks killer I think). Lots of interesting features that I had also thought of adding, but Apple has 1000s of more engineering resources than I do, so they beat me to the punch. Ah, the nature of the business. We’ll see.
  6. Camera (updates). Lots of enhancements, mostly in making taking a picture faster and easier. Using the up volume button to take a picture will be really nice. Rule-of-thirds guides. Built-in editing of photos.
  7. Mail (updates). More composing and editing options, in particular, rich-text formatting (YES!). Introducing a new keyboard layout that is thumb-centric and available system-wide.
  8. PC Free…no more tethering!
  9. Game Center
  10. iMessage, new messaging service for all iOS devices. Yay! iChat for iOS

AirPlay mirroring.

iTunes syncing wirelessly.

Available Fall 2011.

11:20 am Update…

iCloud. The Digital Hub that Steve Jobs talked about in 2001 has now moved to “the clouds”. iCloud stores your content “in the cloud” and wirelessly pushes it to all your devices.

MobileMe “wasn’t our finest hour”, but “we learned a lot”. MobileMe is dead. iCloud will subsume all the services of MobileMe, but everything is rewritten from the ground up, and the best news of all…

…it’s FREE.

iCloud is invisibly integrated into apps that need synching of data, such as Mail, Contacts, Calendar, etc. Wireless back-up (a’la “PC Free” feature above). Also backup purchase of iBooks, music, apps, camera roll (on iPhone), etc.

iCloud also has a feature called “Documents in the Cloud” for syncing Pages, Numbers, and Keynote documents. For developers, there will be an iCloud Storage API. And, it will work with PCs as well.

iCloud allows photos taken on your iPhone to automatically be synched onto your iPad. No more needing to tether, sync, sync, sync, … Up to 1000 images stored on your iOS devices, and anything you want to permanently keep, you just need to move into an album. Photos remain for 30 days, so grab them or lose them. There is a Push Photo Stream builtin to camera rolls which is where the syncing takes place.

iCloud is WiFi only due to immense amount of data being pushed. When carriers can reliably offer 4G or greater, then I’m sure it will move to the celluar network.

Finally, there is now iTunes in the Cloud. Buy a song, sync with all devices, automatically.

10:50 am update…

Just in time for “One more thing…”

iTunes Match. For those songs that you ripped from your personal CDs. iTunes will scan your music for non-iTunes purchased music, and voila, your songs are automatically in the cloud. No uploading needed, if they already exist in the iTunes Store. For the rest, they are uploaded. This is the rumored “Music Locker”, and it costs $25 a year (but if you had MobileMe, you still $74 ahead).

 

 

Xcode 4 and Sharing Archives

Tuesday, April 19th, 2011

Based on discussion in https://devforums.apple.com/thread/86137

In Xcode 3, as it turns out there is bug when building projects that have dependencies on external static library projects. When these projects are pulled over into Xcode 4, this issue manifests itself in the inability to share an archive properly as an .ipa file. Instead we get a .xcarchive file. Also, attempting to validate the archive gives us the following error message:

“<AppName>” does not contain a single–bundle application or contains multiple products. Please select another archive, or adjust your scheme to create a single–bundle application.

The solution is modify the “Skip Install” setting of each static library to be set to “Yes” instead of the default “No”.

The bug in Xcode 3 is that even though “Skip Install” is set to “No”, it seems to be ignored, and the output is not placed in the usr/local/lib directory within the archive.

Apple’s Magic Trackpad

Wednesday, October 20th, 2010

After completing my contract project for version 1.0 of Deep Dish Design’s iPad product, my business manager/advisor gave me permission to make some capital improvements. Namely, to invest in a new input device… Apple’s Magic Trackpad.

Not a purchase of necessity by any  means.

Actually, as nice as the trackpad is on my MacBook, I’m not a big fan of using it unless I happen to be traveling light, or forgot to bring a mouse (usually the case).

But, guess what? I have really enjoyed using the Magic Trackpad. I have yet to reach for my well used Magic Mouse. I think part of it is that I don’t have to reach in front of the keyboard to actually use it. It sits to the side, wherever I want it, and is ergonomically “just right” in term of reach and placement. It also seems less “twitchy” than the Magic Mouse when it comes to zooming in Google Maps or dynamically resizing content in a browser window. Plus, no false zooms like I get with the Magic Mouse – so, incredibly annoying.

Definitely a worthy investment so far.