26146

How to port a Cocoa app to iPhone-OS?

I am about to create a Cocoa app and I want to ensure that one day I can easily port it to the iPad or even the iPhone. How can I plan for this in advance?

I know I will have to redo all NIBs and probably design a different workflow.

But what about the code? Just replacing every NSsomething with UIsomething won't cut it, right? Any tips on how to make sure now that I won't shoot myself in the foot later?

Thank you!

(The iPad-SDK is under NDA. For the sake of this question just assume i asked about the iPhone, OK? Or think iPhone with a bigger screen.)

Answer1:

As with any good project layout, you should separate out your UI from your non-UI components. That doesn't just mean on disk layout (though that makes sense as well) but rather using a MVC approach, whereby your controllers (C) know about the Models (M) and the UI (V) is rendered separately.

You can use Key-Value Observing (aka KVO) to set up your models, such that when they fire, it sends around a notification to any registered listeners to update. If you are using XIB to generate your user interfaces, then this is what happens when you bind an object to your display widget(s).

So you can end up with separate XIBs for your iPhone, Mac OS and (later) iPad - though if you resize things correctly, you can have the same XIB for the iPhone and iPad.

Lastly, there are often some cases where you need to inject logic into your models (for example, adding an image to return from a method). In this case, the iPhone and Mac OS have different Image classes. To do this, you can create the following:

MyModel.m // contains the data, no UI MyModel+UIImage.m // contains a category for adding the UIImage MyModel+NSImage.m // contains a category for adding the NSImage

The category looks like this:

@interface Host(UIImage) -(UIImage *)badge; @end @implementation MyModel(UIImage) -(UIImage *)badge { if (green) return [UIImage imageNamed:@"green.png"]; if (red) return [UIImage imageNamed:@"red.png"]; } @end --- @interface Host(NSImage) -(NSImage *)badge; @end @implementation MyModel(NSImage) -(NSImage *)badge { if (green) return [[NSImage alloc] initWithContentsOfFile: @"green.png"]; if (red) return [[NSImage alloc] initWithContentsOfFile: @"red.png"]; } @end

This has the added advantage that your unit tests can just load the model (without any image categories being loaded) whereas at runtime your code that needs to process the images (say, in a view controller) can load the model-with-category and load the badge with [model badge] in a transparent way, regardless of which platform it's compiled for.

Answer2:

Make sure you strictly uphold the Model-View-Controller separation in your app. The model, especially, should never depend on any controller or view.

In porting to the iPhone/iPod touch/iPad, you'll need to replace most or all of the controllers and all of the NSViews and NSCells. You should be able to keep your CALayer subclasses, if you have any. You may be able to reuse one or two controllers with conditional compilation, if most of a controller will work on both but some parts only work on the Mac or work on both but with completely different APIs. And you should be able to keep the entire model unchanged.

There are probably some more specific pitfalls that an iPhone developer can warn you about, but this is the general rule that holds for any transition from one environment to another. (An example of another environment transition would be making one or more command-line tool equivalents or complements to your app, like xcodebuild, packagemaker, or ibtool.)

Also, look at the Introduction to the Foundation framework reference for figures showing which Foundation classes are Mac- and iPhone-only.

Answer3:

A lot of libraries aren't even supported in Cocoa Touch versus the desktop Cocoa libraries. You need to consider the differences in AppKit versus UIKit. Also, Objective-C does not allow garbage collection on the iPhone. There are many touch events that only exist on the iPhone but not on a desktop. iPhone development is much more restrictive due to the fact that a phone is a very personal device tied to very personal data.

Check out these slides for a better comparison: http://www.slideshare.net/lukhnos/between-cocoa-and-cocoa-touch-a-comparative-introduction

Answer4:

checkout apple.com all apps on the iphone also work on the ipad

Recommend

  • iOS 8 Extension: how to use xib inside Cocoa Touch Framework in extensions?
  • How to add action to a barbuttonitem in a navcontroller that was created programmatically within tab
  • Adding a button inside a popover
  • How are the 2 View Controllers wired to the tabBarController in iPhoneRecipes
  • Implementing HMAC-SHA256 for Keybase in Javascript
  • Objective C - Create a framework for my iphone apps?
  • Which browser have this strange user agent? (IOS device)
  • How to change placeholder text in an autocomplete activity of android google place?
  • Are there any side effects from calling SQLAlchemy flush() within code?
  • react split panel resize
  • iOS Cordova first plugin - plugin.xml to inject a feature
  • Two Tables Serving as one Model in Rails
  • How do I include a SWC in an AS2 Flash project?
  • How to add a focus style to an editable ComboBox in WPF
  • JqueryMobile Popup menu is not working
  • Multicolored edittext hint
  • RxJava debounce by arbitrary value
  • Redux Form - Not able to type anything in input
  • How do I superscript characters in a UIButton?
  • Install PHP intl extension on MacOS
  • Android - Material Design - NavigationView - How to put vertical scroll?
  • onBackPressed() not being executed
  • How can I sort a a table with VBA with given text condition?
  • All Classes Conforming to Protocol Inherit Default Implementation
  • Is my CUDA kernel really runs on device or is being mistekenly executed by host in emulation?
  • PHP - How to update data to MySQL when click a radio button
  • angularjs unit test when to use $rootScope.$new()
  • ActionScript 2 vs ActionScript 3 performance
  • VBA Convert delimiter text file to Excel
  • To display the title for the current loaction in map in iphone
  • Apache 2.4 - remove | delete | uninstall
  • Traverse Array and Display in markup
  • Cannot Parse HTML Data Using Android / JSOUP
  • How to set the response of a form post action to a iframe source?
  • How do you join a server to an Active Directory (domain)?
  • Angular 2 constructor injection vs direct access
  • Understanding cpu registers
  • Why joiner is not used after Sequence generator or Update statergy
  • Setting background image for body element in xhtml (for different monitors and resolutions)
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize