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

ios objective-c swift xcode ios-simulator

109774 просмотра

22 ответа

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

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

Автор: Jeffrey Meyer Источник Размещён: 17.05.2019 03:31

Ответы (22)


345 плюса

Решение

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

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

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

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

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

#include "TargetConditionals.h"

но это больше не нужно для текущей (Xcode 6 / iOS8) инструментальной цепочки.

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

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

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

Автор: Airsource Ltd Размещён: 19.01.2009 05:17

106 плюса

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

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

#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
Автор: Pete Размещён: 19.01.2009 05:10

61 плюса

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

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}
Автор: Daniel Magnusson Размещён: 18.08.2010 10:35

54 плюса

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

#if TARGET_IPHONE_SIMULATOR

и не

#ifdef TARGET_IPHONE_SIMULATOR

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

Автор: Taranfx Размещён: 07.03.2011 07:05

28 плюса

В случае 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
}
Автор: Nischal Hada Размещён: 25.02.2016 04:48

18 плюса

ЛУЧШЕ ПУТЬ СЕЙЧАС!

Начиная с Xcode 9.3 beta 4, вы можете использовать #if targetEnvironment(simulator)для проверки.

#if targetEnvironment(simulator)
//Your simulator code
#endif


Это также поддерживает UPDATE Xcode 10 и iOS 12 SDK.

Автор: Stefan Vasiljevic Размещён: 12.03.2018 01:50

8 плюса

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

Эта статья в блоге показывает, как определить симулятор 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
Автор: onmyway133 Размещён: 17.06.2014 02:57

6 плюса

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

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

Автор: Stunner Размещён: 21.05.2013 07:10

6 плюса

Быстро:

#if (arch(i386) || arch(x86_64))
...            
#endif

От Detect, если приложение создается для устройства или симулятора в Swift

Автор: CedricSoubrie Размещён: 16.06.2016 02:10

4 плюса

У меня была такая же проблема, как TARGET_IPHONE_SIMULATORи TARGET_OS_IPHONEвсегда , так и всегда заданы и установлены на 1. Решение Пита работает, конечно, но если вам когда-нибудь удастся опираться на что-то другое, кроме интеллекта (маловероятно, но кто знает), вот что безопасно, как поскольку аппаратные средства 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_*константы были определены правильно.

Автор: Martin Размещён: 16.06.2009 05:48

2 плюса

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

Я полагаю, что эквивалент объектно-с

+ (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);
    }
}
Автор: Vijay Sharma Размещён: 26.07.2017 01:59

2 плюса

Работает Swift 4иXcode 9.4.1

Используйте этот код:

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif
Автор: Haroldo Gondim Размещён: 18.07.2018 07:06

1 плюс

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

NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
    // we are running in a simulator
}
Автор: jeffr Размещён: 12.06.2015 06:51

1 плюс

С Swift 4.2 (Xcode 10) мы можем сделать это

#if targetEnvironment(simulator)
  //simulator code
#else 
  #warning("Not compiling for simulator")
#endif
Автор: iHS Размещён: 11.06.2018 08:33

0 плюса

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

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

if UIDevice.currentDevice().name.hasSuffix("Simulator"){
    //Code executing on Simulator
} else{
    //Code executing on Device
}
Автор: euthimis87 Размещён: 23.12.2015 12:30

0 плюса

/// Возвращает true, если его симулятор, а не устройство

public static var isSimulator: Bool {
    #if (arch(i386) || arch(x86_64)) && os(iOS)
        return true
    #else
        return false
    #endif
}
Автор: Pratyush Pratik Размещён: 28.02.2018 01:39

0 плюса

Решение SWIFT 4

static let isSimulator: Bool = {
    return TARGET_OS_SIMULATOR == 1
}()

TARGET_OS_SIMULATORнаходится в Darwin.TargetConditionals.swiftфайле.

Автор: kamwysoc Размещён: 11.04.2018 07:09

0 плюса

Apple добавила поддержку для проверки того, что приложение предназначено для симулятора со следующим:

#if targetEnvironment(simulator)
let DEVICE_IS_SIMULATOR = true
#else
let DEVICE_IS_SIMULATOR = false
#endif
Автор: David Corbin Размещён: 11.07.2018 10:43

0 плюса

если ничего не получилось, попробуйте это

public struct Platform {

    public static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0 // Use this line in Xcode 7 or newer
    }

}
Автор: Aklesh Rathaur Размещён: 17.09.2018 01:33

0 плюса

Для Swift 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()
}
Автор: LukeSideWalker Размещён: 25.11.2018 01:29

-3 плюса

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

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

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

Автор: user1686700 Размещён: 09.09.2013 02:45

-3 плюса

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

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


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

}
Автор: Mani Размещён: 11.05.2016 06:40
Вопросы из категории :
32x32