How to detect that a provisioning profile is for development or distribution, programmatically

Alfie Hanssen picture Alfie Hanssen · Apr 26, 2013 · Viewed 12.4k times · Source

I would like to detect if a given provisioning profile is a development profile or a distribution (adhoc or app store) profile. I need to do this purely programmatically.

I already understand how to detect adhoc vs appstore. And am specifically interested in dev vs. distribution.

I've examined the plists internal to each type of profile and cannot find a discernable difference (via security cms -D -i #{@profilePath}). I've also looked into the openssl api and am using this for some certificate manipulation.

This is for a custom xcode automated build system. As part of pre-build validation I need to ensure that the specified profile is not for development.

Is this even possible? If so, how can I programmatically differentiate between the two?

Thanks in advance for any ideas!

Answer

steipete picture steipete · Nov 27, 2013

I've build a more concise and efficient version of Toom's code:

I'll maintain code snippets like this in a gist, you might find a more up to date version here: https://gist.github.com/steipete/7668246

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
}