basics of iOS and OS X API’s


The structure of OS X and iOS native* API’s is very straight forward/minimalistic, typically one does not need to know about anything that goes below the Foundation API however taking a look at the headers can help understanding it better and clearing common confusions between Foundation and CoreFoundation or what exactly constitutes CocoaTouch and Cocoa since the later is a explicit framework while the former is just a naming convention.

All the API’s are present as binary frameworks under /System/Library/Frameworks (with resources but without headers) and under your Xcode toolchain SDK (with headers but without resources) , the objc binary is at /usr/lib/libobjc.A.dylib while the headers are under /usr/include/objc/ and your Xcode toolchain.

I
Now let’s dig right into it, at the lowest level there is CoreFoundation and objc, they are independent of each other :

<objc/objc.h>
objc_class,objc_object,objc_selector etc

<objc/runtime.h>
objc_getClass,objc_getProtocol,class_conformsToProtocol etc

<objc/message.h>
super_class,objc_super,objc_msgSend,objc_msgSendSuper etc

(you can include all the above with #import <objc/objc-class.h>)

<CoreFoundation/CoreFoundation.h>
CFString,CFNumber,CFArray,CFRunLoop,CFStream etc (this is just C, there is no Objective-C syntax or anything at this level)

II
On top of these and including (relying on both) is Foundation, as the name implies you typically never use any API’s below foundation directly.

<Foundation/Foundation.h>
NSString,NSNumber,NSArray,NSRunLoop,NSStream etc, much of it is toll-free bridged to CoreFoundation

III
on top of Foundation there is AppKit for OS X or UIKit for iOS
(on OS X you typically include Foundation, AppKit and CoreData with #import <Cocoa/Cocoa.h>, there is no corresponding CocoaTouch shell framework on iOS)

<AppKit/AppKit.h>
NSView,NSButton,NSColor,NSEvent etc

<UIKit/UIKit.h>
UIView,UIButton,UIColor,UIEvent etc

This is pretty much all there is, from this on there are multiple optional frameworks you can use for specific cases, but the basics are just in the headers above, most API’s are Cocoa but there is still a big chunk of C API’s especially on the OS X side.

It’s worth nothing that there are two types of frameworks : private and public , the private ones are not safe to be used and not allowed in the Mac App Store , the public ones are safe to be used as long as they have headers in the SDK (they could be present in /System/Library/Frameworks but not in the SDK) typically such disparity is a rare occasion nowadays and it was more common prior to 10.6.

One more note is that public frameworks with headers might not have all their methods/classes documented, nevertheless using them should be pretty safe but the lack of documentation is a indication that they are more likely to change/go away than the documented ones.

*OS X and IOS also have the low level BSD API’s (found in /usr/include) most of which are cross-platform and outside the scope of this post.

Advertisements

what the sparkle doc’s won’t tell you

Sparkle is the updates framework for cocoa that “just works” , yea ok it does , however the documentation for it is a bit lacking on some very important aspects that i discovered over time :

1 – the preferences for your application must have SUAutomaticallyUpdate TRUE for autoupdates to happen , just setting SUEnableAutomaticChecks TRUE in the app’s Info.plist is not enough ,

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

[defaults setBool:YES forKey:@”SUAutomaticallyUpdate”];

[defaults synchronize];

OR

SUUpdater *updater = [SUUpdater updaterForBundle:[NSBundle mainBundle]];

[updater setAutomaticallyChecksForUpdates:YES];

OR

create a checkbox in the preferences of your app to toggle it on , unless you do that you have to use one of the methods above directly in code.

2 – since 1.0 sparkle implemented sparkle:shortVersionString to match CFBundleShortVersionString , the problem however is that it is only used when it also sees a different version in sparkle:version , for example if your app has

CFBundleVersion 1
CFBundleShortVersionString 1.1

and the appcast has
sparkle:version=”1″
sparkle:shortVersionString=”1.2″
sparkle will say you have the latest version , it only uses shortVersionString if  version differs from CFBundleVersion

3 – some times you might also want to force a update , either when the user clicks a Update Now button or when the application launches

SUUpdater *updater = [SUUpdater updaterForBundle:[NSBundle mainBundle]];

[updater checkForUpdates:nil];

OR

[updater setAutomaticallyDownloadsUpdates:NO];

[updater checkForUpdatesInBackground];


Both check for a update , however the first way also notifies the user if the current version is the latest one , so should only be triggered from a user action.

The second can be ran transparently on startup as it will not alert the user unless there is a new update , remember to set automaticallydownloadupdates off , or else the updates will only get downloaded and never installed (bug in Sparkle 1.5 b6)

EDIT: the bug has been confirmed for 1.5 b6 by Andy Matuschak , it is fixed in the github sources however http://github.com/andymatuschak/Sparkle/