web-dev-qa-db-ja.com

アプリがiPhoneシミュレーターで実行されているかどうかをプログラムで判断するにはどうすればよいですか?

質問が述べているように、私は主に私のコードがシミュレータで実行されているかどうかを知りたいだけでなく、実行中またはシミュレートされている特定のiPhoneバージョンを知ることに興味があります。

編集:Wordを「プログラムで」質問名に追加しました。私の質問のポイントは、実行しているバージョン/シミュレータに応じてコードを動的に含める/除外できるようにすることです。したがって、この情報を提供できるプリプロセッサディレクティブのようなものを本当に探しています。

260
Jeffrey Meyer

すでに尋ねましたが、非常に異なるタイトルで。

iPhone用にコンパイルするときにXcodeによって設定される#defines

そこから私の答えを繰り返します。

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

どちらがユースケースに適しているかによって異なります。

349
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

これを行う最良の方法は次のとおりです。

#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 thenのデバイスまたはシミュレータ用にビルドされているかどうかを検出したい場合。

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

ISより良い方法があります!

Xcode 9.3 beta 4では、#if targetEnvironment(simulator)を使用して確認できます。

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

UPDATE
Xcode 10およびiOS 12 SDKもこれをサポートしています。

30

これらの答えはすべて良いですが、コンパイルチェックとランタイムチェックを明確にしないため、私のような初心者を混乱させます。プリプロセッサはコンパイル前にありますが、より明確にする必要があります

このブログ記事では 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
8
onmyway133
6
CedricSoubrie

以前の回答は少し古くなっています。 TARGET_IPHONE_SIMULATORマクロを照会するだけでよいことがわかりました(他のヘッダーファイルを含める必要はありません [iOS用にコーディングしている場合])。

TARGET_OS_IPHONEを試しましたが、実際のデバイスとシミュレーターで実行すると同じ値(1)を返しました。そのため、代わりにTARGET_IPHONE_SIMULATORを使用することをお勧めします。

6
Stunner

Swift 4およびXcode 9.4.1に対応

このコードを使用してください:

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

私は同じ問題を抱えていました。TARGET_IPHONE_SIMULATORTARGET_OS_IPHONEの両方が常に定義され、1に設定されています。もちろん、ピートのソリューションは動作しますが、 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

For Swift 4.2/xCode 1

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()
}
3
LukeSideWalker

誰もが提供された答えを考えましたか ここ

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);
    }
}
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のコメントに基づいています。 iOS9以降で作業しているSwiftユーザーの時間を節約するために書きました。

これは私のために働いたものです:

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_SIMULATORDarwin.TargetConditionals.Swiftファイルにあります。

0
kamwysoc