আমার অ্যাপ্লিকেশনটি আইফোন সিমুলেটারে চলছে কিনা তা আমি প্রোগ্রামগতভাবে কীভাবে নির্ধারণ করতে পারি?


270

প্রশ্নটি হিসাবে বলা হয়েছে, আমি মূলত আমার কোডটি সিমুলেটারে চলছে কিনা তা জানতে চাই, তবে নির্দিষ্ট আইফোন সংস্করণটিও চলছে যা চালানো হচ্ছে বা সিমুলেট করা হচ্ছে তা জানতে আগ্রহী হব।

সম্পাদনা: আমি প্রশ্নের নামটিতে 'প্রোগ্রাম্যাটিক' শব্দটি যুক্ত করেছি। আমার প্রশ্নের মূল বিষয়টি হ'ল কোন সংস্করণ / সিমুলেটর চলছে তার উপর নির্ভর করে কোডটিকে গতিশীলভাবে অন্তর্ভুক্ত / বাদ দিতে সক্ষম হবেন, তাই আমি সত্যিই একটি প্রাক-প্রসেসরের নির্দেশকের মতো এমন কিছু সন্ধান করব যা আমাকে এই তথ্য সরবরাহ করতে পারে।


আমি নিশ্চিত নই যে প্রাক-প্রসেসরের নির্দেশিকা গতিশীল (যদিও এটি আপনি যা খুঁজছিলেন তা হতে পারে)। দিকনির্দেশনার অর্থ হ'ল আপনি আসলে এটি জানতেন, কখন আপনি এটি তৈরি করেছিলেন, কোথায় এটি চলমান চলবে।
ওয়াইজ ওल्डডাক

উত্তর:


356

ইতিমধ্যে জিজ্ঞাসা করা হয়েছে, তবে একটি খুব আলাদা শিরোনাম সহ।

আইফোনের জন্য সংকলন করার সময় এক্সকোড দ্বারা # ডিফাইনগুলি কী সেট আপ করে

আমি সেখান থেকে আমার উত্তরটি পুনরাবৃত্তি করব:

এটি "শর্তসাপেক্ষে সোর্স কোডটি সংকলন" এর অধীনে SDK ডক্সে রয়েছে

প্রাসঙ্গিক সংজ্ঞাটি TARGET_OS_SIMULATOR, যা আইওএস ফ্রেমওয়ার্কের মধ্যে /usr/incolve/TargetConditionals.h এ সংজ্ঞায়িত হয়। সরঞ্জামচয়ের আগের সংস্করণগুলিতে আপনাকে লিখতে হয়েছিল:

#include "TargetConditionals.h"

তবে বর্তমানের (এক্সকোড 6 / আইওএস 8) সরঞ্জামচেইনে এটি আর দরকার নেই।

সুতরাং, উদাহরণস্বরূপ, আপনি যদি ডিভাইসে চালাচ্ছেন কিনা তা পরীক্ষা করতে চান, আপনার করা উচিত

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

আপনার ব্যবহারের ক্ষেত্রে উপযুক্ত কিনা তার উপর নির্ভর করে।


1
ধন্যবাদ। আমি আপনার সাথে একমত এটি আপনার মূল প্রশ্নের আরও নির্দিষ্ট সংস্করণ। আপনার যদি আমার আসল অনুসন্ধানে উঠে আসে তবে আমার জিজ্ঞাসা করার দরকারও পড়ত না।
জেফ্রি মায়ার

5
এই সংজ্ঞা সাথে সাবধান হন। আপনি যখন মেনু আইটেম 'প্রজেক্ট> অ্যাক্টিভ এসডিকে> সিমুলেটর সেট করুন ...' সহ কোডটি সংকলন করেন, তখন TARGET_IPHONE_SIMULATOR হিসাবে TARGET_OS_IPHONE ভেরিয়েবল উভয়ই সংজ্ঞায়িত হয়! সুতরাং পৃথক যুক্তির একমাত্র সঠিক উপায় নীচে পিট দ্বারা চিহ্নিত করা হয়েছে (ধন্যবাদ বন্ধু)
ভাদিম

5
#If এবং #ifdef পার্থক্য দেখুন। আমার জন্য এটি ছিল ভুল আচরণের কারণ।
আন্তন

7
সম্ভবত এটি লেখা হওয়ার পর থেকে টার্গেটকন্ডিশনালগুলি অন্তর্ভুক্ত করার প্রয়োজনীয়তাটি প্রতিহত করা হয়েছে তবে কেবলমাত্র লক্ষ রাখতে চেয়েছিলেন যে #if TARGET_IPHONE_SIMULATOR এখন টার্গেটকন্ডিশনালগুলি অন্তর্ভুক্ত না করে কাজ করে।
dmur

1
@ ডিমিট্রিস এটি ভাল অনুশীলন। আপনি কীভাবে TARGET_OS_SIMULATOR সংজ্ঞায়িত করা হয়েছে তা জানেন না! সুতরাং (TARGET_OS_SIMULATOR) এর সাথে অভিন্ন হতে পারে না! TARGET_OS_SIMULATOR
লিমিটেড

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

7
আইওএস 8 এবং এক্সকোড 6.1.1 হিসাবে TARGET_OS_IPHONE সিমুলেটারে সত্য।
মলহাল

3
এটি নতুন
এক্সকোড

1
আপনি 2016 এ না থাকলে এবং একটি 64 বিট সিমুলেটর চালাবেন না। বা 2019 এ এবং আপনার কোডটি ইন্টেল প্রসেসর সহ একটি আইফোনে চালান run
gnasher729

61

প্রাক-প্রসেসরের নির্দেশিকা নয়, আমি যখন এই প্রশ্নটিতে এসেছি তখন এটিই আমি খুঁজছিলাম;

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

9
[model compare:iPhoneSimulator] == NSOrderedSameএভাবে লিখতে হবে[model isEqualToString:iPhoneSimulator]
user102008

18
বা [model hasSuffix:@"Simulator"]আপনি যদি কেবলমাত্র সাধারণভাবে "সিমুলেটর" সম্পর্কে চিন্তা করেন তবে বিশেষত আইফোন বা আইপ্যাড নয় । এই উত্তরটি আইপ্যাড সিমুলেটারের জন্য কাজ করবে না :)
নুথ্যাচ

উত্সাহিত হয়েছে কারণ নুথ্যাচের মন্তব্য এটি টোটোর সেরা উত্তর করেছে।
লে মোট জুসেড

12
IOS9, ডিভাইসটি পরীক্ষা nameপরিবর্তেmodel
n.Drake

1
যদি কোনও ব্যবহারকারী Simulatorতার ডিভাইসের নামে শব্দ যুক্ত করে তবে কোডটি কাজ করবে না
এমবেলস্কি

55

এটি করার সর্বোত্তম উপায় হ'ল:

#if TARGET_IPHONE_SIMULATOR

এবং না

#ifdef TARGET_IPHONE_SIMULATOR

যেহেতু এটি সর্বদা সংজ্ঞায়িত: 0 বা 1


39

এখনই একটি আরও ভাল উপায়!

এক্সকোড 9.3 বিটা 4 হিসাবে #if targetEnvironment(simulator)আপনি চেক করতে ব্যবহার করতে পারেন ।

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

আপডেট করুন
এক্সকোড 10 এবং আইওএস 12 এসডিকে এটিও সমর্থন করে।


1
এটি শুধুমাত্র আমার জন্য কাজ করে, বাকি সমাধানগুলি কাজ করে না।
শ্রুতিন রাঠোড

দ্রষ্টব্য এটি কেবল দ্রুত।
ম্যাট এস

35

সুইফটের ক্ষেত্রে আমরা নিম্নলিখিতগুলি প্রয়োগ করতে পারি

আমরা স্ট্রাক্ট তৈরি করতে পারি যা আপনাকে কাঠামোগত ডেটা তৈরি করতে দেয়

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
    }
}

তারপরে আমরা যদি সুইচটিতে ডিভাইস বা সিমুলেটারের জন্য অ্যাপ তৈরি করা হচ্ছে কিনা তা যদি আমরা সনাক্ত করতে চাইতাম।

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

আমার মতে সবচেয়ে পরিষ্কার বাস্তবায়ন, এবং এটি x86_64 এবং i386 আর্কিটেকচারের জন্য অ্যাকাউন্ট করে। কোর ডেটাতে একটি অদ্ভুত ডিভাইস বনাম সিমুলেটর বাগটি কাটিয়ে উঠতে আমাকে সহায়তা করেছে। তুমি সেই লোক!
আয়রন জন বনি

5
খেলার মাঠে, আপনি একটি সতর্কতা পাবেন, "'রিটার্নের পরে কোড কখনও কার্যকর করা হবে না"। সুতরাং আমার মনে হয় #if #else #endifআরও ভাল হবে।
ডনসং


9

এই সমস্ত উত্তরগুলি ভাল, তবে এটি আমার মতো নবাগতকে বিভ্রান্ত করে কারণ এটি সংকলন চেক এবং রানটাইম চেকটি পরিষ্কার করে না। প্রিপ্রেসেসর সময় সংকলনের আগে হয় তবে আমাদের এটি আরও পরিষ্কার করা উচিত

এই ব্লগ নিবন্ধে আইফোন সিমুলেটরটি কীভাবে সনাক্ত করা যায় তা দেখানো হয়েছে? পরিষ্কারভাবে

রানটাইম

প্রথমত, শীঘ্রই আলোচনা করা যাক। ইউআইডিভাইস আপনাকে ডিভাইস সম্পর্কে ইতিমধ্যে তথ্য সরবরাহ করে

[[UIDevice currentDevice] model]

অ্যাপটি কোথায় চলছে সে অনুযায়ী আপনাকে "আইফোন সিমুলেটর" বা "আইফোন" ফিরিয়ে দেবে।

সংকলন সময়

যাইহোক আপনি যা চান তা সংকলিত সময় সংজ্ঞায়িত ব্যবহার করা। কেন? কারণ আপনি সিমুলেটারের ভিতরে বা ডিভাইসে চালিত হতে আপনার অ্যাপ্লিকেশনটি কঠোরভাবে সংকলন করেছেন। অ্যাপল একটি সংজ্ঞায়িত করে তোলে TARGET_IPHONE_SIMULATOR। সুতরাং কোডটি দেখুন:

#if TARGET_IPHONE_SIMULATOR

NSLog(@"Running in Simulator - no app store or giro");

#endif

1
অন্যান্য উত্তরে এটি কীভাবে উন্নতি করবে?
ব্যবহারকারী 151019

@ মার্ক এটি কিছুটা স্পষ্ট করে
onwayway133

5
বর্তমানে, এক্সকোড in-এ, আইওএস 9 সিমুলেটার পরিবর্তে [[UIDevice currentDevice] model]ফিরে আসছে । সুতরাং, আমি মনে করি এটি সেরা পদ্ধতির নয়। iPhoneiPhone Simulator
eMdOS

6

আগের উত্তরগুলি কিছুটা তারিখযুক্ত। আমি দেখতে পেয়েছি যে আপনাকে যা করতে হবে তা হ'ল TARGET_IPHONE_SIMULATORম্যাক্রোকে জিজ্ঞাসা করা ( অন্য কোনও শিরোনাম ফাইল অন্তর্ভুক্ত করার দরকার নেই) [আপনি iOS এর জন্য কোডিং করছেন বলে ধরে নিচ্ছেন])।

আমি চেষ্টা করেছিলাম TARGET_OS_IPHONEকিন্তু প্রকৃত ডিভাইস এবং সিমুলেটারে চলার সময় এটি একই মান (1) ফিরে আসে, এজন্য আমি TARGET_IPHONE_SIMULATORপরিবর্তে ব্যবহারের পরামর্শ দিই ।


TARGET_OS_IPHONE কোডের জন্য যা আইওএস বা ম্যাকস এক্স এ চালিত হতে পারে vious স্পষ্টতই আপনি চাইবেন যে কোডটি একটি সিমুলেটারে "আইফোন" এর আচরণ করবে।
gnasher729

6

ম্যাক অ্যাপ্লিকেশনগুলির মধ্যে পার্থক্য জানাতে: #if (খিলান (i386) || খিলান (x86_64)) ও&! ওএস (ওএসএক্স) // আমরা ম্যাকটিতে চলমান একটি সিমুলেটর করছি এবং ম্যাক অ্যাপ্লিকেশন নয়। (ম্যাক লক্ষ্যবস্তুগুলিতে অন্তর্ভুক্ত ক্রস প্ল্যাটফর্ম কোডের জন্য)
ববজট

4

আমার একই সমস্যা ছিল, উভয়ই TARGET_IPHONE_SIMULATORএবং TARGET_OS_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

কেউ কি এখানে প্রদত্ত উত্তর বিবেচনা করেছে ?

আমি মনে করি উদ্দেশ্য-সি সমতুল্য হবে

+ (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

সুইফট 4.2 / এক্সকোড 10 এর জন্য

আমি ইউআইডিভাইসিতে একটি এক্সটেনশন তৈরি করেছি, তাই সিমুলেটরটি চলছে কিনা তা আমি সহজেই জিজ্ঞাসা করতে পারি।

// 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()
}

1

সব ধরণের "সিমুলেটর" অন্তর্ভুক্ত করা

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

4
এক্সকোড with এর সাথে এর কোনও যোগসূত্র নেই you আপনি যদি আইওএস ৮ (এক্সকোড from থেকে) এর সাথে আইওএস সিমুলেটার চালনা করেন তবে এটি কাজ করবে। এটি iOS9 এর জন্য কাজ করবে না যেখানে [[ইউআইডিভাইস বর্তমান ডিভাইস] মডেল] আইওএস সিমুলেটর থেকে অ্যাপটি চালু করা হলে কেবল "আইফোন" ফেরত দেয়
টেসলা

কেন না -[NSString containsString]?
গোব

1

সুইফট ৪.২ (এক্সকোড 10) দিয়ে আমরা এটি করতে পারি

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

1
ঠিক আর একটি অনুলিপি পেস্ট করুন
জে ডো

0

আমার উত্তর @ ড্যানিয়েল ম্যাগনুসনের উত্তর এবং @ নূত্যাচ এবং @ এন.ড্রাকের মন্তব্যের ভিত্তিতে। এবং আমি এটি iOS9 এবং এর পরে কাজ করা সুইফ্ট ব্যবহারকারীদের জন্য কিছুটা সময় বাঁচানোর জন্য লিখেছি।

এটিই আমার পক্ষে কাজ করেছে:

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

1
কোনও ব্যবহারকারী Simulatorতার ডিভাইসের নামে শব্দ যুক্ত করলে কোডটি কাজ করবে না
এমবেলস্কি

দুর্ভাগ্যক্রমে এক্সকোড ৮- UIDevice.current.nameএর সাথে মেশিনটির নাম সিমুলেটর চলছে (সাধারণত "সাইমনস ম্যাকবুক প্রো" এর মতো কিছু এখন চলছে) তাই পরীক্ষাটি বিশ্বাসযোগ্য নয়। আমি এখনও এটি ঠিক করার জন্য একটি পরিষ্কার উপায় সন্ধান করছি।
মাইকেল

0

/// যদি এটির সিমুলেটর থাকে এবং কোনও ডিভাইস না হয় তবে সত্যটি ফেরত দেয়

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

0

অ্যাপলটি নীচের সাথে সিমুলেটারের জন্য লক্ষ্যযুক্ত অ্যাপটি পরীক্ষা করার জন্য সমর্থন যোগ করেছে:

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

0

যদি কিছুই কাজ না করে থাকে তবে এটি চেষ্টা করে দেখুন

public struct Platform {

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

}

-4

আমার মতে, উত্তর (উপরে উপস্থাপিত এবং নীচে পুনরাবৃত্তি):

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

এটি সর্বোত্তম উত্তর কারণ এটি স্পষ্টতই কার্যকর করা হয় রন্টটাইমে বনাম একটি সম্পূর্ণ পরিচালক হিসাবে RE


11
আমি একমত নই এই কোডটি আপনার পণ্যটিতে শেষ হয়, যেখানে একটি সংকলক নির্দেশিকা - ডিভাইসে অপ্রয়োজনীয় - নিয়মিতভাবে বাইরে রাখে।
নয়টি পাথর

1
সংকলক নির্দেশিকা কাজ করে কারণ ডিভাইস এবং সিমুলেটরগুলি সম্পূর্ণ পৃথক সংকলন লক্ষ্য - যেমন আপনি উভয় ক্ষেত্রে একই বাইনারি ব্যবহার করবেন না। এটা তোলে হয়েছে বিভিন্ন হার্ডওয়্যারে কম্পাইল করা, তাই এটি যে ক্ষেত্রে জ্ঞান করে তোলে।
ব্র্যাড পার্কগুলি

RUNTIME এ মৃত্যুদন্ড কার্যকর করা এটিকে সবচেয়ে খারাপ উত্তর দেয়।
gnasher729

-4

এটি আমার পক্ষে সবচেয়ে ভাল কাজ করেছে

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


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

}

2
এক্সকোড 7.3 এ, আইফোন 6 প্লাস সিমুলেটর ফিরে আসে "iPhone"
এরিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.