ios - 확인 - 아이폰 업데이트 12




iOS 버전 확인 방법 (20)

장치의 iOS 버전이 3.1.3 보다 큰지 확인하고 싶습니다. 다음과 같이 시도했습니다.

[[UIDevice currentDevice].systemVersion floatValue]

하지만 작동하지 않습니다, 난 그냥 싶어요 :

if (version > 3.1.3) { }

이것을 어떻게 할 수 있습니까?


선호 접근법

Swift 2.0에서 Apple은 더 편리한 구문을 사용하여 가용성 검사를 추가했습니다 (자세한 내용은 here ). 이제는 더 깨끗한 구문으로 OS 버전을 확인할 수 있습니다.

if #available(iOS 9, *) {
    // Then we are on iOS 9
} else {
    // iOS 8 or earlier
}

respondsToSelector 등을 검사하는 것보다 선호됩니다 ( Swift의 새로운 기능 ). 컴파일러는 코드를 올바르게 지키지 않으면 항상 경고합니다.

Pre Swift 2.0

iOS 8의 새로운 기능은보다 의미 론적 버전 관리 검사를 허용하는 NSProcessInfo 입니다.

iOS 8 이상에 배포

iOS 8.0 이상의 최소 배포 대상인 경우 NSProcessInfo operatingSystemVersion 또는 isOperatingSystemAtLeastVersion .

그러면 다음과 같이됩니다.

let minimumVersion = NSOperatingSystemVersion(majorVersion: 8, minorVersion: 1, patchVersion: 2)
if NSProcessInfo().isOperatingSystemAtLeastVersion(minimumVersion) {
    //current version is >= (8.1.2)
} else {
    //current version is < (8.1.2)
}

iOS 7에 배포

iOS 7.1 이하의 최소 배포 대상인 경우 UIDevice systemVersion NSStringCompareOptions.NumericSearch 와 비교하십시오.

그러면 다음과 같이됩니다.

let minimumVersionString = "3.1.3"
let versionComparison = UIDevice.currentDevice().systemVersion.compare(minimumVersionString, options: .NumericSearch)
switch versionComparison {
    case .OrderedSame, .OrderedDescending:
        //current version is >= (3.1.3)
        break
    case .OrderedAscending:
        //current version is < (3.1.3)
        fallthrough
    default:
        break;
}

NSHipster 에서 더 많은 독서.


빠른 답변 ...


Swift 2.0부터 if 또는 guard 에서 #available 을 사용하여 특정 시스템에서만 실행해야하는 코드를 보호 할 수 있습니다.

if #available(iOS 9, *) {}


Objective-C에서는 시스템 버전을 확인하고 비교를 수행해야합니다.

[[NSProcessInfo processInfo] operatingSystemVersion] iOS 8 이상.

Xcode 9부터 :

if (@available(iOS 9, *)) {}


정답 ...

드문 경우이지만 Objective-C 및 Swift에서는 장치 또는 OS 기능의 표시로 운영 체제 버전에 의존하는 것을 피하는 것이 좋습니다. 일반적으로 특정 기능이나 클래스를 사용할 수 있는지 여부를 확인하는보다 안정적인 방법이 있습니다.

API의 존재 확인 :

예를 들어 NSClassFromString 사용하여 현재 장치에서 UIPopoverController 를 사용할 수 있는지 확인할 수 있습니다.

if (NSClassFromString(@"UIPopoverController")) {
    // Do something
}

약하게 링크 된 클래스의 경우 클래스에 직접 메시지를 보내는 것이 안전합니다. 특히 이것은 "필수"로 명시 적으로 링크되지 않은 프레임 워크에서 작동합니다. 누락 된 클래스의 경우 표현식은 nil로 평가되고 조건은 실패합니다.

if ([LAContext class]) {
    // Do something
}

CLLocationManagerUIDevice 와 같은 일부 클래스는 장치 기능을 검사하는 메서드를 제공합니다.

if ([CLLocationManager headingAvailable]) {
    // Do something
}

심볼의 유무 확인 :

아주 가끔, 상수가 있는지 확인해야합니다. 이것은 iOS 8에서 UIApplicationOpenSettingsURLString 이 도입되어 -openURL: 통해 Settings 앱을로드하는 데 사용되었습니다. 값은 iOS 8 이전에는 존재하지 않았습니다.이 API에 nil을 전달하면 오류가 발생하므로 먼저 상수가 있는지 확인해야합니다.

if (&UIApplicationOpenSettingsURLString != NULL) {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}

운영 체제 버전 비교 :

운영체제 버전을 확인할 필요가 거의 없다고 가정 해 봅시다. iOS 8 이상을 대상으로하는 프로젝트의 경우 NSProcessInfo 는 오류 가능성이 적은 버전 비교를 수행하는 방법을 포함합니다.

- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version

구형 시스템을 대상으로하는 프로젝트는 UIDevice systemVersion 을 사용할 수 있습니다. Apple은 GLSprite 샘플 코드에서이를 사용합니다.

// A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
// class is used as fallback when it isn't available.
NSString *reqSysVer = @"3.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {
    displayLinkSupported = TRUE;
}

어떤 이유로 든 systemVersion 이 원하는 것으로 결정하면 문자열로 취급해야합니다. 그렇지 않으면 패치 개정 번호 (예 : 3.1.2 -> 3.1)가 잘릴 수 있습니다.


obj-C ++ 11의 좀 더 일반적인 버전 (NSString / C 함수로 대체 할 수 있지만이 방법은 덜 장황하다.) 두 가지 메커니즘이있다. splitSystemVersion은 모든 부분을 배열로 제공한다. 주요 버전 (예 : switch([self splitSystemVersion][0]) {case 4: break; case 5: break; } )을 switch([self splitSystemVersion][0]) {case 4: break; case 5: break; } 됩니다.

#include <boost/lexical_cast.hpp>

- (std::vector<int>) splitSystemVersion {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    std::vector<int> versions;
    auto i = version.begin();

    while (i != version.end()) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        versions.push_back(boost::lexical_cast<int>(versionPart));
    }

    return versions;
}

/** Losslessly parse system version into a number
 * @return <0>: the version as a number,
 * @return <1>: how many numeric parts went into the composed number. e.g.
 * X.Y.Z = 3.  You need this to know how to compare again <0>
 */
- (std::tuple<int, int>) parseSystemVersion {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    int versionAsNumber = 0;
    int nParts = 0;

    auto i = version.begin();
    while (i != version.end()) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        int part = (boost::lexical_cast<int>(versionPart));
        versionAsNumber = versionAsNumber * 100 + part;
        nParts ++;
    }

    return {versionAsNumber, nParts};
}


/** Assume that the system version will not go beyond X.Y.Z.W format.
 * @return The version string.
 */
- (int) parseSystemVersionAlt {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    int versionAsNumber = 0;
    int nParts = 0;

    auto i = version.begin();
    while (i != version.end() && nParts < 4) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        int part = (boost::lexical_cast<int>(versionPart));
        versionAsNumber = versionAsNumber * 100 + part;
        nParts ++;
    }

    // don't forget to pad as systemVersion may have less parts (i.e. X.Y).
    for (; nParts < 4; nParts++) {
        versionAsNumber *= 100;
    }

    return versionAsNumber;
}

yasimturks 솔루션의 변형으로 5 개의 매크로 대신 하나의 함수와 몇 개의 enum 값을 정의했습니다. 나는 그것을 더 우아하게 느낀다. 그러나 그것은 맛의 문제 다.

용법:

if (systemVersion(LessThan, @"5.0")) ...

.h 파일 :

typedef enum {
  LessThan,
  LessOrEqual,
  Equal,
  GreaterOrEqual,
  GreaterThan,
  NotEqual
} Comparison;

BOOL systemVersion(Comparison test, NSString* version);

.m 파일 :

BOOL systemVersion(Comparison test, NSString* version) {
  NSComparisonResult result = [[[UIDevice currentDevice] systemVersion] compare: version options: NSNumericSearch];
  switch (test) {
    case LessThan:       return result == NSOrderedAscending;
    case LessOrEqual:    return result != NSOrderedDescending;
    case Equal:          return result == NSOrderedSame;
    case GreaterOrEqual: return result != NSOrderedAscending;
    case GreaterThan:    return result == NSOrderedDescending;
    case NotEqual:       return result != NSOrderedSame;
  }
}

이름에 앱의 접두사를 추가해야하며, 특히 Comparison 유형에 접두사를 추가해야합니다.


난 항상 내 Constants.h 파일에 보관 :

#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES) 
#define IS_OS_5_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0)
#define IS_OS_6_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)
#define IS_OS_7_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
#define IS_OS_8_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

버전이 7.0 또는 6.0.3이므로 버전을 숫자로 변환하여 비교할 수 있습니다. 버전이 7.0과 같은 경우 다른 ".0"을 추가 한 다음 숫자 값을 가져옵니다.

 int version;
 NSString* iosVersion=[[UIDevice currentDevice] systemVersion];
 NSArray* components=[iosVersion componentsSeparatedByString:@"."];
 if ([components count]==2) {
    iosVersion=[NSString stringWithFormat:@"%@.0",iosVersion];

 }
 iosVersion=[iosVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
 version=[iosVersion integerValue];

6.0.0

  if (version==600) {
    // Do something
  }

7.0 용

 if (version==700) {
   // Do something
 }

신속한 [[UIDevice currentDevice] systemVersion] 및 NSFoundationVersionNumber를 사용하여 시스템 버전을 확인하는 새로운 방법.

NSProcessInfo -isOperatingSystemAtLeastVersion을 사용할 수 있습니다.

     import Foundation

     let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0)
     NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false

아래 코드를 사용해보십시오.

NSString *versionString = [[UIDevice currentDevice] systemVersion];

이 시도

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { 
// do some work
}

이 질문은 오래된 질문이지만, Availability.h 에서 컴파일 타임 매크로를 언급해야합니다. 다른 모든 메서드는 런타임 솔루션이며 헤더 파일, 클래스 범주 또는 ivar 정의에서 작동하지 않습니다.

이러한 상황에서는

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0
  // iOS 6+ code here
#else
  // Pre iOS 6 code here
#endif

this 대답은 / h


일반적으로 객체가 있어야 하는지를 결정하기 위해 버전 번호를 확인하는 대신 객체가 주어진 선택기를 수행 할 수 있는지 물어 보는 것이 좋습니다.

이것이 옵션이 아닌 경우, [@"5.0" compare:@"5" options:NSNumericSearch] 가 전혀 의도하지 않았을 NSOrderedDescending 을 반환하기 때문에 여기서주의해야합니다. 나는 여기 NSOrderedSame 기대할지도 모른다. 이것은 적어도 이론적 인 관심사입니다. 제 의견에는 변함이 없습니다.

또한 합리적으로 비교할 수없는 잘못된 버전 입력 가능성도 고려해 볼 가치가 있습니다. Apple은 NSOrderedAscending , NSOrderedSameNSOrderedDescending 이라는 세 개의 미리 정의 된 상수를 제공하지만 두 가지를 비교할 수없는 이벤트에서 NSOrderedUnordered 라는 것을 사용한다고 생각할 수 있습니다.이 값을 반환하고 싶습니다.

게다가, 언젠가는 애플이 언젠가는 비교할 가치가있는 다양한 반환 값을 허용하기 위해 세 가지 미리 정의 된 상수를 확장한다는 것은 불가능하지 않습니다 != NSOrderedAscending 현명하지 != NSOrderedAscending .

이것으로 다음 코드를 고려하십시오.

typedef enum {kSKOrderedNotOrdered = -2, kSKOrderedAscending = -1, kSKOrderedSame = 0, kSKOrderedDescending = 1} SKComparisonResult;

@interface SKComparator : NSObject
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo;
@end

@implementation SKComparator
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo {
  if (!vOne || !vTwo || [vOne length] < 1 || [vTwo length] < 1 || [vOne rangeOfString:@".."].location != NSNotFound ||
    [vTwo rangeOfString:@".."].location != NSNotFound) {
    return SKOrderedNotOrdered;
  }
  NSCharacterSet *numericalCharSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"];
  NSString *vOneTrimmed = [vOne stringByTrimmingCharactersInSet:numericalCharSet];
  NSString *vTwoTrimmed = [vTwo stringByTrimmingCharactersInSet:numericalCharSet];
  if ([vOneTrimmed length] > 0 || [vTwoTrimmed length] > 0) {
    return SKOrderedNotOrdered;
  }
  NSArray *vOneArray = [vOne componentsSeparatedByString:@"."];
  NSArray *vTwoArray = [vTwo componentsSeparatedByString:@"."];
  for (NSUInteger i = 0; i < MIN([vOneArray count], [vTwoArray count]); i++) {
    NSInteger vOneInt = [[vOneArray objectAtIndex:i] intValue];
    NSInteger vTwoInt = [[vTwoArray objectAtIndex:i] intValue];
    if (vOneInt > vTwoInt) {
      return kSKOrderedDescending;
    } else if (vOneInt < vTwoInt) {
      return kSKOrderedAscending;
    }
  }
  if ([vOneArray count] > [vTwoArray count]) {
    for (NSUInteger i = [vTwoArray count]; i < [vOneArray count]; i++) {
      if ([[vOneArray objectAtIndex:i] intValue] > 0) {
        return kSKOrderedDescending;
      }
    }
  } else if ([vOneArray count] < [vTwoArray count]) {
    for (NSUInteger i = [vOneArray count]; i < [vTwoArray count]; i++) {
      if ([[vTwoArray objectAtIndex:i] intValue] > 0) {
        return kSKOrderedAscending;
      }
    }
  }
  return kSKOrderedSame;
}
@end

파티에 약간 늦었지만 iOS 8.0에 비추어 볼 때 이것은 적절할 수 있습니다.

사용을 피할 수 있다면

[[UIDevice currentDevice] systemVersion]

대신 메소드 / 클래스 / 다른 것의 존재 여부를 확인하십시오.

if ([self.yourClassInstance respondsToSelector:@selector(<yourMethod>)]) 
{ 
    //do stuff 
}

iOS 8.0에서 requestWhenInUseAuthorization을 호출해야하지만 위치를 iOS 8.0에서 사용할 수없는 위치 관리자에게 유용하다는 것을 알았습니다.


nv-ios-version 프로젝트 (Apache License, Version 2.0)에 포함 된 Version 클래스를 사용하면 iOS 버전을 쉽게 얻고 비교할 수 있습니다. 아래의 예제 코드는 iOS 버전을 덤프하고 버전이 6.0 이상인지 확인합니다.

// Get the system version of iOS at runtime.
NSString *versionString = [[UIDevice currentDevice] systemVersion];

// Convert the version string to a Version instance.
Version *version = [Version versionWithString:versionString];

// Dump the major, minor and micro version numbers.
NSLog(@"version = [%d, %d, %d]",
    version.major, version.minor, version.micro);

// Check whether the version is greater than or equal to 6.0.
if ([version isGreaterThanOrEqualToMajor:6 minor:0])
{
    // The iOS version is greater than or equal to 6.0.
}

// Another way to check whether iOS version is
// greater than or equal to 6.0.
if (6 <= version.major)
{
    // The iOS version is greater than or equal to 6.0.
}

프로젝트 페이지 : nv-ios-version
nv-ios-version

블로그 : 런타임에 iOS 버전을 가져 와서 Version 클래스와 비교하십시오 .
런타임시 iOS 버전과 Version 클래스 가져 오기 및 비교


Objective-C 에서 Xcode 9 시작 :

if (@available(iOS 11, *)) {
    // iOS 11 (or newer) ObjC code
} else {
    // iOS 10 or older code
}

Swift 에서 Xcode 7 시작 :

if #available(iOS 11, *) {
    // iOS 11 (or newer) Swift code
} else {
    // iOS 10 or older code
}

버전의 경우 MAJOR, MINOR 또는 PATCH ( http://semver.org/ 정의 http://semver.org/ 를 지정할 수 있습니다. 예 :

  • iOS 11iOS 11.0 은 동일한 최소 버전입니다.
  • iOS 10 , iOS 10.3 , iOS 10.3.1 은 최소 버전입니다.

해당 시스템에 대한 값을 입력 할 수 있습니다.

  • iOS , macOS , watchOS , tvOS

내 포드 중 하나 에서 가져온 실제 사례 :

if #available(iOS 10.0, tvOS 10.0, *) {
    // iOS 10+ and tvOS 10+ Swift code
} else {
    // iOS 9 and tvOS 9 older code
}

documentation


UIDevice + IOSVersion.h

@interface UIDevice (IOSVersion)

+ (BOOL)isCurrentIOSVersionEqualToVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionGreaterThanVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionGreaterThanOrEqualToVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionLessThanVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionLessThanOrEqualToVersion:(NSString *)iOSVersion

@end

UIDevice + IOSVersion.m

#import "UIDevice+IOSVersion.h"

@implementation UIDevice (IOSVersion)

+ (BOOL)isCurrentIOSVersionEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedSame;
}

+ (BOOL)isCurrentIOSVersionGreaterThanVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedDescending;
}

+ (BOOL)isCurrentIOSVersionGreaterThanOrEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] != NSOrderedAscending;
}

+ (BOOL)isCurrentIOSVersionLessThanVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedAscending;
}

+ (BOOL)isCurrentIOSVersionLessThanOrEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] != NSOrderedDescending;
}

@end

실제로 작동하는 신속한 예 :

switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) {
case .OrderedSame, .OrderedDescending:
    println("iOS >= 8.0")
case .OrderedAscending:
    println("iOS < 8.0")
}

8.0에서 작동하지 않는 NSProcessInfo를 사용하지 마십시오. 따라서 2016 년까지 쓸모가 없습니다.


#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

그런 다음 if 조건을 다음과 같이 추가하십시오.

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
   //Your code
}       

#define _kisiOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

if (_kisiOS7) {
            NSLog(@"iOS7 or greater")
} 
else {
           NSLog(@"Less than iOS7");
}

/*
 *  System Versioning Preprocessor Macros
 */ 

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

/*
 *  Usage
 */ 

if (SYSTEM_VERSION_LESS_THAN(@"4.0")) {
    ...
}

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"3.1.1")) {
    ...
}

float deviceOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
float versionToBeCompared = 3.1.3; //(For Example in your case)

if(deviceOSVersion < versionToBeCompared)
   //Do whatever you need to do. Device version is lesser than 3.1.3(in your case)
else 
   //Device version should be either equal to the version you specified or above






objective-c