Swift에서 앱이 장치 또는 시뮬레이터용으로 구축되어 있는지 여부를 감지하는 방법
Objective-C에서는 매크로를 사용하여 앱이 디바이스용인지 시뮬레이터용인지를 알 수 있습니다.
#if TARGET_IPHONE_SIMULATOR
// Simulator
#else
// Device
#endif
이것들은 컴파일 시 매크로이며 실행 시 사용할 수 없습니다.
Swift에서도 어떻게 같은 일을 할 수 있을까요?
업데이트 30/01/19
이 답변은 효과가 있을 수 있지만 (여러 Apple 엔지니어에 의해 명확하게 설명되었듯이) 정적 체크를 위해 권장되는 솔루션은 iOS Simulators를 대상으로 한 커스텀 컴파일러 플래그를 정의하는 것입니다.자세한 방법은 @mbelsky의 답변을 참조하십시오.
원답
정적 체크가 필요한 경우(예를 들어 런타임 if/else가 아님) 시뮬레이터를 직접 검출할 수는 없지만 다음과 같은 데스크톱 아키텍처에서 iOS를 검출할 수 있습니다.
#if (arch(i386) || arch(x86_64)) && os(iOS)
...
#endif
Swift 4.1 버전 이후
모든 유형의 시뮬레이터에 대해 한 가지 조건에서 직접 사용하는 최신 사용에서는 한 가지 조건만 적용하면 됩니다.
#if targetEnvironment(simulator)
// your simulator code
#else
// your real device code
#endif
자세한 내용은 Swift 제안서 SE-0190을 참조하십시오.
이전 버전의 경우 -
이것은 디바이스에서는 false이지만, 설명서에 기재되어 있듯이 iOS Simulator에서는 true가 반환됩니다.
arch(i386) 빌드 구성은 코드가 32비트 iOS 시뮬레이터용으로 컴파일되면 true를 반환합니다.
중인 iOS를 할 수 .os
★★★★★★★★★★★★★★★★★★
시계를 검출하다OS 시뮬레이터
#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endif
TVOS 시뮬레이터를 검출하다
#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endif
또는 시뮬레이터를 검출할 수도 있습니다.
#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif
시 체크에 가 없는 는, 「 」를 할 수 있습니다.」를 할 수 있습니다.TARGET_OS_SIMULATOR
"변수")TARGET_IPHONE_SIMULATOR
8버전)은입니다. (iOS 8은 truthy).
이것은 프리프로세서 플래그를 사용하는 것과는 다르며 조금 더 제한적이라는 점에 유의하시기 바랍니다., 예, 이, 이, 이, 이, 이, 이, 습, 습, 습, for, for, for, for, for, for, for, for, for, for, for, for, for, for,if/else
구문적으로 유효하지 않습니다(예를 들어 기능 범위 외).
예를 들어, 디바이스와 시뮬레이터에서 다른 Import를 할 수 있습니다.이것은 동적 검사에서는 불가능하지만 정적 검사에서는 사소한 것입니다.
#if (arch(i386) || arch(x86_64)) && os(iOS)
import Foo
#else
import Bar
#endif
also also also 로 바뀌기 0
★★★1
preprocessor에서 swift preprocessor에 if/else
도달 불능 코드에 대한 경고를 컴파일러가 발생시키는 식입니다.
이 경고를 회피하려면 다른 답변 중 하나를 참조하십시오.
SWIFT 4.1에는 구식입니다.사용하다#if targetEnvironment(simulator)
대신.출처
Swift에서 시뮬레이터를 감지하려면 빌드 구성을 사용할 수 있습니다.
- Swift 컴파일러에서 D IOS_SIMATOR 설정을 정의합니다(커스텀플래그> 기타 Swift 플래그).
- 이 드롭다운에서 iOS Simulator SDK를 선택합니다.
이제 시뮬레이터를 검출하기 위해 다음 문을 사용할 수 있습니다.
#if IOS_SIMULATOR
print("It's an iOS Simulator")
#else
print("It's a device")
#endif
UIDevice 클래스를 확장할 수도 있습니다.
extension UIDevice {
var isSimulator: Bool {
#if IOS_SIMULATOR
return true
#else
return false
#endif
}
}
// Example of usage: UIDevice.current.isSimulator
2018년 2월 20일자로 갱신된 정보
@russbishop은 오랫동안 효과가 있었던 것처럼 보였지만, 이 대답이 "잘못된" 것으로 보이는 권위 있는 답변을 가지고 있는 것 같습니다.
이전 답변
@WZW의 답변과 @Pang의 코멘트를 바탕으로 심플한 유틸리티 구조를 만들었습니다.이 솔루션은 @WZW의 답변에 의한 경고를 회피합니다.
import Foundation
struct Platform {
static var isSimulator: Bool {
return TARGET_OS_SIMULATOR != 0
}
}
사용 예:
if Platform.isSimulator {
print("Running on Simulator")
}
스위프트 4
해서 '어울리지 않다'를 할 수 되었습니다.targetEnvironment(simulator)
의론으로서.
#if targetEnvironment(simulator)
// Simulator
#else
// Device
#endif
Xcode 9.3용으로 업데이트됨
Xcode 9.3부터
#if targetEnvironment(simulator)
Swift는 하나의 유효한 인수 시뮬레이터를 사용하여 새로운 플랫폼 조건 targetEnvironment를 지원합니다.빌드 대상이 시뮬레이터인 경우를 감지하기 위해 '#if targetEnvironment(시뮬레이터)' 형식의 조건부 컴파일을 사용할 수 있습니다.Swift 컴파일러는 기존 os() 및 arch() 플랫폼 조건을 통해 시뮬레이터 환경을 간접적으로 테스트하는 것으로 보이는 플랫폼 조건을 평가할 때 targetEnvironment(시뮬레이터) 사용을 검출, 경고 및 제안합니다. (SE-0190)
iOS 9+:
extension UIDevice {
static var isSimulator: Bool {
return NSProcessInfo.processInfo().environment["SIMULATOR_DEVICE_NAME"] != nil
}
}
스위프트 3:
extension UIDevice {
static var isSimulator: Bool {
return ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
}
}
iOS 9 이전 버전:
extension UIDevice {
static var isSimulator: Bool {
return UIDevice.currentDevice().model == "iPhone Simulator"
}
}
목표-C:
@interface UIDevice (Additions)
- (BOOL)isSimulator;
@end
@implementation UIDevice (Additions)
- (BOOL)isSimulator {
if([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9, 0, 0}]) {
return [NSProcessInfo processInfo].environment[@"SIMULATOR_DEVICE_NAME"] != nil;
} else {
return [[self model] isEqualToString:@"iPhone Simulator"];
}
}
@end
여기서 몇 가지 사항을 명확히 하겠습니다.
TARGET_OS_SIMULATOR
는 대부분의 경우 Swift 코드로 설정되어 있지 않습니다.브릿지헤더 때문에 실수로 Import 되는 경우가 있습니다만, 이것은 취약하기 때문에 지원되지 않습니다.그것은 또한 프레임워크에서도 가능하지 않다.이것이 Swift에서 이것이 작동되는지 헷갈리는 이유다.- 시뮬레이터 대신 건축을 사용하지 말 것을 강력히 권합니다.
동적 검사를 수행하려면:
중ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
아무 문제 없어요
수 .SIMULATOR_MODEL_IDENTIFIER
는 " "와 문자열을 반환합니다.iPhone10,3
.
정적 검사를 수행하려면:
Xcode 9.2 및 이전 버전: 독자적인 Swift 컴파일 플래그를 정의합니다(다른 답변 참조).
Xcode 9.3+는 새로운 targetEnvironment 조건을 사용합니다.
#if targetEnvironment(simulator)
// for sim only
#else
// for device
#endif
Swift 5.2.4 X 코드 11.7
#if targetEnvironment(simulator)
#endif
런타임이지만, 여기서는 다른 대부분의 솔루션보다 단순합니다.
if TARGET_OS_SIMULATOR != 0 {
// target is current running in the simulator
}
또는 (특히 프로젝트에서 이미 혼합된 경우) 프리프로세서 매크로를 사용하는 부울을 반환하는 Objective-C 도우미 함수를 호출할 수도 있습니다.
편집: 특히 Xcode 9.3에서는 최적의 솔루션이 아닙니다.Hot Jard의 답변 보기
Swift 1.0이 Arm 이외의 아키텍처를 체크하고 있기 때문에 다음과 같은 이점이 있습니다.
#if arch(i386) || arch(x86_64)
//simulator
#else
//device
#endif
이 내선번호가 편리했으면 좋겠어요.
extension UIDevice {
static var isSimulator: Bool = {
#if targetEnvironment(simulator)
return true
#else
return false
#endif
}()
}
사용방법:
if UIDevice.isSimulator {
print("running on simulator")
}
최신 시스템:
#if targetEnvironment(simulator)
// sim
#else
// device
#endif
아주 쉬워요.
TARGET_IPHONE_SIMULATOR
는 iOS 9에서는 권장되지 않습니다.TARGET_OS_SIMULATOR
대체품입니다.또한.TARGET_OS_EMBEDDED
사용할 수 있습니다.
TargetConditionals.h 에서:
#if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) ) . . . #define TARGET_OS_SIMULATOR 0 #define TARGET_OS_EMBEDDED 1 #define TARGET_IPHONE_SIMULATOR TARGET_OS_SIMULATOR /* deprecated */ #define TARGET_OS_NANO TARGET_OS_WATCH /* deprecated */
Xcode 11, Swift 5
#if !targetEnvironment(macCatalyst)
#if targetEnvironment(simulator)
true
#else
false
#endif
#endif
Xcode 7.2(및 이전 버전이지만 얼마나 이전 버전인지 테스트하지 않음)에서는 "Any iOS Simulator"에 대해 플랫폼 고유의 빌드 플래그 "-D TARGET_IPHONE_SIMATOR"을 설정할 수 있습니다.
"Swift Compiler - Customer Flags" 아래에 있는 프로젝트 빌드 설정을 확인하고 "Other Swift Flags"에서 플래그를 설정합니다.빌드 구성 위로 마우스를 가져가면 '더하기' 아이콘을 클릭하여 플랫폼별 플래그를 설정할 수 있습니다.
이 방법에는 몇 가지 장점이 있습니다.1) Swift 코드와 Objective-C 코드에서 동일한 조건부 테스트("#if TARGET_IPHONE_SIMATOR")를 사용할 수 있습니다.2) 각 빌드에만 적용되는 변수를 컴파일할 수 있습니다.
여기 다윈이 모두 묘사되어 있다.Target Conditionals : https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/Base.subproj/SwiftRuntime/TargetConditionals.h
TARGET_OS_SIMULATOR - Generated code will run under a simulator
아래 코드를 사용합니다.
#if targetEnvironment(simulator)
// Simulator
#else
// Device
#endif
기능하는 것Swift 4
그리고.Xcode 9.4.1
여기 Xcode 11 Swift의 예가 위의 HotJard의 훌륭한 답변에 근거하고 있습니다.이것 또한,isDevice
Bool 및 용도SIMULATOR_UDID
이름 대신.변수 할당은 각 행에서 수행되므로 원하는 경우 디버거에서 더 쉽게 검사할 수 있습니다.
import Foundation
// Extensions to UIDevice based on ProcessInfo.processInfo.environment keys
// to determine if the app is running on an actual device or the Simulator.
@objc extension UIDevice {
static var isSimulator: Bool {
let environment = ProcessInfo.processInfo.environment
let isSimulator = environment["SIMULATOR_UDID"] != nil
return isSimulator
}
static var isDevice: Bool {
let environment = ProcessInfo.processInfo.environment
let isDevice = environment["SIMULATOR_UDID"] == nil
return isDevice
}
}
의 사전 항목도 있습니다.DTPlatformName
그 안에는simulator
.
다른 답변과 함께요.
Objective-c에서 TargetConditionals를 포함했는지 확인합니다.
#include <TargetConditionals.h>
사용하기 전에TARGET_OS_SIMULATOR
.
Swift 3에서 아래 코드를 사용했습니다.
if TARGET_IPHONE_SIMULATOR == 1 {
//simulator
} else {
//device
}
Swift 4:
현시점에서는 이 프로세스를 사용하는 것을 선호합니다.디바이스가 시뮬레이터인지 여부와 사용 중인 디바이스의 종류를 알 수 있는 정보 클래스:
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
print("yes is a simulator :\(simModelCode)")
}
simModelCode
어떤 종류의 시뮬레이터가 시작되었는지 바로 알 수 있는 코드는 아닙니다.필요하다면 현재 아이폰/디바이스 모델을 판별하고 보다 사람이 읽을 수 있는 문자열을 얻기 위해 다른 SO 답변을 볼 수 있습니다.
이것이 누구에게 도움이 될지는 모르겠지만 적어도 현재 버전의 M1 mac은 SIMATOR_MODEL_IDENTIFIER를 NS Process에 전달하지 않는 것 같습니다.정보
나는 사용했다
BOOL isMobile = [[NSProcessInfo processInfo].environment[@"USER"] isEqual:@"mobile"];
신속한 대응이 가능합니다.이것은 깨지기 쉬울지도 모르지만 효과가 있다.
언급URL : https://stackoverflow.com/questions/24869481/how-to-detect-if-app-is-being-built-for-device-or-simulator-in-swift
'programing' 카테고리의 다른 글
svn 로그에 특정 사용자의 커밋을 표시하는 방법 (0) | 2023.04.19 |
---|---|
Windows 10에서 WSL 단말기의 비프음을 무효로 합니다. (0) | 2023.04.19 |
VBA 또는 매크로 없이 Excel을 루프인하려면 어떻게 해야 합니까? (0) | 2023.04.14 |
Swift Array - 인덱스가 존재하는지 확인합니다. (0) | 2023.04.14 |
git 마크를 삭제한 파일과 새로운 파일을 파일 이동으로 만드는 방법 (0) | 2023.04.14 |