1// Copyright 2015-present 650 Industries. All rights reserved. 2 3#import <EXApplication/EXProvisioningProfile.h> 4 5@implementation EXProvisioningProfile { 6 NSDictionary *_plist; 7} 8 9+ (nonnull instancetype)mainProvisioningProfile 10{ 11 static EXProvisioningProfile *profile; 12 static dispatch_once_t onceToken; 13 dispatch_once(&onceToken, ^{ 14 NSDictionary *plist = [self _readProvisioningProfilePlist]; 15 profile = [[self alloc] initWithPlist:plist]; 16 }); 17 return profile; 18} 19 20- (instancetype)initWithPlist:(NSDictionary *)plist 21{ 22 if (self = [super init]) { 23 _plist = plist; 24 } 25 return self; 26} 27 28- (nullable NSString *)notificationServiceEnvironment 29{ 30 if (!_plist) { 31 return nil; 32 } 33 34 NSDictionary *entitlements = _plist[@"Entitlements"]; 35 NSString *apsEnvironment = entitlements[@"aps-environment"]; 36 return apsEnvironment; 37} 38 39- (EXAppReleaseType)appReleaseType { 40 NSString *provisioningPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"]; 41 if (!provisioningPath) { 42 // provisioning profile does not exist 43#if TARGET_IPHONE_SIMULATOR 44 return EXAppReleaseSimulator; 45#else 46 return EXAppReleaseAppStore; 47#endif 48 } 49 50 NSDictionary *mobileProvision = _plist; 51 if (!mobileProvision) { 52 // failure to read other than it simply not existing 53 return EXAppReleaseTypeUnknown; 54 } else if ([[mobileProvision objectForKey:@"ProvisionsAllDevices"] boolValue]) { 55 // enterprise distribution contains ProvisionsAllDevices - true 56 return EXAppReleaseEnterprise; 57 } else if ([mobileProvision objectForKey:@"ProvisionedDevices"] && [[mobileProvision objectForKey:@"ProvisionedDevices"] count] > 0) { 58 // development contains UDIDs and get-task-allow is true 59 // ad hoc contains UDIDs and get-task-allow is false 60 NSDictionary *entitlements = [mobileProvision objectForKey:@"Entitlements"]; 61 if ([[entitlements objectForKey:@"get-task-allow"] boolValue]) { 62 return EXAppReleaseDev; 63 } else { 64 return EXAppReleaseAdHoc; 65 } 66 } else { 67 // app store contains no UDIDs (if the file exists at all?) 68 return EXAppReleaseAppStore; 69 } 70} 71 72/** embedded.mobileprovision plist format: 73 74 AppIDName, // string — TextDetective 75 ApplicationIdentifierPrefix[], // [ string - 66PK3K3KEV ] 76 CreationData, // date — 2013-01-17T14:18:05Z 77 DeveloperCertificates[], // [ data ] 78 Entitlements { 79 application-identifier // string - 66PK3K3KEV.com.blindsight.textdetective 80 get-task-allow // true or false 81 keychain-access-groups[] // [ string - 66PK3K3KEV.* ] 82 }, 83 ExpirationDate, // date — 2014-01-17T14:18:05Z 84 Name, // string — Barrierefreikommunizieren (name assigned to the provisioning profile used) 85 ProvisionedDevices[], // [ string.... ] 86 TeamIdentifier[], // [string — HHBT96X2EX ] 87 TeamName, // string — The Blindsight Corporation 88 TimeToLive, // integer - 365 89 UUID, // string — 79F37E8E-CC8D-4819-8C13-A678479211CE 90 Version, // integer — 1 91 ProvisionsAllDevices // true or false ***NB: not sure if this is where this is 92 93 */ 94+ (NSDictionary *)_readProvisioningProfilePlist 95{ 96 NSString *profilePath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"]; 97 if (!profilePath) { 98 return nil; 99 } 100 101 NSError *error; 102 NSString *profileString = [NSString stringWithContentsOfFile:profilePath encoding:NSASCIIStringEncoding error:&error]; 103 if (!profileString) { 104 NSLog(@"Error reading provisioning profile: %@", error.localizedDescription); 105 return nil; 106 } 107 108 NSScanner *scanner = [NSScanner scannerWithString:profileString]; 109 BOOL readPrelude = [scanner scanUpToString:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" intoString:nil]; 110 if (!readPrelude) { 111 return nil; 112 } 113 114 NSString *plistString; 115 BOOL readPlist = [scanner scanUpToString:@"</plist>" intoString:&plistString]; 116 if (!readPlist) { 117 return nil; 118 } 119 plistString = [plistString stringByAppendingString:@"</plist>"]; 120 121 NSData *plistData = [plistString dataUsingEncoding:NSUTF8StringEncoding]; 122 NSDictionary *plistDictionary = [NSPropertyListSerialization propertyListWithData:plistData 123 options:NSPropertyListImmutable 124 format:NULL 125 error:&error]; 126 if (!plistDictionary) { 127 NSLog(@"Error unserializing provisioning profile plist: %@", error.localizedDescription); 128 return nil; 129 } 130 131 return plistDictionary; 132} 133 134@end 135