about iOS target version and SDK version - objective-c

iOS SDK is upgrading, and some new tech will appear, i.e, block is new tech.
So question is if "block" based implementation also can be distributed to lower target version or older iPhone ( 3G or first generation ) ?
how to cope with those issues ?

The usual way to deal with this sort of issue is to selectively enable features at runtime based on the current OS version. However, this can be very complicated to manage.
Query the current OS version at runtime
Use weak linking
Dynamically create the class
Call the new features only if the new class is present
For example:
Class optionalClass = NSClassFromString(#"NSArtificialIntelligence");
if (optionalClass) {
id optionalObj = [[optionalClass alloc] init];
// ...
}
The following documentation describes the process in detail:
Configuring a Project for SDK-Based Development
Using Weakly Linked Classes in iOS
You specifically mention blocks. This feature requires support from the compiler and Objective-C runtime, so it will not be available at all on older systems.

You must weak link to libSystem.B.dylib if you are using blocks for iOS4 or later. Because blocks are able to compile with the latest iOS SDK but iOS2,3.0 and 3.1 don't have blocks runtime.
iOS 4 app crashes at startup on iOS 3.1.3: Symbol not found: __NSConcreteStackBlock
(Besides, you can use blocks for iPhone 2.2+. Please take a look at plblocks.)

Related

Discover calls to methods not available in earlier iOS versions

I am building my app using iOS 5.0 as base SDK and iOS 3.0 as deployment target.
I know I need to check for existence of methods and classes when I work with features that are not available in the earlier iOS versions, but lately I've lost a few hours on a problem just to discover I was calling a method not available in some iOS versions. I simply did not notice it was a new method and did no check before to call it. The app of course compiled with 0 errors and 0 warnings.
This is a big problem because if I forgot some other check somewhere in the app, I will not know it until I or, worst, some user will activate that specific part of code.
Maybe I am missing something, is there some compiler option I can set to detect the calls I make to methods not available in the iOS deployment target? How do you deal with such a problem?
This link might point you in the right direction. Supporting mutiple ios Versions in your apps. It explains how to deal with taking advantage of the newer ios features while maintaining backwards compatibility. Hope that helps.
The only way to check for compatibility with a prior version of iOS, currently, it to test the app on an old non-updated device running that version of the OS.
If you can't find a device that old, even just to borrow for short time, then there may not be a good buiness reason to set the Deployment target that low.

How check the availably of all objective-c function in source code for Cocoa

When you read the Class Reference of every object of iOS, you will find:
Available in iOS 2.0 and later.
There are a program or a way to list all function and the minimum iOS system?
How can I know if the iPhone with iOS 3.0 will run all iOS function? I can check it in runtime with respondToSelector, but can be more easy with source code?
Set your project's base SDK to iOS 3, and see if it builds.
AFAIK there is no way to list all the APIs you use in your app into one list and check that you are building past the minimum for all those APIs. You will just have to check each one, one by one. Highlight the API in Xcode, and then click escape and it will tell you very easily.
But also I have to mention that this won't be extremely necessary since you should test on the minimum OS you are building for and if it crashes at any point then you have your issue for that certain API.

xcode 4 garbage collection removed?

I am learning Xcode and objective c, but the book I am reading is using the older version (3.2) of Xcode. One chapter, which is completely dedicated to memory and leaks, says I need to turn on garbage collection through Project Settings > Build. However, I can't find the garbage collection setting. Has it been removed or am I just missing it?
Xcode 4 still has Garbage Collection, all you do is go into your project (the top option in the navigation bar with the big xcode project icon). Select your target which should just be the name of your app with the application icon next to it. When you select that, along the top there is a bar with different options, such as summary, info, build settings etc. Hit "Build Settings" and type "garbage" in the search field. Then set garbage collection to required.
One very important note about GC is that it is officially deprecated as of Mac OS 10.8, which means you should be transitioning your code to ARC if possible because GC might not be around for much longer.
Update: See other answers for enabling GC in current versions of Xcode. As I stated above, you should be transitioning to ARC if you haven't already.
As of XCode 4.4 the garbage collection build flag is user defined (see the very end of the build settings list).
GCC_ENABLE_OBJC_GC supported
Valid build settings are:
unsupported: The application cannot load code that requires garbage collection. The loadable bundle cannot be loaded by an application that requires garbage collection.
supported: The application can load code that supports or requires garbage collection. The loadable bundle can be loaded by an application with any level of garbage-collection support.
required: The application can load only code that supports garbage collection. The loadable bundle can be loaded only by an application that supports garbage collection.
Garbage collection is very much fully supported in Xcode 4. Xcode 4, itself, is a GC'd application.
GC is also very much not available in iOS. If you are writing an iPhone/iPad app, you can't use GC.
That's a challenge but you might be able to get it done - here's a starting point to think about in relation to PDF generation:
iOS SDK - Programmatically generate a PDF file
If you can generally follow what is going on there, you might be OK.
Xcode 3.2 is still available for download - in fact, 3.2.6 was released within the past week or two, so it's not exactly "old and busted." :-) Xcode 4's interface is very different, so given your tight schedule and your need to start from square one, you might be better off using 3.2 for now. That will certainly make it far easier to use the book you have.
As of Xcode 4.3.3 the only setting available for parameter "Objective-C Garbage Collection" under section "Apple LLVM compiler 3.1 - language", Build Settings for your target app = "Unsupported"

Dealing with deprecated symbols and methods when building for multiple iOS versions

I'm a c++ developer who is transitioning into the iPhone world, and I would love to get help around something.
Let's say for example, MPMoviePlayerController used to post the MPMoviePlayerContentPreloadDidFinishNotification notification in iOS 3.1 and earlier.
However, now this notification is deprecated.
I want my app to be able to run on every iPhone that has iOS 3 and above.
If I'm developing using base sdk 4.2, when I'm installing my app on an iphone with iOS 3.2 what will happen? Does the app comes with the sdk linked to it (like mfc static link for example)?
If I understand correctly, on iPhone with iOS 3.2 for example, that notification will still get called. (If i'm calling a function on an earlier sdk, assuming it's not statically linked like I asked above).
Does that mean that if I'm writing a new app now, I still have to take care of those deprecated notifications?
I can't get my head around this and would appreciate any explanation.
Thanks
If you use a symbol that was included with iOS 4.2 on a device that is running 3.2 you will encounter a crash.
The way to get around this is to use new symbols conditionally based on whether or not they're available at runtime.
Eg.
if (&NewNotificationSymbol != NULL)
{
// awesome, it's not NULL, we can use it
}
else
{
// not so awesome, we'll use the old, deprecated one
// but at least we won't crash
}
The same approach can be used for Classes that are new in 4.x when running on 3.x too:
if (NSClassFromString(#"MyAwesomeNewClass") != nil)
{
// awesome, it's not NULL, we can use it
}
else
{
// not so awesome, we'll use the old, deprecated one
// but at least we won't crash
}
As a rule of thumb, you should always compile and link against the latest iOS SDK provided with the developer tools and then set your Deployment Target build setting to the oldest version of iOS that you wish to support. Then use these conditionals to make use of new features and gracefully fallback without crashing if they're not available.

Android and Objective-C

I'm completing a project for the iPhone entirely written in Objective-C. I'd like to port this for Android too.
While the user interface of the iPhone and the Android OS are very different and will need different code, can I some how import the core of my code (ie. the black box that does the thinking) as is to Android as part of some Java code?
I have no familiarity with bridging between Objective-C and Java even though I have written in both.
You got luck! Phil Hassey has recently ported his own game from iPhone to Android within a week and wrote up what he did steps by steps. Here is his journey: http://www.philhassey.com/blog/2010/08/03/porting-galcon-using-the-android-ndk/
You could have a look at Apportable which allows to generate an Android app from an existing Objective-C code base. See this article too.
there is a fork of the gcc that supports objective-c on the android by patching the NDK on
http://code.google.com/p/android-gcc-objc2-0/. But it's considered beta at the moment and i'm not sure if jni/java bridges are already implemented
I have been doing a lot of work on this front — for example by creating my own C++ base framework that does not depend on STL (called Platform Core) and writing the core of the next version of my iOS app with that, so that I can easily port it to Android and whatever else has a C++ compiler and strikes my fancy.
I suggest having a (ick, I can't believe I'm about to say this, but eh), ahem, having a C++ core (there, I said it!) so it can be easily ported.