1

I'm trying to build a library that has convenience methods for dealing with the iOS and OSX AddressBook frameworks (Contact List on iOS and Contacts on OSX) and includes such methods as:

  • (BOOL)addressBookContainsRecordWithID:(NSString *)recordID (NSInteger in the case of OSX)
  • (id)newOrExistingGroupWithName:(NSString *)groupName
  • (id)addressBookRecordWithID:(NSString *)recordID

etc.

And I'd like to be able to call these methods on both OSX and iOS, but have that method execute the logic path respective for each device. For example, on OSX it would use a method that uses ABPerson and ABGroup whereas on iOS it would use a method that uses ABRecordRef.

My current plan is to have preprocessor directives (#if device-is-osx callOSXMethod #else callIOSMethod) which figure out whether I'm using iOS or OSX and use the correct method.

Is there a better way I could go about this? I feel like there is some design patter that could be used here.

Glauco Vinicius
  • 2,527
  • 3
  • 24
  • 37
Alex
  • 7,432
  • 20
  • 75
  • 118

2 Answers2

3

It depends on how much shared code there will be between your two different implementations. If almost all of the code is shared except for a few specific method calls to the AddressBook frameworks then preprocessor directives with #if TARGET_OS_IPHONE are the way to go.

On the other hand, if you find that the code in your #if blocks is getting quite long, it usually makes more sense to split the Mac and iOS implementations into separate files that share an identical interface. Thus you'd have:

  • MyAddressBook.h - Shared by both
  • MyAddressBook_Mac.h - Mac implementation of MyAddressBook
  • MyAddressBook_iOS.h - iOS implementation of MyAddressBook

This is made easier by the fact that your implementations can even have different instance variables by using a class extension inside each implementation file. This second pattern leads to greater readability at the cost of having to maintain whatever common code there is in two places.

torrey.lyons
  • 5,519
  • 1
  • 23
  • 30
1

Preprocessor directives are the way to go. There are even predefined ones you can use:

#if TARGET_OS_IPHONE
    // iOS code here
#else
    // OS X code here
#endif
DrummerB
  • 39,814
  • 12
  • 105
  • 142
  • Thanks for the answer. Does TARGET_OS_IPHONE test for all iOS devices or do I have to use something else when testing for a general iOS device? – Alex Dec 07 '12 at 12:27
  • 1
    It tests for iOS (previously called iPhone OS). – DrummerB Dec 07 '12 at 13:10