FBDeviceControl/Commands/FBDeviceProvisioningProfileCommands.m (96 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #import "FBDeviceProvisioningProfileCommands.h" #import "FBDevice.h" @interface FBDeviceProvisioningProfileCommands () @property (nonatomic, weak, readonly) FBDevice *device; @end @implementation FBDeviceProvisioningProfileCommands #pragma mark Public + (instancetype)commandsWithTarget:(FBDevice *)target { return [[self alloc] initWithDevice:target]; } - (instancetype)initWithDevice:(FBDevice *)device { self = [super init]; if (!self) { return nil; } _device = device; return self; } #pragma mark FBDeviceProvisioningProfileCommands Implementation - (FBFuture<NSArray<NSDictionary<NSString *, id> *> *> *)allProvisioningProfiles { return [[self listProvisioningProfiles] onQueue:self.device.workQueue pop:^(NSArray<id> *merged) { id<FBDeviceCommands> device = merged[0]; NSArray<id> *profiles = [merged subarrayWithRange:NSMakeRange(1, merged.count - 1)]; NSMutableArray<NSDictionary<NSString *, id> *> *allProfiles = NSMutableArray.array; for (id profile in profiles) { NSDictionary<NSString *, id> *payload = CFBridgingRelease(device.calls.ProvisioningProfileCopyPayload((__bridge CFTypeRef)(profile))); payload = [FBCollectionOperations recursiveFilteredJSONSerializableRepresentationOfDictionary:payload]; [allProfiles addObject:payload]; } return [FBFuture futureWithResult:allProfiles]; }]; } - (FBFuture<NSDictionary<NSString *, id> *> *)removeProvisioningProfile:(NSString *)uuid { return [[self.device connectToDeviceWithPurpose:@"remove_provisioning_profile"] onQueue:self.device.workQueue pop:^(id<FBDeviceCommands> device) { int status = device.calls.RemoveProvisioningProfile(device.amDeviceRef, (__bridge CFStringRef)(uuid)); if (status != 0) { NSString *errorDescription = CFBridgingRelease(device.calls.ProvisioningProfileCopyErrorStringForCode(status)); return [[FBControlCoreError describeFormat:@"Failed to remove profile %@: %@", uuid, errorDescription] failFuture]; } return [FBFuture futureWithResult:@{}]; }]; } - (FBFuture<NSDictionary<NSString *, id> *> *)installProvisioningProfile:(NSData *)profileData { return [[self.device connectToDeviceWithPurpose:@"install_provisioning_profile"] onQueue:self.device.workQueue pop:^(id<FBDeviceCommands> device) { MISProfileRef profile = device.calls.ProvisioningProfileCreateWithData((__bridge CFDataRef)(profileData)); if (!profile) { return [[FBControlCoreError describeFormat:@"Could not construct profile from data %@", profileData] failFuture]; } int status = device.calls.InstallProvisioningProfile(device.amDeviceRef, profile); if (status != 0) { NSString *errorDescription = CFBridgingRelease(device.calls.ProvisioningProfileCopyErrorStringForCode(status)); return [[FBControlCoreError describeFormat:@"Failed to install profile %@: %@", profile, errorDescription] failFuture]; } NSDictionary<NSString *, id> *payload = CFBridgingRelease(device.calls.ProvisioningProfileCopyPayload(profile)); payload = [FBCollectionOperations recursiveFilteredJSONSerializableRepresentationOfDictionary:payload]; if (!payload) { return [[FBControlCoreError describeFormat:@"Failed to get payload of %@", profile] failFuture]; } return [FBFuture futureWithResult:payload]; }]; } #pragma mark Private - (FBFutureContext<NSArray<id> *> *)listProvisioningProfiles { return [[self.device connectToDeviceWithPurpose:@"list_provisioning_profiles"] onQueue:self.device.workQueue pend:^(id<FBDeviceCommands> device) { NSArray<id> *profiles = CFBridgingRelease(device.calls.CopyProvisioningProfiles(device.amDeviceRef)); if (!profiles) { return [[FBControlCoreError describeFormat:@"Failed to copy provisioning profiles"] failFuture]; } return [FBFuture futureWithResult:[@[device] arrayByAddingObjectsFromArray:profiles]]; }]; } @end