2

I am building with Xcode 5/iOS SDK 6.1. If the app runs on an iOS 7.x device it should check whether the setting "Settings -> General -> BackgroundAppRefresh" is set for the app. Since this property is only available on iOS 7 I am doing:

if([[UIApplication sharedApplication] respondsToSelector:@selector(backgroundRefreshStatus)])
{
    NSInteger outcome=[[[UIApplication sharedApplication] performSelector:@selector(backgroundRefreshStatus)] integerValue];
    //do something with "outcome"
}

However... the app crashes on iOS 7 at the "performSelector" line which is strange because it passes the "respondsToSelector" call?? Anyone knows why? I also tried NSSelectorFromString(@"backgroundRefreshStatus") with the same result.

2 Answers2

4

You've got a lot of unnecessary code there. Unless the backgroundRefreshStatus selector exists before iOS 7 as a private API you don't need the version check.

Your use of @selector is also incorrect and you don't need to use performSelector, just call the method:

if ([[UIApplication sharedApplication] respondsToSelector:@selector(backgroundRefreshStatus)]) {
    UIBackgroundRefreshStatus refreshStatus = [[UIApplication sharedApplication] backgroundRefreshStatus];
}
David Snabel-Caunt
  • 57,804
  • 13
  • 114
  • 132
  • It won´t compile with iOS 6 SDK because neither "UIBackgroundRefreshStatus" nor "backgroundRefreshStatus" is defined there! – Franz van der Steg Nov 06 '13 at 15:06
  • You should really be developing with the iOS 7 SDK and enabling backwards compatibility with iOS 6 by using techniques like checking if a receiver `respondsToSelector`, rather than using an old SDK and trying to be 'forwards compatible'. If you insist on using an older SDK (which isn't necessary to achieve compatibility with both iOS 6 & 7) you'll have to use [NSInvocation](http://stackoverflow.com/a/2716195/80425) in this case as UIBackgroundRefreshStatus is a primitive type, which is extremely messy. – David Snabel-Caunt Nov 06 '13 at 15:26
1

You are using a string as the selector. Try without the string:

UIApplication *app = [UIApplication sharedApplication];
if([app respondsToSelector:@selector(backgroundRefreshStatus)])
{
    UIBackgroundRefreshStatus outcome = [app performSelector:@selector(backgroundRefreshStatus)];
    // or outcome = [app backgroundRefreshStatus]
}
Mike D
  • 4,938
  • 6
  • 43
  • 99
  • You are right about the string. It was my fault because in my code it was right. I changed my original post. The problem with your solution is that "UIBackgroundRefreshStatus" is not available within the iOS 6.1 SDK so it will not compile. What I tried was: NSInteger status=[[[UIApplication sharedApplication] performSelector:@selector(backgroundRefreshStatus)] integerValue]; but with no success. – Franz van der Steg Nov 06 '13 at 14:58