질문에서 알 수 있듯이 주로 내 코드가 시뮬레이터에서 실행 중인지 여부를 알고 싶지만 실행 중이거나 시뮬레이션중인 특정 iPhone 버전을 알고 싶어합니다.
편집 : 질문 이름에 '프로그래밍 방식으로'라는 단어를 추가했습니다. 내 질문의 요점은 실행중인 버전 / 시뮬레이터에 따라 코드를 동적으로 포함 / 제외 할 수 있기 때문에 실제로이 정보를 제공 할 수있는 전 프로세서 지시문과 같은 것을 찾고 있습니다.
질문에서 알 수 있듯이 주로 내 코드가 시뮬레이터에서 실행 중인지 여부를 알고 싶지만 실행 중이거나 시뮬레이션중인 특정 iPhone 버전을 알고 싶어합니다.
편집 : 질문 이름에 '프로그래밍 방식으로'라는 단어를 추가했습니다. 내 질문의 요점은 실행중인 버전 / 시뮬레이터에 따라 코드를 동적으로 포함 / 제외 할 수 있기 때문에 실제로이 정보를 제공 할 수있는 전 프로세서 지시문과 같은 것을 찾고 있습니다.
답변:
이미 요청했지만 제목이 매우 다릅니다.
iPhone을 컴파일 할 때 Xcode에서 #define을 설정하는 것
나는 거기에서 내 대답을 반복 할 것이다.
SDK 문서의 "조건부 소스 코드 컴파일"에 있습니다.
관련 정의는 TARGET_OS_SIMULATOR이며, 이는 iOS 프레임 워크의 /usr/include/TargetConditionals.h에 정의되어 있습니다. 이전 버전의 툴체인에서는 다음과 같이 작성해야했습니다.
#include "TargetConditionals.h"
그러나 현재 (Xcode 6 / iOS8) 툴체인에서는 더 이상 필요하지 않습니다.
예를 들어 장치에서 실행 중인지 확인하려면 수행해야합니다.
#if TARGET_OS_SIMULATOR
// Simulator-specific code
#else
// Device-specific code
#endif
사용 사례에 적합한 방법에 따라
이것은 공식적으로 작동하도록되어 있습니다.
#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif
이 코드는 시뮬레이터에서 실행 중인지 알려줍니다.
#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif
전 처리기 지시문은 아니지만 이것이 내가이 질문에 왔을 때 찾고 있던 것입니다.
NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
//device is simulator
}
[model compare:iPhoneSimulator] == NSOrderedSame
작성[model isEqualToString:iPhoneSimulator]
[model hasSuffix:@"Simulator"]
일반적으로 "시뮬레이터"에만 관심이 있다면, 특히 iPhone 또는 iPad 는 아닙니다 . 이 답변은 iPad 시뮬레이터에서 작동하지 않습니다 :)
name
model
Simulator
자신의 장치 이름에 단어를 추가하면 코드가 작동하지 않습니다
더 나은 길은 지금 있습니다!
Xcode 9.3 베타 4 #if targetEnvironment(simulator)
부터 확인할 수 있습니다 .
#if targetEnvironment(simulator)
//Your simulator code
#endif
업데이트
Xcode 10 및 iOS 12 SDK도이를 지원합니다.
Swift의 경우 다음을 구현할 수 있습니다.
구조화 된 데이터를 만들 수있는 구조체를 만들 수 있습니다
struct Platform {
static var isSimulator: Bool {
#if targetEnvironment(simulator)
// We're on the simulator
return true
#else
// We're on a device
return false
#endif
}
}
그런 다음 Swift에서 장치 또는 시뮬레이터 용 앱이 빌드되고 있는지 감지하려면.
if Platform.isSimulator {
// Do one thing
} else {
// Do the other
}
#if #else #endif
더 나을 것이라고 생각 합니다.
모든 대답은 훌륭하지만 컴파일 검사와 런타임 검사를 명확히하지 않기 때문에 어떻게 든 저와 초보자를 혼동합니다. 전처리 기는 컴파일 시간 이전이지만 더 명확하게 만들어야합니다.
이 블로그 기사는 iPhone 시뮬레이터를 감지하는 방법을 보여줍니다 . 분명히
실행 시간
우선, 간단히 논의 해 봅시다. UIDevice는 이미 장치에 대한 정보를 제공합니다
[[UIDevice currentDevice] model]
앱이 실행중인 위치에 따라 "iPhone Simulator"또는 "iPhone"을 반환합니다.
컴파일 시간
그러나 원하는 것은 컴파일 시간 정의를 사용하는 것입니다. 왜? 시뮬레이터 내부 또는 장치에서 실행되도록 앱을 엄격하게 컴파일하기 때문입니다. Apple은이라는 정의를 만듭니다 TARGET_IPHONE_SIMULATOR
. 코드를 보자.
#if TARGET_IPHONE_SIMULATOR
NSLog(@"Running in Simulator - no app store or giro");
#endif
[[UIDevice currentDevice] model]
는 iPhone
대신을 반환 iPhone Simulator
합니다. 따라서 이것이 최선의 방법은 아니라고 생각합니다.
이전 답변은 약간 날짜가 있습니다. TARGET_IPHONE_SIMULATOR
매크로를 쿼리하기 만하면됩니다 ( 다른 헤더 파일을 포함 할 필요가 없습니다 ( iOS 용으로 코딩한다고 가정)).
시도 TARGET_OS_IPHONE
했지만 실제 장치 및 시뮬레이터에서 실행할 때 동일한 값 (1)을 반환했기 때문에 TARGET_IPHONE_SIMULATOR
대신 사용 하는 것이 좋습니다 .
저도 같은 문제를 겪고, 모두 TARGET_IPHONE_SIMULATOR
와 TARGET_OS_IPHONE
항상 정의, 그리고 물론 1 피트의 솔루션 작품에 설정되지만으로 안전, 여기의 뭔가를 당신은 이제까지 인텔이 아닌 다른 무언가에 빌드로 발생 (가능성,하지만 누가 알 겠어) 경우 아이폰 하드웨어가 변경되지 않는 한 (코드는 항상 현재 존재하는 아이폰에서 작동합니다) :
#if defined __arm__ || defined __thumb__
#undef TARGET_IPHONE_SIMULATOR
#define TARGET_OS_IPHONE
#else
#define TARGET_IPHONE_SIMULATOR 1
#undef TARGET_OS_IPHONE
#endif
편리한 곳에두고 TARGET_*
상수가 올바르게 정의 된 척하십시오 .
누구든지 여기에 제공된 대답을 고려 했습니까?
objective-c에 해당하는 것으로 가정합니다.
+ (BOOL)isSimulator {
NSOperatingSystemVersion ios9 = {9, 0, 0};
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
if ([processInfo isOperatingSystemAtLeastVersion:ios9]) {
NSDictionary<NSString *, NSString *> *environment = [processInfo environment];
NSString *simulator = [environment objectForKey:@"SIMULATOR_DEVICE_NAME"];
return simulator != nil;
} else {
UIDevice *currentDevice = [UIDevice currentDevice];
return ([currentDevice.model rangeOfString:@"Simulator"].location != NSNotFound);
}
}
스위프트 4.2 / xCode 10
UIDevice에서 확장을 만들었으므로 시뮬레이터가 실행 중인지 쉽게 요청할 수 있습니다.
// UIDevice+CheckSimulator.swift
import UIKit
extension UIDevice {
/// Checks if the current device that runs the app is xCode's simulator
static func isSimulator() -> Bool {
#if targetEnvironment(simulator)
return true
#else
return false
#endif
}
}
예를 들어 내 AppDelegate 에서이 방법을 사용하여 시뮬레이터에 불가능한 원격 알림을 등록해야하는지 결정합니다.
// CHECK FOR REAL DEVICE / OR SIMULATOR
if UIDevice.isSimulator() == false {
// REGISTER FOR SILENT REMOTE NOTIFICATION
application.registerForRemoteNotifications()
}
모든 유형의 "시뮬레이터"를 포함하려면
NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
// we are running in a simulator
}
-[NSString containsString]
?
내 대답은 @Daniel Magnusson 답변과 @Nuthatch 및 @ n.Drake의 의견을 기반으로합니다. iOS9 이상에서 작업하는 신속한 사용자를 위해 시간을 절약하기 위해 작성했습니다.
이것이 나를 위해 일한 것입니다.
if UIDevice.currentDevice().name.hasSuffix("Simulator"){
//Code executing on Simulator
} else{
//Code executing on Device
}
Simulator
자신의 장치 이름에 단어를 추가하면 코드가 작동하지 않습니다
UIDevice.current.name
에서는 시뮬레이터가 실행되는 시스템의 이름 (일반적으로 "Simon 's MacBook Pro"와 같은 이름)이보고되어 테스트를 신뢰할 수 없게되었습니다. 나는 여전히 그것을 고칠 수있는 깨끗한 방법을 찾고 있습니다.
/// 시뮬레이터가 아닌 장치 인 경우 true를 리턴합니다.
public static var isSimulator: Bool {
#if (arch(i386) || arch(x86_64)) && os(iOS)
return true
#else
return false
#endif
}
아무것도 효과가 없다면 이것을 시도하십시오
public struct Platform {
public static var isSimulator: Bool {
return TARGET_OS_SIMULATOR != 0 // Use this line in Xcode 7 or newer
}
}
내 의견으로는, 대답 (위에 제시되고 아래에 반복) :
NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
//device is simulator
}
런타임에 분명히 실행되고 COMPILE DIRECTIVE이기 때문에 가장 좋은 대답입니다.