mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
[AltServer] Manages active/inactive profiles when installing apps
This commit is contained in:
@@ -351,10 +351,10 @@ private extension ConnectionManager
|
||||
switch result
|
||||
{
|
||||
case .failure(let error): finish(.failure(error))
|
||||
case .success(.beginInstallation):
|
||||
case .success(.beginInstallation(let installRequest)):
|
||||
print("Installing to device \(request.udid)...")
|
||||
|
||||
self.installApp(at: fileURL, toDeviceWithUDID: request.udid, connection: connection) { (result) in
|
||||
self.installApp(at: fileURL, toDeviceWithUDID: request.udid, activeProvisioningProfiles: installRequest.activeProfiles, connection: connection) { (result) in
|
||||
print("Installed to device with result:", result)
|
||||
switch result
|
||||
{
|
||||
@@ -403,14 +403,14 @@ private extension ConnectionManager
|
||||
}
|
||||
}
|
||||
|
||||
func installApp(at fileURL: URL, toDeviceWithUDID udid: String, connection: ClientConnection, completionHandler: @escaping (Result<Void, ALTServerError>) -> Void)
|
||||
func installApp(at fileURL: URL, toDeviceWithUDID udid: String, activeProvisioningProfiles: Set<String>?, connection: ClientConnection, completionHandler: @escaping (Result<Void, ALTServerError>) -> Void)
|
||||
{
|
||||
let serialQueue = DispatchQueue(label: "com.altstore.ConnectionManager.installQueue", qos: .default)
|
||||
var isSending = false
|
||||
|
||||
var observation: NSKeyValueObservation?
|
||||
|
||||
let progress = ALTDeviceManager.shared.installApp(at: fileURL, toDeviceWithUDID: udid) { (success, error) in
|
||||
let progress = ALTDeviceManager.shared.installApp(at: fileURL, toDeviceWithUDID: udid, activeProvisioningProfiles: activeProvisioningProfiles) { (success, error) in
|
||||
print("Installed app with result:", error == nil ? "Success" : error!.localizedDescription)
|
||||
|
||||
if let error = error.map({ $0 as? ALTServerError ?? ALTServerError(.unknown) })
|
||||
|
||||
@@ -536,7 +536,8 @@ To prevent this from happening, feel free to try again with another Apple ID to
|
||||
{
|
||||
try Result(success, error).get()
|
||||
|
||||
ALTDeviceManager.shared.installApp(at: application.fileURL, toDeviceWithUDID: device.identifier) { (success, error) in
|
||||
let activeProfiles: Set<String>? = (team.type == .free) ? [profile.bundleIdentifier] : nil
|
||||
ALTDeviceManager.shared.installApp(at: application.fileURL, toDeviceWithUDID: device.identifier, activeProvisioningProfiles: activeProfiles) { (success, error) in
|
||||
completionHandler(Result(success, error))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ extern NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification
|
||||
- (void)start;
|
||||
|
||||
/* App Installation */
|
||||
- (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid 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)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(NSDictionary<NSString *, NSError *> *errors))completionHandler;
|
||||
|
||||
@@ -71,7 +71,7 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
||||
|
||||
#pragma mark - App Installation -
|
||||
|
||||
- (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler
|
||||
- (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler
|
||||
{
|
||||
NSProgress *progress = [NSProgress discreteProgressWithTotalUnitCount:4];
|
||||
|
||||
@@ -88,41 +88,42 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
||||
__block misagent_client_t mis = NULL;
|
||||
__block lockdownd_service_descriptor_t service = NULL;
|
||||
|
||||
NSURL *removedProfilesDirectoryURL = [[[NSFileManager defaultManager] temporaryDirectory] URLByAppendingPathComponent:[[NSUUID UUID] UUIDString]];
|
||||
NSMutableDictionary<NSString *, ALTProvisioningProfile *> *preferredProfiles = [NSMutableDictionary dictionary];
|
||||
NSMutableDictionary<NSString *, ALTProvisioningProfile *> *cachedProfiles = [NSMutableDictionary dictionary];
|
||||
NSMutableSet<ALTProvisioningProfile *> *installedProfiles = [NSMutableSet set];
|
||||
|
||||
void (^finish)(NSError *error) = ^(NSError *error) {
|
||||
void (^finish)(NSError *error) = ^(NSError *e) {
|
||||
__block NSError *error = e;
|
||||
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:removedProfilesDirectoryURL.path isDirectory:nil])
|
||||
if (activeProvisioningProfiles != nil)
|
||||
{
|
||||
// Reinstall all provisioning profiles we removed before installation.
|
||||
// Remove installed provisioning profiles if they're not active.
|
||||
|
||||
NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:removedProfilesDirectoryURL.path error:nil];
|
||||
for (NSString *filename in contents)
|
||||
for (ALTProvisioningProfile *installedProfile in installedProfiles)
|
||||
{
|
||||
NSURL *fileURL = [removedProfilesDirectoryURL URLByAppendingPathComponent:filename];
|
||||
|
||||
ALTProvisioningProfile *provisioningProfile = [[ALTProvisioningProfile alloc] initWithURL:fileURL];
|
||||
if (provisioningProfile == nil)
|
||||
if (![activeProvisioningProfiles containsObject:installedProfile.bundleIdentifier])
|
||||
{
|
||||
continue;
|
||||
NSError *removeError = nil;
|
||||
if (![self removeProvisioningProfile:installedProfile misagent:mis error:&removeError])
|
||||
{
|
||||
if (error == nil)
|
||||
{
|
||||
error = removeError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ALTProvisioningProfile *preferredProfile = preferredProfiles[provisioningProfile.bundleIdentifier];
|
||||
if (![preferredProfile isEqual:provisioningProfile])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
NSError *installError = nil;
|
||||
if (![self installProvisioningProfile:preferredProfile misagent:mis error:&installError])
|
||||
}
|
||||
}
|
||||
|
||||
[cachedProfiles enumerateKeysAndObjectsUsingBlock:^(NSString *bundleID, ALTProvisioningProfile *profile, BOOL * _Nonnull stop) {
|
||||
NSError *installError = nil;
|
||||
if (![self installProvisioningProfile:profile misagent:mis error:&installError])
|
||||
{
|
||||
if (error == nil)
|
||||
{
|
||||
error = installError;
|
||||
}
|
||||
}
|
||||
|
||||
[[NSFileManager defaultManager] removeItemAtURL:removedProfilesDirectoryURL error:nil];
|
||||
}
|
||||
}];
|
||||
|
||||
instproxy_client_free(ipc);
|
||||
afc_client_free(afc);
|
||||
@@ -278,17 +279,24 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
||||
service = NULL;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
/* Provisioning Profiles */
|
||||
NSURL *provisioningProfileURL = [appBundleURL URLByAppendingPathComponent:@"embedded.mobileprovision"];
|
||||
ALTProvisioningProfile *installationProvisioningProfile = [[ALTProvisioningProfile alloc] initWithURL:provisioningProfileURL];
|
||||
if (installationProvisioningProfile != nil)
|
||||
if (activeProvisioningProfiles != nil)
|
||||
{
|
||||
NSError *error = nil;
|
||||
if (![[NSFileManager defaultManager] createDirectoryAtURL:removedProfilesDirectoryURL withIntermediateDirectories:YES attributes:nil error:&error])
|
||||
{
|
||||
return finish(error);
|
||||
}
|
||||
|
||||
NSArray<ALTProvisioningProfile *> *provisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:&error];
|
||||
if (provisioningProfiles == nil)
|
||||
{
|
||||
@@ -302,27 +310,33 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
||||
continue;
|
||||
}
|
||||
|
||||
ALTProvisioningProfile *preferredProfile = preferredProfiles[provisioningProfile.bundleIdentifier];
|
||||
if (preferredProfile != nil)
|
||||
BOOL installingProfile = NO;
|
||||
for (ALTProvisioningProfile *installedProfile in installedProfiles)
|
||||
{
|
||||
if ([provisioningProfile.expirationDate compare:preferredProfile.expirationDate] == NSOrderedDescending)
|
||||
if ([installedProfile.bundleIdentifier isEqualToString:provisioningProfile.bundleIdentifier])
|
||||
{
|
||||
preferredProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
|
||||
installingProfile = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if ([activeProvisioningProfiles containsObject:provisioningProfile.bundleIdentifier] && !installingProfile)
|
||||
{
|
||||
preferredProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
|
||||
}
|
||||
|
||||
NSString *filename = [NSString stringWithFormat:@"%@.mobileprovision", [[NSUUID UUID] UUIDString]];
|
||||
NSURL *fileURL = [removedProfilesDirectoryURL URLByAppendingPathComponent:filename];
|
||||
|
||||
NSError *copyError = nil;
|
||||
if (![provisioningProfile.data writeToURL:fileURL options:NSDataWritingAtomic error:©Error])
|
||||
{
|
||||
NSLog(@"Failed to copy profile to temporary URL. %@", copyError);
|
||||
continue;
|
||||
// We're not installing this provisioning profile, but it is active,
|
||||
// so we'll cache it to install it again after installing this app.
|
||||
|
||||
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])
|
||||
|
||||
Reference in New Issue
Block a user