Detecting Mountain Lion from within the iOS Simulator [duplicate] - objective-c

I'd like to know whether my app is being run on device or simulator at run time. Is there a way to detect this?
Reason being to test bluetooth api with simulator:
http://volcore.limbicsoft.com/2009/09/iphone-os-31-gamekit-pt-1-woooohooo.html

#if TARGET_OS_SIMULATOR
//Simulator
#else
// Device
#endif
Pls refer this previous SO question also What #defines are set up by Xcode when compiling for iPhone

I created a macro in which you can specify which actions you want to perform inside parentheses and these actions will only be performed if the device is being simulated.
#define SIM(x) if ([[[UIDevice currentDevice].model lowercaseString] rangeOfString:#"simulator"].location != NSNotFound){x;}
This is used like this:
SIM(NSLog(#"This will only be logged if the device is simulated"));

TARGET_IPHONE_SIMULATOR is defined on the device (but defined to false). and defined as below
#if TARGET_IPHONE_SIMULATOR
NSString * const DeviceMode = #"Simulator";
#else
NSString * const DeviceMode = #"Device";
#endif
Just use DeviceMode to know between device and simulator

Check if simulator
#if TARGET_IPHONE_SIMULATOR
// Simulator
#endif
Check if device
#if !(TARGET_IPHONE_SIMULATOR)
// Device
#endif
Check for both
#if TARGET_IPHONE_SIMULATOR
// Simulator
#else
// Device
#endif
Please note that you should not ifdef on
TARGET_IPHONE_SIMULATOR because it will always be defined to either 1 or 0.

From XCode 9.3+ , Swift
#if targetEnvironment(simulator)
//Simulator
#else
//Real device
#endif
Helps you to code against device type specific.

You can use the TARGET_IPHONE_SIMULATOR preprocessor macro to distinguish between device and simulator targets.

Use this below code:
#if targetEnvironment(simulator)
// iOS Simulator
#else
// Device
#endif
Works for Swift 4 and Xcode 9.4.1

if anyone is looking for Unity solution i did this, the only way i found how.
using System.Globalization;
public static bool IsArm() {
return CultureInfo.InvariantCulture.CompareInfo.IndexOf(SystemInfo.processorType, "ARM", CompareOptions.IgnoreCase) >= 0;
}

Related

Objective-C #ifdef DEBUG is TRUE when the app is distributed?

In my project, I am sharing events to Firebase Analytics and other analytics platform
When an event occurs I am checking whether the scheme is in debug mode:
#ifdef DEBUG
#define sharedAnalytics NO
#else
#define sharedAnalytics YES
#endif
When debugging in Xcode evetything seems to work as expected:
-When changing the build configuration in scheme to Release, sharedAnalytics is true, and the event is fired,
when changing the build configuration to Debug - sharedAnalytics is false.
But the app in Appstore stopped firing those events somewhere in Jan 2020, both in Firebase Analytics and in AppsFlyer.
In the Android app everything works.
From what I know, when the app is compiled for Appstore (or Testflight) it automatically switches to Release build configuration, but it looks like it's not?
My questions are:
-Do I need to make sure I am in Release mode before uploading an app to Appstore?
-What changed in the beginning of 2020?
Thanks!
EDIT:
This is where I check sharedAnalytics
- (void)logFirebaseEvent:(NSString*)eventName params:(NSDictionary*)params{
if (sharedAnalytics) {
[FIRAnalytics logEventWithName:eventName parameters:params];
}
else {
NSLog(#"%#", sharedAnalytics == nil ? #"sharedAnalytics is nil" : #"sharedAnalytics == NO");
}
}
When in DEBUG prints "sharedAnalytics is nil"
When in RELEASE prints logs the event.
Debug, Release, Appstore is just build configurations.
Xcode by default just create Debug and Release configurations in new projects.
There is two possible ways to define macros:
in code by #define ...
in build settings in GCC_PREPROCESSOR_DEFINITIONS parameter
May be you have copied Appstore from Debug or may be you have #define DEBUG some where
May be you have DEBUG=0
Proper way to check for DEBUG is
#if defined(DEBUG) && DEBUG
#define sharedAnalytics NO
#else
#define sharedAnalytics YES
#endif
May be you also checking sharedAnalytics wrong.
In both cases #ifdef sharedAnalytics gives YES
Ok Vadim, not that this will solve the problem, but when you check this is a bit better
- (void)logFirebaseEvent:(NSString*)eventName params:(NSDictionary*)params{
if (sharedAnalytics) {
[FIRAnalytics logEventWithName:eventName parameters:params];
}
else {
NSLog(#"sharedAnalytics == NO");
}
}
Technically that
sharedAnalytics == nil
evaluates to
sharedAnalytics == NO
which is true and so it reports it as nil.
The problem is this still leaves an NSLog in your production / release code, so maybe you need to do that differently. Again, this is moot relative to your problem, just doing the tests a bit better. Anyway, herewith an idea.
Do the define as follows.
#ifdef DEBUG
#undef sharedAnalytics
#else
#define sharedAnalytics
#endif
To be extremely pure, you should use caps and reduce that to a single branch but lets not go there right now ...
Then when you test do as follows
- (void)logFirebaseEvent:(NSString*)eventName params:(NSDictionary*)params{
#ifdef sharedAnalytics
[FIRAnalytics logEventWithName:eventName parameters:params];
#else
NSLog(#"sharedAnalytics == NO");
#endif
}
While this looks a lot like your original code and does not solve the direct problem you have, it is better since when you compile for DEBUG you get the NSLog bit and when you compile for RELEASE that code is stripped completely from your release version.
What do you get for all this? You should strip all NSLog's from release code as it has performance implications.

conditional compilation warning for constant

QUESTION
I would like to trigger a warning only if my TESTING is YES. Is this possible? What I have now doesn't work. What should I do?
BOOL const TESTING = NO;
#if TESTING == YES
#warning don't forget to turn testing to NO before upload
#endif
ANSWER
Based on the answer below, here is what worked for me:
#define _TESTING // COMMENT THIS OUT TO DISABLE TESTING MODE
#ifdef _TESTING
BOOL const TESTING = YES;
#warning don't forget to turn testing to NO for production
#else
BOOL const TESTING = NO;
#endif
Try replacing what you have with
#ifdef TESTING
#warning //... warning here
BOOL const testingBool = YES;
#else
BOOL const testingBool = NO;
#endif
Then, you need to add TESTING as a "Preprocessor Macro" in your Target's Build Settings (see this question for more details on how to do that).

XCode - Check with constant if my program is running in simulator o device [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I programmatically determine if my app is running in the iphone simulator?
How I can check in XCode 4 with constant if my program is running in simulator o device?
Something like this:
#ifdef RUNING_ON_DEVICE
#else
#endif
There are a couple of options
Preprocessor macro:
#if TARGET_IPHONE_SIMULATOR
//is sim
#elif TARGET_OS_IPHONE
//is real device
#else
//unknown target
#endif
Or, if you'd rather do it in some arbitrary method:
if ([[[UIDevice currentDevice] model] isEqualToString:#"iPhone Simulator"]) {
//device is simulator
}

How can I differentiate the iPad and iPhone programmatically? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Best way to programmatically detect iPad/iPhone hardware
How can I differentiate the iPad and iPhone programmatically?
It seems for me that the question is a duplicate, but I'll try to brief all I know about device type and iOS version detection.
There are several methods based on which information you want to receive, whether it just device type (iPhone, iPod or iPad) or iOS version.
Here is code for detecting device type (returns i386 in case of Simulator):
#import <sys/utsname.h>
+ (NSString *)getDeviceType {
struct utsname systemInfo;
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8Encoding];
}
And here is iOS version detector:
+ (float)getOSVersion {
return [[[UIDevice currentDevice] systemVersion] floatValue];
}
And OS detector for compiler:
#ifdef __IPHONE_4_0
//this part of code will be running on devices with os iOS4+
#else
//this part of code will be running on devices with os _UNDER_ iOS4+
#endif
Also, nobody proibits us to use
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED > 40000
//this part of code will be running on devices with os iOS4+
#endif

how to know if current architecture is i386 or x86_64 in macs? (Xcode)

I am handling a camera that needs different parameters in different architecture, Is there a flag that I can check to see if I am in 32bits or 64bits in my mac?
I was trying this but does not seem to work, I always get 32Bits!! :
#if defined(PER_ARCH_CFLAGS_x86_64)
NSLog(#"64bit!!");
#else
NSLog(#"32Bits!!");
#endif
#ifdef __LP64__
// 64-bit code
#else
// 32-bit code
#endif
Source: http://developer.apple.com/mac/library/documentation/Darwin/Conceptual/64bitPorting/MakingCode64-BitClean/MakingCode64-BitClean.html#//apple_ref/doc/uid/TP40001064-CH226-SW2
#ifdef __x86_64__
//64-bit intel
#endif
#ifdef __i386__
//32-bit intel
#endif
//carry on for ppc, ppc64, ARM
or...
#ifdef __LP64__
//64-bit Intel or PPC
#else
//32-bit Intel, PPC or ARM
#endif