it-swarm.com.ru

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

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

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

254
Jeffrey Meyer

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

Что #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

в зависимости от того, который подходит для вашего варианта использования.

348
Airsource Ltd

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

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

#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
106
Pete

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

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

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

#if TARGET_IPHONE_SIMULATOR

и не

#ifdef TARGET_IPHONE_SIMULATOR

так как его всегда определяется: 0 или 1

54
Taranfx

В случае 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
}
30
Nischal Hada

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

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

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

ОБНОВЛЕНИЕ
Xcode 10 и iOS 12 SDK также поддерживают это.

23
Stefan Vasiljevic

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

Эта статья блога показывает Как обнаружить симулятор 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
onmyway133
6
CedricSoubrie

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

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

6
Stunner

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

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

4
Martin

Работает для Swift 4 и Xcode 9.4.1

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

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif
3
Haroldo Gondim

Для 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()
}
2
LukeSideWalker

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

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

+ (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);
    }
}
2
Vijay Sharma

Включить все виды «симуляторов»

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

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

#if targetEnvironment(simulator)
  //simulator code
#else 
  #warning("Not compiling for simulator")
#endif
1
iHS

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

public static var isSimulator: Bool {
    #if (Arch(i386) || Arch(x86_64)) && os(iOS)
        return true
    #else
        return false
    #endif
}
0
Pratyush Pratik

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

public struct Platform {

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

}
0
Aklesh Rathaur

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

#if targetEnvironment(simulator)
let DEVICE_IS_SIMULATOR = true
#else
let DEVICE_IS_SIMULATOR = false
#endif
0
David Corbin

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

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

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

Решение Swift 4

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

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

0
kamwysoc