1

I have been tried the following two kinds of codes.

Run time:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0) {
    CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
    CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); 
}

Compile time:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 {
    CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
    CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); 
}

kCFStreamNetworkServiceType and kCFStreamNetworkServiceTypeVoIP are the constants provided in iOS 4.0. However, I need to build the above codes into the device with iOS 3.1 due to some reasons. If I build the above codes into the device with iOS 3.1, it will crash when I open the application. Are there any ways to solve the problem?

  • I'm just curious why you accepted Apurv's answer. It's wrong. Testing the OS version by comparing it to a float is not generally correct. See the link for OS version macros in my answer, or the example I added as to why this fails. – Nate Aug 01 '12 at 01:00
  • Sorry about that. My point is how to avoid compiling the constants. Anyway, in my case, `if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0)` is enough to utilize. Thanks. – Chih-Shu Shih Aug 07 '12 at 03:46
  • No, it's actually not enough. If you run that code, for example, on a device with OS 4.0.1, you may get the incorrect result from `([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0)`. Please see my example below. – Nate Aug 07 '12 at 03:57

2 Answers2

1

I agree with Apurv that you should set the Deployment Target in your Xcode build settings, to iOS 3.1, and built with the latest Base SDK. But, I don't recommend that test for the operating system version.

OS versions are not floating point numbers. "3.1.3" is a valid OS version, but it is not a floating point number. Also, comparison of floating point numbers is never really a good idea.

Instead, use the macros from this other Stack Overflow answer

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"4.0")) {
    CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
    CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); 
}

Edit: As an example of why this is necessary, consider the code:

NSString* osVersion = @"3.1.3";
float x = [osVersion floatValue];
NSLog(@"OS version = %lf", x);
if (x >= 3.1) {
    NSLog(@"OS >= 3.1");
} else if (x < 3.1) {
    NSLog(@"OS < 3.1");
}

Running this on an iPhone 5.0 simulator produces the following output, which is obviously not what you want:

2012-07-31 17:56:38.155 HelloWorld[5856:f803] OS version = 3.100000

2012-07-31 17:56:41.257 HelloWorld[5856:f803] OS < 3.1

If you inspect the value of x in the debugger, I see it as 3.0999999, which triggers the incorrect comparison result.

Community
  • 1
  • 1
Nate
  • 31,017
  • 13
  • 83
  • 207
0

You should build your application with latest SDK and provide the deployment target to iOS 3.1.

If you are putting the below check, then it should not get crash.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0) {
    CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
    CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); 
}
Apurv
  • 17,116
  • 8
  • 51
  • 67