I just installed iPhone SDK 3.0 and found that the text property of UITableViewCell is not used anymore, and should use textLabel.text instead. Does this mean that I have to know the current system version and call the corresponding method? like this.
UITableViewCell *cell = ...;
if ([[[UIDevice currentDevice] systemVersion] isEqualToString:#"3.0"]) {
cell.textLabel.text = #"...";
} else {
cell.text = #"...";
}
If so, that would be very annoying.
Instead of checking the OS version, you can check if the cell has the new property:
if ([cell respondsToSelector:#selector(textLabel)]) {
// Do it the 3.0 way
cell.textLabel.text = #"...";
} else {
// Do it the 2.2 way, but avoid deprecation warning
[cell performSelector:#selector(setText:) withObject:#"..."];
}
Just build for 3.0 and don't worry about 2.2 anymore. Unlike major OS upgrades, people have been upgrading to new version of iPhone OS very, very quickly. Check out this post on the TapBots blog: iPhone 3.0 Adoption Rate.
By the time your app gets approved (2 weeks from now + some?) almost nobody will be using 2.2 anymore!
You can use the 3.0 SDK and target an older version on your projects, like 2.2 or 2.2.1.
To do so, you set the Base SDK to 3.0 but change the iPhone OS Deployment Target setting. Both settings are accesible if you Get Info on the project.
It's deprecated and they suggest the new way, but you certainly can still use the 2.2 way if you want and it won't negatively affect your app running on 3.0. If you're concerned about users still on 2.2 definitely check the link ben provided. I don't think it'll be a big deal if you compile for 3.0.
Actually, I don't think you have to do this because when you build your project, you choose what firmware it is targetted to, like pgb mentioned. Then you can simply use #ifdef directives. Here is more information: iPhone check firmware version A much more thorough answer is posted here: How to target a specific iPhone version?
EDIT: I removed some text after realizing that systemVersion is actually a string, source: UIDevice Docs.
If you will use it in various files across your project then you can maybe organize it by adding it as a property to your appdelegate, and them retrieving the value by doing something like this:
MyAppDelegate *theDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *version = theDelegate.version;
But that might be too convoluted for something so simple as the version number.
If you decide to stick with 2.2 for now, be sure to test in the simulator with 3.0. We've seen odd behavioral differences between 2.2 and 3.0, especially with tables.
Related
i have built my application using xcode 5 to support ios 6 or above.I want the same application to work on versions less than 6.
I am not using auto layout.I changed all my nib files to build with os 4.3 or later.But the deprecated methods do not work on the older versions.what is the best possible way to support multiple ios versions(In my case ios 4.3 to ios 7.0)?.
http://www.raywenderlich.com/42591/supporting-multiple-ios-versions-and-devices can give you good advices.
short part of the article:
Unsupported classes
Sometimes you want to use a class that exists in
your base SDK, but not in your deployment target. To do this you need
to check the availability of this class at runtime to avoid crashing
your app. It crashes because this is what the Objetive-C runtime will
do if you try to use a class that doesn’t exist. As of iOS 4.2,
classes are weakly linked so you can use the +class method to perform
the runtime check. For example:
if ([SLComposeViewController class]) {
//Safe to use SLComposeViewController } else {
//Fail gracefully }
Unsupported methods
Similarly, if you’re using a method in your base SDK that doesn’t exist in your deployment
target, you can avoid nasty crashes by using a little introspection.
The methods -respondsToSelector: and +instancesRespondToSelector: will
both do the trick, as shown in the code examples below:
if
([self.image respondsToSelector:#selector(resizableImageWithCapInsets:resizingMode:)])
{
//Safe to use this way of creating resizable images } else {
//Fail gracefully }
The same goes for verifying the existence of class methods, except you call respondsToSelector: on the class
itself, like so:
if ([UIView
respondsToSelector:#selector(requiresConstraintBasedLayout)]) {
//Safe to use this method } else {
//Fail gracefully }
What I would like to suggest you, first block your code by version. I mean make block for deprecated methods like IOS 7, IOS 6 as on. Then try to find out the appropriate method that is supported by that version. But as far I knew you can't give full support to the version 4.3 like 7.
As #rckoenes say 80% is on iOS 7 the rest is on 6 and some are on 5. 4.3 is hardly used so I am also not give support below 6.0. So best of luck.
Please avoid to make deployment target as 4.3. use this link currently no device using 4.3. its waste of time
you can do with only native code or xib if you want do app with deployment target as 4.3.
because auto layout doesn't support 4.3 and 5.0
stroyboard not support 4.3
https://mixpanel.com/trends/
Sometimes there are features added in new versions of iOS that are tempting to use, but you don't want to prevent users on older devices from using the app just because of one minor feature.
I've just added UIRefreshControl to an app, which was added in iOS 6. I don't really care enough to use a 3rd party solution (of which there are a number), I'd just like to not invoke the code that sets it up if I'm running on an older device. I suspect, being a static language, this isn't possible, but I thought I'd ask and see if there are ways of achieving this.
Obviously if I was just sharing the code I could do this with preprocessor macros, but I need to build the app to execute on iOS 5.1 + iOS 6.0.
This is perfectly possible, just check if a class is available:
if ([UIRefreshControl class]) {
// the UIRefreshControl is available.
}
It the same with new method on existing classes:
if ([self.someLabel respondsToSelector:#selector(setAttributedText:)]) {
// The label support attributed strings
}
Objective-c is not a static as you might think, just be sure that you weak link any frameworks that are not available in earlier versions of iOS.
fourLetterWord = #"isdjfiodjof";
if ([UIReferenceLibraryViewController dictionaryHasDefinitionForTerm:fourLetterWord]) {
self.display.text = fourLetterWord;
return;
}
else
fourLetterWord = #"";
This string is getting accepted. I do not know what I am doing wrong here, but before 4.5 this worked fine. Is this an issue with xcode 4.5, or is there something wrong with my code?
I just had the same issue and start working around it.[UIReferenceLibraryViewController dictionaryHasDefinitionForTerm:fourLetterWord]) method doensn't work in the simulator for some reasons, Apple need to fix it.
BUT if you TEST YOUR APP IN THE DEVICE [UIReferenceLibraryViewController dictionaryHasDefinitionForTerm:fourLetterWord]) method runs and gives you the right result.
it's kinda slow though.
hope helps.
dictionaryHasDefinitionForTerm: always returns YES if no dictionary has been downloaded yet (because if there is no dictionary, it can't know whether the word is in it).
The download is automatically offered when you actually show a dictionary popover in any app. I think the download-on-demand feature was introduced in iOS 6, along with dictionaries in languages other than English.
My experience is that this works fine on my iPad running iOS 5.1.1 but returns TRUE every time on my iPod running iOS 6.1.3. I've logged it as a bug with Apple.
Update: omz is right. Once I had downloaded Apple's dictionary onto my iOS6 iPod then it validates the word correctly. It was so long ago that I installed iOS5 on my iPad I had no memory of whether I'd installed it manually or if it was done for me. Regardless, it requires a manual install on iOS6 for this method to be of use.
I'm implementing background fetching similar to this example. However, I also need to support devices with older iOS versions (3.0 and up). So, my question is: What versions will support this?
Also, I've been using the technique of attempting the create the object and checking if it is null as a means of insuring backward compatibility. However, if there is a way of checking the version directly, that would be great also.
At a glance I don't see anything in that code that isn't available with ios 3.0. Therefore you should be OK.
NSURLConnection is Available in iOS 2.0 and later
When you build just ensure you set your iOS Deployment Target to 3.0
The above code appears to be 3.0 compatible. If you do need to know the version of the OS you can call:
[[UIDevice currentDevice] systemVersion]
Also, I looked a the example you're using and there appears to be a significant memory leak. The line:
mutData = [[[NSMutableData alloc] init] retain];
Sets the retain count of mutData to 2, which probably means it won't ever get released.
i have iphone with os ver. 2.0 i read that for app store all appplication must be run 3.0 os.so how could i make my application to run in both firmware.is there a way i can detect if os ver.>3.0 then run different statments alse run statments for lower than 3.0 os.currently i am using this.
#if __IPHONE_3_0
cell.textLabel.text=cellValue;
[cell.textLabel setFont:[UIFont systemFontOfSize:15.0]];
[cell.textLabel setLineBreakMode:UILineBreakModeTailTruncation];
#else
cell.text=cellValue;
[cell setFont:[UIFont systemFontOfSize:15.0]];
[cell setLineBreakMode:UILineBreakModeTailTruncation];
#endif
will it run on both firmware
i want to make my app to be run on >=3.0 os and lower than this...please help me
how do i check my application for deprecated methods...i can only see this line as deprecated
cell.text=cellValue;
is there anything to change.i have installed new sdk named iphone_sdk_3.0__leopard__9m2736__final.dmg
Your code above will not run on both sets of OSes. When you use #if statements, you are basically excluding code for one version of the OS for that particular build. In other words, each version that you build, one when you define __IPHONE_3_0 and one when you don't, will exclude the code for the other.
What you are doing is building two executables, one that is built for __IPHONE_3_0 and another for ! __IPHONE_3_0.
If you want to build one executable, that is one app, that runs on both, then you need to replace the #if statements with runtime ifs, not compile time #ifs, like:
if (theOS >= kiPhone3)
....
else
....
You can also link in libraries that are 3.0 only, but test for the availability of the framework at runtime, and then skip the call if the methods aren't available. There are different calls you'll need to use, one for checking to see if a method is available, and one for if a class is available:
Class newClass = (NSClassFromString(#"NewClassName"));
if (newClass != nil)
Last thing, there is a later version of the SDK than the one you mentioned.
Good luck!
There was a similar post some time ago. Have a look at Apple's MailComposer sample to see en example of an app that supports both 3.0 and 2.x firmware
If you build it against the 2.0 (or 2.1, or 2.2.1, etc) SDK, it will run on that SDK and any later version unless Apple specifically discontinue support for that SDK. I see plenty of apps in the App Store that say they work with iPhone OS 2.x or later and they run fine on my iPhone 3G running 3.1.
The if-else directives will hide one part of the code from the compiler so it won't run on both software.