[AltServer] Fixes installing more than 3 apps on 13.3 and below

This commit is contained in:
Riley Testut
2020-03-17 12:24:11 -07:00
parent a6746754b8
commit 0d65fc9974
3 changed files with 148 additions and 163 deletions

View File

@@ -445,12 +445,10 @@ private extension ConnectionManager
func handleInstallProvisioningProfilesRequest(_ request: InstallProvisioningProfilesRequest, for connection: ClientConnection) func handleInstallProvisioningProfilesRequest(_ request: InstallProvisioningProfilesRequest, for connection: ClientConnection)
{ {
let removeInactiveProfiles = (request.activeProfiles != nil) ALTDeviceManager.shared.installProvisioningProfiles(request.provisioningProfiles, toDeviceWithUDID: request.udid, activeProvisioningProfiles: request.activeProfiles) { (success, error) in
ALTDeviceManager.shared.installProvisioningProfiles(request.provisioningProfiles, toDeviceWithUDID: request.udid, activeProvisioningProfiles: request.activeProfiles, removeInactiveProvisioningProfiles: removeInactiveProfiles) { (errors) in if let error = error, !success
if let error = errors.values.first
{ {
print("Failed to install profiles \(request.provisioningProfiles.map { $0.bundleIdentifier }):", errors) print("Failed to install profiles \(request.provisioningProfiles.map { $0.bundleIdentifier }):", error)
let errorResponse = ErrorResponse(error: ALTServerError(error)) let errorResponse = ErrorResponse(error: ALTServerError(error))
connection.send(errorResponse, shouldDisconnect: true) { (result) in connection.send(errorResponse, shouldDisconnect: true) { (result) in
@@ -471,10 +469,10 @@ private extension ConnectionManager
func handleRemoveProvisioningProfilesRequest(_ request: RemoveProvisioningProfilesRequest, for connection: ClientConnection) func handleRemoveProvisioningProfilesRequest(_ request: RemoveProvisioningProfilesRequest, for connection: ClientConnection)
{ {
ALTDeviceManager.shared.removeProvisioningProfiles(forBundleIdentifiers: request.bundleIdentifiers, fromDeviceWithUDID: request.udid) { (errors) in ALTDeviceManager.shared.removeProvisioningProfiles(forBundleIdentifiers: request.bundleIdentifiers, fromDeviceWithUDID: request.udid) { (success, error) in
if let error = errors.values.first if let error = error, !success
{ {
print("Failed to remove profiles \(request.bundleIdentifiers):", errors) print("Failed to remove profiles \(request.bundleIdentifiers):", error)
let errorResponse = ErrorResponse(error: ALTServerError(error)) let errorResponse = ErrorResponse(error: ALTServerError(error))
connection.send(errorResponse, shouldDisconnect: true) { (result) in connection.send(errorResponse, shouldDisconnect: true) { (result) in

View File

@@ -29,8 +29,8 @@ extern NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification
/* App Installation */ /* App Installation */
- (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; - (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
- (void)installProvisioningProfiles:(NSSet<ALTProvisioningProfile *> *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles removeInactiveProvisioningProfiles:(BOOL)removeInactiveProvisioningProfiles completionHandler:(void (^)(NSDictionary<ALTProvisioningProfile *, NSError *> *errors))completionHandler; - (void)installProvisioningProfiles:(NSSet<ALTProvisioningProfile *> *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
- (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(NSDictionary<NSString *, NSError *> *errors))completionHandler; - (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
/* Connections */ /* Connections */
- (void)startWiredConnectionToDevice:(ALTDevice *)device completionHandler:(void (^)(ALTWiredConnection *_Nullable connection, NSError *_Nullable error))completionHandler; - (void)startWiredConnectionToDevice:(ALTDevice *)device completionHandler:(void (^)(ALTWiredConnection *_Nullable connection, NSError *_Nullable error))completionHandler;

View File

@@ -176,6 +176,20 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
return finish([NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadCorruptFileError userInfo:@{NSURLErrorKey: fileURL}]); return finish([NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadCorruptFileError userInfo:@{NSURLErrorKey: fileURL}]);
} }
ALTApplication *application = [[ALTApplication alloc] initWithFileURL:appBundleURL];
if (application.provisioningProfile)
{
[installedProfiles addObject:application.provisioningProfile];
}
for (ALTApplication *appExtension in application.appExtensions)
{
if (appExtension.provisioningProfile)
{
[installedProfiles addObject:appExtension.provisioningProfile];
}
}
/* Find Device */ /* Find Device */
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS) if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
{ {
@@ -279,76 +293,39 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
service = NULL; service = NULL;
} }
ALTApplication *application = [[ALTApplication alloc] initWithFileURL:appBundleURL]; BOOL shouldManageProfiles = (activeProvisioningProfiles != nil || [application.provisioningProfile isFreeProvisioningProfile]);
if (application.provisioningProfile) if (shouldManageProfiles)
{ {
[installedProfiles addObject:application.provisioningProfile]; // Free developer account was used to sign this app, so we need to remove all
} // provisioning profiles in order to remain under sideloaded app limit.
for (ALTApplication *appExtension in application.appExtensions)
{
if (appExtension.provisioningProfile)
{
[installedProfiles addObject:appExtension.provisioningProfile];
}
}
/* Provisioning Profiles */
if (activeProvisioningProfiles != nil)
{
NSError *error = nil; NSError *error = nil;
NSArray<ALTProvisioningProfile *> *provisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:&error]; NSDictionary<NSString *, ALTProvisioningProfile *> *removedProfiles = [self removeAllFreeProfilesExcludingBundleIdentifiers:nil misagent:mis error:&error];
if (provisioningProfiles == nil) if (removedProfiles == nil)
{ {
return finish(error); return finish(error);
} }
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles) [removedProfiles enumerateKeysAndObjectsUsingBlock:^(NSString *bundleID, ALTProvisioningProfile *profile, BOOL * _Nonnull stop) {
{ if (activeProvisioningProfiles != nil)
if (![provisioningProfile isFreeProvisioningProfile])
{ {
continue; if ([activeProvisioningProfiles containsObject:bundleID])
}
BOOL installingProfile = NO;
for (ALTProvisioningProfile *installedProfile in installedProfiles)
{
if ([installedProfile.bundleIdentifier isEqualToString:provisioningProfile.bundleIdentifier])
{ {
installingProfile = YES; // Only cache active profiles to reinstall afterwards.
break; cachedProfiles[bundleID] = profile;
} }
} }
else
if ([activeProvisioningProfiles containsObject:provisioningProfile.bundleIdentifier] && !installingProfile)
{ {
// We're not installing this provisioning profile, but it is active, // Cache all profiles to reinstall afterwards if we didn't provide activeProvisioningProfiles.
// so we'll cache it to install it again after installing this app. cachedProfiles[bundleID] = profile;
ALTProvisioningProfile *preferredProfile = cachedProfiles[provisioningProfile.bundleIdentifier];
if (preferredProfile != nil)
{
if ([provisioningProfile.expirationDate compare:preferredProfile.expirationDate] == NSOrderedDescending)
{
cachedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
}
}
else
{
cachedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
}
} }
}];
if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:&error])
{
return finish(error);
}
}
lockdownd_client_free(client);
client = NULL;
} }
lockdownd_client_free(client);
client = NULL;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSProgress *installationProgress = [NSProgress progressWithTotalUnitCount:100 parent:progress pendingUnitCount:1]; NSProgress *installationProgress = [NSProgress progressWithTotalUnitCount:100 parent:progress pendingUnitCount:1];
@@ -514,7 +491,7 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
#pragma mark - Provisioning Profiles - #pragma mark - Provisioning Profiles -
- (void)installProvisioningProfiles:(NSSet<ALTProvisioningProfile *> *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(NSSet<NSString *> *)activeProvisioningProfiles removeInactiveProvisioningProfiles:(BOOL)removeInactiveProvisioningProfiles completionHandler:(void (^)(NSDictionary<ALTProvisioningProfile *, NSError *> *errors))completionHandler; - (void)installProvisioningProfiles:(NSSet<ALTProvisioningProfile *> *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *error))completionHandler
{ {
dispatch_async(self.installationQueue, ^{ dispatch_async(self.installationQueue, ^{
__block idevice_t device = NULL; __block idevice_t device = NULL;
@@ -523,109 +500,86 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
__block misagent_client_t mis = NULL; __block misagent_client_t mis = NULL;
__block lockdownd_service_descriptor_t service = NULL; __block lockdownd_service_descriptor_t service = NULL;
void (^finish)(NSDictionary<ALTProvisioningProfile *, NSError *> *, NSError *) = ^(NSDictionary *installationErrors, NSError *error) { void (^finish)(NSError *_Nullable) = ^(NSError *error) {
lockdownd_service_descriptor_free(service); lockdownd_service_descriptor_free(service);
misagent_client_free(mis); misagent_client_free(mis);
afc_client_free(afc); afc_client_free(afc);
lockdownd_client_free(client); lockdownd_client_free(client);
idevice_free(device); idevice_free(device);
if (installationErrors) completionHandler(error == nil, error);
{
completionHandler(installationErrors);
}
else
{
NSMutableDictionary *installationErrors = [NSMutableDictionary dictionary];
for (ALTProvisioningProfile *profile in provisioningProfiles)
{
installationErrors[profile] = error;
}
completionHandler(installationErrors);
}
}; };
/* Find Device */ /* Find Device */
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS) if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
{ {
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]);
} }
/* Connect to Device */ /* Connect to Device */
if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS) if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS)
{ {
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
} }
/* Connect to Misagent */ /* Connect to Misagent */
if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL) if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL)
{ {
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
} }
if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS) if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS)
{ {
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
} }
NSError *error = nil; NSError *error = nil;
NSArray<ALTProvisioningProfile *> *installedProvisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:&error];
if (provisioningProfiles == nil) if (activeProvisioningProfiles != nil)
{ {
return finish(nil, error); // Remove all non-active free provisioning profiles.
}
for (ALTProvisioningProfile *provisioningProfile in installedProvisioningProfiles) NSMutableSet *excludedBundleIdentifiers = [activeProvisioningProfiles mutableCopy];
{ for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
if (![provisioningProfile isFreeProvisioningProfile])
{ {
continue; // Ensure we DO remove old versions of profiles we're about to install, even if they are active.
[excludedBundleIdentifiers removeObject:provisioningProfile.bundleIdentifier];
} }
BOOL removeProfile = NO; if (![self removeAllFreeProfilesExcludingBundleIdentifiers:excludedBundleIdentifiers misagent:mis error:&error])
for (ALTProvisioningProfile *profile in provisioningProfiles)
{ {
if ([profile.bundleIdentifier isEqualToString:provisioningProfile.bundleIdentifier]) return finish(error);
{
// Remove previous provisioning profile before installing new one.
removeProfile = YES;
break;
}
}
if (removeInactiveProvisioningProfiles && ![activeProvisioningProfiles containsObject:provisioningProfile.bundleIdentifier])
{
// Remove all non-active provisioning profiles to remain under 3 app limit for free developer accounts.
removeProfile = YES;
}
if (removeProfile)
{
if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:&error])
{
return finish(nil, error);
}
} }
} }
else
{
// Remove only older versions of provisioning profiles we're about to install.
NSMutableDictionary<ALTProvisioningProfile *, NSError *> *profileErrors = [NSMutableDictionary dictionary]; NSMutableSet *bundleIdentifiers = [NSMutableSet set];
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
{
[bundleIdentifiers addObject:provisioningProfile.bundleIdentifier];
}
if (![self removeProvisioningProfilesForBundleIdentifiers:bundleIdentifiers misagent:mis error:&error])
{
return finish(error);
}
}
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles) for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
{ {
NSError *error = nil;
if (![self installProvisioningProfile:provisioningProfile misagent:mis error:&error]) if (![self installProvisioningProfile:provisioningProfile misagent:mis error:&error])
{ {
profileErrors[provisioningProfile] = error; return finish(error);
} }
} }
finish(profileErrors, nil); finish(nil);
}); });
} }
- (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(NSDictionary<NSString *, NSError *> *errors))completionHandler - (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL success, NSError *error))completionHandler
{ {
dispatch_async(self.installationQueue, ^{ dispatch_async(self.installationQueue, ^{
__block idevice_t device = NULL; __block idevice_t device = NULL;
@@ -634,79 +588,112 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
__block misagent_client_t mis = NULL; __block misagent_client_t mis = NULL;
__block lockdownd_service_descriptor_t service = NULL; __block lockdownd_service_descriptor_t service = NULL;
void (^finish)(NSDictionary<NSString *, NSError *> *, NSError *) = ^(NSDictionary *installationErrors, NSError *error) { void (^finish)(NSError *_Nullable) = ^(NSError *error) {
lockdownd_service_descriptor_free(service); lockdownd_service_descriptor_free(service);
misagent_client_free(mis); misagent_client_free(mis);
afc_client_free(afc); afc_client_free(afc);
lockdownd_client_free(client); lockdownd_client_free(client);
idevice_free(device); idevice_free(device);
if (installationErrors) completionHandler(error == nil, error);
{
completionHandler(installationErrors);
}
else
{
NSMutableDictionary *installationErrors = [NSMutableDictionary dictionary];
for (NSString *bundleID in bundleIdentifiers)
{
installationErrors[bundleID] = error;
}
completionHandler(installationErrors);
}
}; };
/* Find Device */ /* Find Device */
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS) if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
{ {
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]);
} }
/* Connect to Device */ /* Connect to Device */
if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS) if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS)
{ {
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
} }
/* Connect to Misagent */ /* Connect to Misagent */
if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL) if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL)
{ {
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
} }
if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS) if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS)
{ {
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
} }
NSError *error = nil; NSError *error = nil;
NSArray<ALTProvisioningProfile *> *provisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:&error]; if (![self removeProvisioningProfilesForBundleIdentifiers:bundleIdentifiers misagent:mis error:&error])
if (provisioningProfiles == nil)
{ {
return finish(nil, error); return finish(error);
} }
NSMutableDictionary<NSString *, NSError *> *profileErrors = [NSMutableDictionary dictionary]; finish(nil);
/* Remove provisioning profiles */
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
{
if (![bundleIdentifiers containsObject:provisioningProfile.bundleIdentifier])
{
continue;
}
if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:&error])
{
profileErrors[provisioningProfile.bundleIdentifier] = error;
}
}
finish(profileErrors, nil);
}); });
} }
- (NSDictionary<NSString *, ALTProvisioningProfile *> *)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers misagent:(misagent_client_t)mis error:(NSError **)error
{
return [self removeAllProfilesForBundleIdentifiers:bundleIdentifiers excludingBundleIdentifiers:nil limitedToFreeProfiles:NO misagent:mis error:error];
}
- (NSDictionary<NSString *, ALTProvisioningProfile *> *)removeAllFreeProfilesExcludingBundleIdentifiers:(nullable NSSet<NSString *> *)bundleIdentifiers misagent:(misagent_client_t)mis error:(NSError **)error
{
return [self removeAllProfilesForBundleIdentifiers:nil excludingBundleIdentifiers:bundleIdentifiers limitedToFreeProfiles:YES misagent:mis error:error];
}
- (NSDictionary<NSString *, ALTProvisioningProfile *> *)removeAllProfilesForBundleIdentifiers:(nullable NSSet<NSString *> *)includedBundleIdentifiers
excludingBundleIdentifiers:(nullable NSSet<NSString *> *)excludedBundleIdentifiers
limitedToFreeProfiles:(BOOL)limitedToFreeProfiles
misagent:(misagent_client_t)mis
error:(NSError **)error
{
NSMutableDictionary<NSString *, ALTProvisioningProfile *> *cachedProfiles = [NSMutableDictionary dictionary];
NSArray<ALTProvisioningProfile *> *provisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:error];
if (provisioningProfiles == nil)
{
return nil;
}
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
{
if (limitedToFreeProfiles && ![provisioningProfile isFreeProvisioningProfile])
{
continue;
}
if (includedBundleIdentifiers != nil && ![includedBundleIdentifiers containsObject:provisioningProfile.bundleIdentifier])
{
continue;
}
if (excludedBundleIdentifiers != nil && [excludedBundleIdentifiers containsObject:provisioningProfile.bundleIdentifier])
{
continue;
}
ALTProvisioningProfile *preferredProfile = cachedProfiles[provisioningProfile.bundleIdentifier];
if (preferredProfile != nil)
{
if ([provisioningProfile.expirationDate compare:preferredProfile.expirationDate] == NSOrderedDescending)
{
cachedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
}
}
else
{
cachedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
}
if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:error])
{
return nil;
}
}
return cachedProfiles;
}
- (BOOL)installProvisioningProfile:(ALTProvisioningProfile *)provisioningProfile misagent:(misagent_client_t)mis error:(NSError **)error - (BOOL)installProvisioningProfile:(ALTProvisioningProfile *)provisioningProfile misagent:(misagent_client_t)mis error:(NSError **)error
{ {
plist_t pdata = plist_new_data((const char *)provisioningProfile.data.bytes, provisioningProfile.data.length); plist_t pdata = plist_new_data((const char *)provisioningProfile.data.bytes, provisioningProfile.data.length);