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.
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/
Dear Scholars.
I have created a simple application using the latest SDK (4.2.1), Which runs smoothly and error free on all devices with iOS 4.x.x.
Lately I am getting some comments from users with older iOS version complaining the application is crashing on start, on Apple's crash log I see nothing at all.
Pushing my investigation forward, the only suspect I have at the moment is the use of EventKit class, which if memory serves, where introduced only after iOS4.
I am using it very lightly in one of my classes, and it works perfectly on iOS4.2.1
#import <EventKit/EventKit.h>
//some time later
[self setADateInCal: [MyTimeArray objectAtIndex:0] :formatterDate];
Thus my Questions:
Can this be the issue that crashes my application on iOS < 4 ?
How can I prevent it without dropping the feature for people with iOS4
In general, How can I test this? I have the latest official iOS on my device and SDK, the simulator is limited to how back it can go in regrading to iOS version... any magical way to do so?
1.) Yes. If it wasn't in the API in <4.0 than anyone not running >4.0 will crash.
2.) Test to see if the class is available using NSClassFromString (Google for examples) and respondsToSelector in correspondence to see if the method you want is available to use in the OS version the client is running. You will also probably need to weak link the EventKit framework (again Google for how to do this).
3.) The only real way to test this is to keep a device at the OS you want to test. Personally, I have an old iPhone that I never update running 3.1.3 for things just like this. Alternatively, you can keep old installs of xcode+iOSSDK on different partitions or something and use their simulator. (for future updates i guess since you obviously haven't done this for <4.0). But no, there is no magical way to do this. sorry.
edit for clarity on Number 2: Basically you will check to see if the class/method you want is available on the OS version you are currently running, if it is you can use it, if not you will have to find a work around (omit completely or do it another way that is compliant with older versions).
Yes it could be causing the crash. Issues with missing libraries do not report anything in the apple crash log.
To prevent it from happening you need to do two things,
Weak link the event kit library in xcode.
Check for its existence in your code with something like
,
if(!NSClassFromString(#"EKEventKit")){
//do stuff with event kit
}
The only way to test on the actual iOS version is to get hold of a physical device running ios < 4.
I have an application designed for iPhone OS 2.0 and I am adding some new 3.x functionality to it. My idea is to maintain compatibility with older versions.
I have managed so far, to test for deprecated functions using "if respondToSelector...". This is just fine for calls inside a method but how to deal with method name changes? For example, the OS 2.x method
-imagePickerController:didFinishPickingImage:editingInfo:
changed in OS 3.x to
-imagePickerController:didFinishPickingMediaWithInfo:
How can I test for the OS version and direct the application to the proper method in this case?
thanks for any help.
You can use NSObject's -respondsToSelector method to dynamically determine if the method exists, then call it. You might also want to use -performSelector:withObject: to call the methods, so you don't get compiler warnings.
OK.
After a second read, I found, that I did not get your problem completely. If you implement both methods, either one will be performed at runtime. If it is a 2.x the -imagePickerController:didFinishPickingImage:editingInfo: will be performed, if it is 3.x the other one will be called
This is the crap I have written prematurely and where the comments are related to:
you may use
#ifdef __IPHONE_3_0
// iPhone 3.0 specific stuff
#else
// iPhone 2.2 specific stuff
#endif
see also this post:
What #defines are set up by Xcode when compiling for iPhone
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.
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.