TWRequest class. What to do? - ios

I update the project, which was written under iOS5. Now do support only iOS7.
The project has check:
if ([TWRequest class]) {
...
}
XCODE says "TWRequest is deprecated: first deprecated in iOS 6.0". I know I should use Social.framework.
Therefore, the question whether it makes sense to update these checks, or you can simply remove it? Indeed, in the iOS still supported by default Social.framework?

Related

Check for warnings of deprecation and new methods

Recently I submitted my app on AppStore with a method setting badgecolor of tabbaritem.
[[[AppDelegate globalDelegate].tabBarController viewControllers] objectAtIndex:1].tabBarItem.badgeColor = kTabBarBadgeColor;
This badgeColor came in iOS 10 only and my app supported iOS 8 and above. I had no idea about it and the app got approved. Now, I have to resubmit my app with fixing this issue.
I want to know if there is a way to find out such cases where methods get deprecated or are visible in specific OS versions only.
By changing target of Xcode project you can see errors & warnings while building.
If you need more info,
You can visible all API changes like Added,Modified & Deprecated variants in Apple documentation
it will give you searching options for both Swift & Objective C
Searching UITabBarItem Instance Property badgeColor. it gives API changes are none.Supporting SDK's version
SDKs
iOS 10.0+
tvOS 10.0+
Searching finishedSelectedImage instance method of UITabBarItem.
SDK
iOS 5.0–7.0 Deprecated
Deprecated Use selectedImage with UIImageRenderingModeAlwaysOriginal
instead.

Was I supposed to get a warning [duplicate]

This question already has an answer here:
Why is the Xcode compiler not warning me about invalid methods for my Deployment Target?
(1 answer)
Closed 9 years ago.
In my code I use
[[self presentingViewController] dismissViewControllerAnimated:YES
completion:dismissBlock];
The thing is my deployment target is set to: 5.0.
While base SDK is 6.1.
Was I not supposed to get a warning by XCode? (because I think the above method got introduced in iOS6).
Unfortunately no, Xcode doesn't check if you use symbols that are not available in your deployment SDK.
It only checks your code against the base SDK.
But you can use some third-party software for this, like DeployMate.
That being said, as others pointed it out, dismissViewControllerAnimated:completion: is available since iOS 5, so your code is safe.
But it's always a good idea to check for unavailable or deprecated APIs in your app, using something like DeployMate.
EDIT
Here's an answer to your comment:
If you deployment target is 5.0 and your base SDK 6.0, using a symbol available in the 6.0 SDK on an iOS 5 device will crash the application.
But Xcode won't warn about this when compiling, hence the need of some third-party software.
Once you identified the problematic symbol, using respondsToSelector: is the way to go, as it's better than simple version checking.
This way, you can have conditional code that will run with both SDK versions:
if( [ someObject respondsToSelector: #selector( someIOS6Method ) ] )
{ /* iOS 6 code */ }
else
{ /* iOS 5 code */ }
Only do this if you have detected SDK issues. Don't do this for everything.
According to UIVIewController class reference, this method is available from iOS 5.0 and higher.
Availability
Available in iOS 5.0 and later.
It is not ok to warn you. It doesn't have this warnining included in the default bundle of the SDK.

Is UIViewController's beginAppearanceTransition:animated: method available in iOS5

I need to use beginAppearanceTransition:animated: in a UIViewController subclass that implements controller containment with custom animation transitions. I need to support iOS5 as a minimum.
The Apple docs say the method is:
Available in iOS 6.0 and later
Yet UIViewController.h has the method tagged with:
__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0)
I'm hoping the docs are just wrong. Can anyone give me a definitive answer on whether I'm allowed to call this in iOS5?
I filed a bug report with Apple about this discrepancy and got the response that the methods are available in iOS 5.0. The headers are right and the documentation is wrong. I've filed another report to ask for the documentation to be updated...
The methods were added to the public headers in the iOS 6 SDK, but are available and can be used on devices running iOS 5.0.
Update (28-Aug-2013)
The documentation has been updated to show that beginAppearanceTransition:animated: and endAppearanceTransition are available on iOS 5.0.
In my experience when in doubt, the headers are more accurate. the docs are generated / written using the headers. So I assume at this point that iOS 5 is supported.
Now I tested it on the simulator. Once for 5.0 and once for iOS 6.1 and the moths are called on both versions whenever you push or pop a vc.

How to detect if I am accessing iOS6-only methods? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a way for XCode to warn about new API calls?
I'm building an app that will support iOS 4.3 through iOS 6.x. However, I unknowingly used a method that is marked __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_6_0). This means that the selector does not exist in previous versions of iOS.
Of course, when I tested my code on an iOS 5.x device, the app crashed. I figured out what was going on, and inserted a respondsToSelector check, and default to the "iOS 4.x way" of doing things when it fails this check.
How can I prevent these bugs in the future? Is there a compile-time way to figure out that I am accessing iOS-6-only methods, so that I can add appropriate iOS feature-checks?
I don't want to accidentally ship a product that works fine on my iOS6 devices, only to have it fail on someone's iOS4.3 device, because the selector does not exist.
The answer here worked for me: https://stackoverflow.com/a/8919108/208989
Download this header: https://github.com/mattjgalloway/MJGFoundation/blob/master/Source/Utilities/MJGAvailability.h
And put the following at the top of your .pch file:
#define __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED __IPHONE_4_3
#import "MJGAvailability.h"

Developing apps for multiple iOS version

I am testing an app on an iPhone 4 with iOS 5.1 and an iPad 4 with iOS 6.0. I looked around and surprisingly did not find similar questions:
1- My app has some methods that have been deprecated in iOS 6.0 so I believe I have to build some if/then conditions to test for system version using: [[UIDevice currentDevice] systemVersion], and then use the version appropriate methods. Is that the most efficient way?
2- My understanding is, with only one target, the "project" Deployment Target and the "Targets" deployment target serve the same purpose. And I need to have one of them or both as iOS 5.1 since that is the minimum iOS supported. What is confusing is that if the target is built based on iOS 5.1, how would it run on the iPad4 with iOS 6.0:
Does the iPad OS checks for target versions before running or just tries to run the code and it happens that the iOS 5.1 target does not have any code that the 6.0 is incompatible with?
Even if that is the case though, how could a 5.1 target support 6.0 methods that I built to conditionally replace deprecated methods?
Many thanks!
Deprecated methods
Deprecated methods can be used if you are targetting iOS versions that were released before those methods were deprecated. But assuming your deployment target is set correctly, you won't get any compiler errors unless those deprecated methods were always deprecated for the versions you are targetting. In other words, if you are seeing deprecation warnings in your code you need to fix them or check that your deployment target setting is correct. Do not ignore them!
Xcode setting levels
You mention the fact that you can define the deployment target setting at both the target and project level. Xcode build settings at the target level will override project settings. So define the deployment target at one of these levels only, then go to the other and hit delete so you don't have duplicate values. If you only have one target then it doesn't really matter if you define it at the target or project level.
Backwards and forwards compatibility
Finally, there are many factors that come into play for backwards and forwards compatibility. Sometimes there will be new iOS 6 methods like supportedInterfaceOrientations which will simply be ignored on older iOS versions. Other times you need to add explicit checks:
If you are calling a method on an object and that method was only introducted with iOS 6, you will need to add a respondsToSelector: check like this:
// only available on iOS 6
if ([locationManager respondsToSelector:#selector(pausesLocationUpdatesAutomatically)]) {
locationManager.pausesLocationUpdatesAutomatically = YES;
}
If you want to check if a particular class exists on the current iOS version, you can check the return value of the +class method like this:
// Only available on iOS 6
if ([UICollectionView class]) {
// ...
} else {
// class doesn't exist in this iOS version
}
If you want to check if a particular function is available, do a simple if statement on it:
// Only available in iOS 6
if (ABAddressBookCreateWithOptions) {
ABAddressBookCreateWithOptions(...);
} else {
ABAddressBookCreate(...);
}
Finally, if you want to check if a constant is available, check it's address:
// Only available in iOS 4
if (&UIApplicationProtectedDataDidBecomeAvailable) {
// subscribe to notification
}
Your Base SDK setting should always be set to "latest".
If you follow all these guidelines you will be able to solve most of your problems without having to add explicit version checks. Checking the iOS version or device ID is very brittle and is likely to cause your app to break in future versions. You really want to avoid it.
You can use [[UIDevice currentDevice] systemVersion] to detect the OS version, that would work. Rather than detecting the OS version, you could use respondsToSelector: to see what methods are present, NSClassFromString() != nil to see if classes are present, and fallback if that method is not available.
iOS is backward compatible, so iOS 6 will run iOS 5 apps just fine. However, if you want to use iOS 6 specific feature but still support iOS 5.1, you have to :
Compile using the 6.0 SDK so that the compilers knows new APIs
Set your target version to the lowest supported, aka. 5.1. Any system higher than that number will run the code. Any lower will not try.
Use one of the method described in 1. to make sure that each device execute codes the OS support.
I hope that's clear, don't hesitate if you have more questions
What you must do is detect functionality, not iOS version, please check out this thread:
Conditional support of iOS 6 features in an iOS 5 app
You shouldn't check against the system version but rather check against the functionality you are trying to use. On that note remember that deprecated does not mean removed so whatever you are trying to do may very well be there for iOS6. To check against a specific functionality you would do something like:
if([TheClassInQuestion class] != nil)
{
//use it
}
iOS is backwards compatible. If you compile your app for iOS 5.1 it will be perfectly run on iOS 6 as well. No need to re-implement deprecated classes.
But if you change your deployment version from 5.0 to 6.0, Xcode will show you warnings if you use deprecated methods
If you want to use methods, which are available only in iOS 6, you can use this check:
if ([self respondsToSelector:#selector(doSomething:)]) {
[self doSomething];
}

Resources