FBSimulatorControl/Configuration/FBSimulatorConfiguration.m (122 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 "FBSimulatorConfiguration.h"
#import <objc/runtime.h>
#import <FBControlCore/FBControlCoreGlobalConfiguration.h>
#import "FBSimulatorConfiguration+CoreSimulator.h"
#import "FBSimulatorControl+PrincipalClass.h"
#import "FBSimulatorControlFrameworkLoader.h"
@implementation FBSimulatorConfiguration
+ (void)initialize
{
[FBSimulatorControlFrameworkLoader.essentialFrameworks loadPrivateFrameworksOrAbort];
}
#pragma mark Initializers
- (instancetype)initWithNamedDevice:(FBDeviceType *)device os:(FBOSVersion *)os
{
NSParameterAssert(device);
NSParameterAssert(os);
self = [super init];
if (!self) {
return nil;
}
_device = device;
_os = os;
return self;
}
+ (instancetype)defaultConfiguration
{
static dispatch_once_t onceToken;
static FBSimulatorConfiguration *configuration;
dispatch_once(&onceToken, ^{
configuration = [self makeDefaultConfiguration];
});
return configuration;
}
+ (instancetype)makeDefaultConfiguration
{
FBDeviceModel model = FBDeviceModeliPhone6;
FBDeviceType *device = FBiOSTargetConfiguration.nameToDevice[model];
FBOSVersion *os = [FBSimulatorConfiguration newestAvailableOSForDevice:device];
NSAssert(
os,
@"Could not obtain OS for model '%@'. Supported OS Versions for Model %@. All Available OS Versions %@",
model,
[FBCollectionInformation oneLineDescriptionFromArray:[FBSimulatorConfiguration supportedOSVersionsForDevice:device]],
[FBCollectionInformation oneLineDescriptionFromArray:[FBSimulatorConfiguration supportedOSVersions]]
);
return [[FBSimulatorConfiguration alloc] initWithNamedDevice:device os:os];
}
#pragma mark NSCopying
- (instancetype)copyWithZone:(NSZone *)zone
{
return [[self.class alloc] initWithNamedDevice:self.device os:self.os];
}
#pragma mark NSObject
- (NSUInteger)hash
{
return self.deviceModel.hash ^ self.osVersionString.hash;
}
- (BOOL)isEqual:(FBSimulatorConfiguration *)object
{
if (![object isKindOfClass:self.class]) {
return NO;
}
return [self.deviceModel isEqualToString:object.deviceModel] &&
[self.osVersionString isEqualToString:object.osVersionString];
}
- (NSString *)description
{
return [NSString stringWithFormat:
@"Device '%@' | OS Version '%@' | Architecture '%@'",
self.deviceModel,
self.osVersionString,
self.architecture
];
}
#pragma mark Models
- (instancetype)withDeviceModel:(FBDeviceModel)model
{
FBDeviceType *device = FBiOSTargetConfiguration.nameToDevice[model];
device = device ?: [FBDeviceType genericWithName:model];
return [self withDevice:device];
}
#pragma mark OS Versions
- (instancetype)withOSNamed:(FBOSVersionName)osName
{
FBOSVersion *os = FBiOSTargetConfiguration.nameToOSVersion[osName];
os = os ?: [FBOSVersion genericWithName:osName];
return [self withOS:os];
}
#pragma mark Private
- (instancetype)withOS:(FBOSVersion *)os
{
NSParameterAssert(os);
return [[FBSimulatorConfiguration alloc] initWithNamedDevice:self.device os:os ];
}
- (instancetype)withDevice:(FBDeviceType *)device
{
NSParameterAssert(device);
// Use the current os if compatible
FBOSVersion *os = self.os;
if ([FBSimulatorConfiguration device:device andOSPairSupported:os]) {
return [[FBSimulatorConfiguration alloc] initWithNamedDevice:device os:os];
}
// Attempt to find the newest OS for this device, otherwise use what we had before.
os = [FBSimulatorConfiguration newestAvailableOSForDevice:device] ?: os;
return [[FBSimulatorConfiguration alloc] initWithNamedDevice:device os:os];
}
#pragma mark Private
+ (BOOL)device:(FBDeviceType *)device andOSPairSupported:(FBOSVersion *)os
{
return [os.families containsObject:@(device.family)];
}
- (FBDeviceModel)deviceModel
{
return self.device.model;
}
- (FBOSVersionName)osVersionString
{
return self.os.name;
}
- (FBArchitecture)architecture
{
return self.device.simulatorArchitecture;
}
@end