Как я могу программным образом определить, работает ли мое приложение в симуляторе iphone?

Как говорится в этом вопросе, мне бы хотелось узнать, действительно ли мой код запущен в симуляторе, но он также будет заинтересован в том, чтобы знать конкретную версию iphone, которая работает или моделируется.

EDIT: я добавил слово "программно" в имя вопроса. Суть моего вопроса состоит в том, чтобы иметь возможность динамически включать/исключать код в зависимости от того, какая версия/симулятор работает, поэтому я действительно искал бы что-то вроде предпроцессорной директивы, которая может предоставить мне эту информацию.

Ответ 1

Уже спросил, но с совсем другим названием.

Какие #defines настроены Xcode при компиляции для iPhone

Я повторю свой ответ оттуда:

Это в документах SDK в разделе "Компиляция исходного кода условно"

Соответствующее определение - TARGET_OS_SIMULATOR, которое определено в /usr/include/TargetConditionals.h в рамках iOS. В более ранних версиях инструментальной цепочки вам нужно было написать:

#include "TargetConditionals.h"

но это больше не нужно для текущей (Xcode 6/iOS8) toolchain.

Итак, например, если вы хотите проверить, что вы работаете на устройстве, вы должны сделать

#if TARGET_OS_SIMULATOR
    // Simulator-specific code
#else
    // Device-specific code
#endif

в зависимости от того, что подходит для вашего прецедента.

Ответ 2

Обновленный код:

Предполагается, что он официально работает.

#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

Ответ 3

Не предпроцессорная директива, но это было то, что я искал, когда я пришел к этому вопросу;

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}

Ответ 4

Лучший способ сделать это:

#if TARGET_IPHONE_SIMULATOR

а не

#ifdef TARGET_IPHONE_SIMULATOR

поскольку он всегда определен: 0 или 1

Ответ 5

В случае Swift мы можем реализовать следующие

Мы можем создать структуру, которая позволяет создавать структурированные данные

struct Platform {
    static let isSimulator: Bool = {
        #if arch(i386) || arch(x86_64)
            return true
        #endif
        return false
    }()
}

Затем, если мы хотим определить, будет ли приложение создано для устройства или симулятора в Swift, тогда.

if Platform.isSimulator {
    // Do one thing
}
else {
    // Do the other
}

Ответ 6

Все эти ответы хороши, но это как-то путает новичков, подобных мне, поскольку оно не уточняет проверку компиляции и проверку выполнения. Препроцессор перед компиляцией, но мы должны сделать его более ясным

В этой статье в блоге Как определить симулятор iPhone? ясно

Runtime

Прежде всего, давайте вкратце обсудим. 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

Ответ 8

У меня была такая же проблема, как и TARGET_IPHONE_SIMULATOR, так и TARGET_OS_IPHONE всегда определены и установлены в 1. Решение Пит работает, конечно, но если вы когда-нибудь создадите что-то другое, кроме intel (маловероятно, но кто знает), здесь что-то безопасное до тех пор, пока аппаратное обеспечение iphone не изменится (поэтому ваш код всегда будет работать для iphones в настоящее время там):

#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_* определены правильно.

Ответ 9

Предыдущие ответы немного устарели. Я обнаружил, что все, что вам нужно сделать, это запросить макрос TARGET_IPHONE_SIMULATOR ( не нужно включать какие-либо другие файлы заголовков [при условии, что вы кодируете iOS]).

Я попытался TARGET_OS_IPHONE, но он вернул то же значение (1) при запуске на реальном устройстве и симуляторе, поэтому я рекомендую вместо этого использовать TARGET_IPHONE_SIMULATOR.

Ответ 10

Чтобы включить все типы "симуляторов"

NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
    // we are running in a simulator
}

Ответ 11

Мой ответ основан на ответе @Daniel Magnusson и комментариях @Nuthatch и @n.Drake. и я пишу это, чтобы сэкономить время для быстрых пользователей, работающих на iOS9 и далее.

Это то, что сработало для меня:

if UIDevice.currentDevice().name.hasSuffix("Simulator"){
    //Code executing on Simulator
} else{
    //Code executing on Device
}

Ответ 12

Кто-нибудь посчитал ответ здесь?

Я полагаю, что эквивалент 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);
    }
}

Ответ 13

На мой взгляд, ответ (представленный выше и повторенный ниже):

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}

- лучший ответ, потому что он явно выполнен в RUNTIME по сравнению с ДИНАМИКОЙ COMPILE.

Ответ 14

Это сработало для меня лучше всего

NSString *name = [[UIDevice currentDevice] name];


if ([name isEqualToString:@"iPhone Simulator"]) {

}