-
-
Save steipete/7668246 to your computer and use it in GitHub Desktop.
static BOOL PSPDFIsDevelopmentBuild(void) { | |
#if TARGET_IPHONE_SIMULATOR | |
return YES; | |
#else | |
static BOOL isDevelopment = NO; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
// There is no provisioning profile in AppStore Apps. | |
NSData *data = [NSData dataWithContentsOfFile:[NSBundle.mainBundle pathForResource:@"embedded" ofType:@"mobileprovision"]]; | |
if (data) { | |
const char *bytes = [data bytes]; | |
NSMutableString *profile = [[NSMutableString alloc] initWithCapacity:data.length]; | |
for (NSUInteger i = 0; i < data.length; i++) { | |
[profile appendFormat:@"%c", bytes[i]]; | |
} | |
// Look for debug value, if detected we're a development build. | |
NSString *cleared = [[profile componentsSeparatedByCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet] componentsJoinedByString:@""]; | |
isDevelopment = [cleared rangeOfString:@"<key>get-task-allow</key><true/>"].length > 0; | |
} | |
}); | |
return isDevelopment; | |
#endif | |
} |
This is all based on public API and App Store safe. Used in http://PSPDFKit.com
Actually "embedded.mobileprovision" is not a public API. it is an implementation detail that might change in future
We set a Preprocessor Macro, but this looks more hip :-0
Why do you use NSData and a manual to-string-conversion instead of
NSString *profile = [NSString stringWithContentsOfFile:...
encoding:NSISOLatin1StringEncoding
error:&err];
(NSISOLatin1StringEncoding as a "accept any byte value, 0..127 is ASCII")
@nskboy It defaults to NO, so if this changes nothing will go wrong, we just falsely detect an AppStore/AdHoc build. This is only used to be developer-friendly and provide more logs/alerts when using certain features during development.
@dhoepfl I tried that. This will pick up \0 's from the binary part and prematurely end the string.
I mean existence of a file embedded.mobileprovision rather than get-task-allow itself
@steipete Good thinking
I tried this snippet in a production app a while back, this snippet caused a crash on ~0.1% of users.
What was the crash?
To avoid crashes I suggest to check only
+ (BOOL)isDevelopmentBuild {
#if TARGET_IPHONE_SIMULATOR
return YES;
#else
static BOOL isDevelopment = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// There is no provisioning profile in AppStore Apps.
NSData *data = [NSData dataWithContentsOfFile:[NSBundle.mainBundle pathForResource:@"embedded" ofType:@"mobileprovision"]];
if (data) {
isDevelopment=YES;
}
});
return isDevelopment;
#endif
}
Based on http://stackoverflow.com/questions/3426467/how-to-determine-at-run-time-if-app-is-for-development-app-store-or-ad-hoc-dist