mirror of
https://github.com/kyleneideck/BackgroundMusic
synced 2024-11-10 06:34:22 +00:00
Add a UI tests target for BGMApp. Only has one test so far.
The UI tests run with clean user defaults, but BGMDevice and Scripting Bridge still need to be mocked/stubbed out. That also means that the UI tests can only run if BGMDriver is installed and that changes to BGMDriver's state made during the tests will persist.
This commit is contained in:
parent
d49ff20820
commit
60e1b3564b
12 changed files with 362 additions and 54 deletions
|
@ -36,6 +36,7 @@
|
|||
1CCC4F3E1E58196C008053E4 /* BGMXPCHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CCC4F3C1E58196C008053E4 /* BGMXPCHelperTests.m */; };
|
||||
1CCC4F4D1E581C40008053E4 /* BGMMusicPlayersUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CCC4F4B1E581C40008053E4 /* BGMMusicPlayersUnitTests.mm */; };
|
||||
1CCC4F4E1E581C40008053E4 /* Mock_CAHALAudioObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CCC4F4C1E581C40008053E4 /* Mock_CAHALAudioObject.cpp */; };
|
||||
1CCC4F621E584100008053E4 /* BGMAppUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CCC4F611E584100008053E4 /* BGMAppUITests.m */; };
|
||||
1CD1FD301BDDEAF2004F7E1B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CD1FD2F1BDDEAF2004F7E1B /* AudioToolbox.framework */; };
|
||||
1CE7064C1BF1EC0600BFC06D /* BGMOutputDevicePrefs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CE7064B1BF1EC0600BFC06D /* BGMOutputDevicePrefs.mm */; };
|
||||
1CED61691C3081C2002CAFCF /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 1CED61681C3081C2002CAFCF /* LICENSE */; };
|
||||
|
@ -93,6 +94,13 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
1CCC4F591E584081008053E4 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 1CB8B32E1BBA75EF000E2DD1 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 1CB8B3351BBA75EF000E2DD1;
|
||||
remoteInfo = "Background Music";
|
||||
};
|
||||
278D71F31CABB88B00899CF9 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 1CB8B32E1BBA75EF000E2DD1 /* Project object */;
|
||||
|
@ -167,6 +175,9 @@
|
|||
1CCC4F491E581C0D008053E4 /* BGMAppUnitTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "BGMAppUnitTests-Info.plist"; path = "UnitTests/BGMAppUnitTests-Info.plist"; sourceTree = "<group>"; };
|
||||
1CCC4F4B1E581C40008053E4 /* BGMMusicPlayersUnitTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = BGMMusicPlayersUnitTests.mm; path = UnitTests/BGMMusicPlayersUnitTests.mm; sourceTree = "<group>"; };
|
||||
1CCC4F4C1E581C40008053E4 /* Mock_CAHALAudioObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Mock_CAHALAudioObject.cpp; path = UnitTests/Mock_CAHALAudioObject.cpp; sourceTree = "<group>"; };
|
||||
1CCC4F541E584081008053E4 /* BGMAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BGMAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1CCC4F5F1E5840EF008053E4 /* BGMAppUITests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "BGMAppUITests-Info.plist"; path = "UITests/BGMAppUITests-Info.plist"; sourceTree = "<group>"; };
|
||||
1CCC4F611E584100008053E4 /* BGMAppUITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BGMAppUITests.m; path = BGMAppTests/UITests/BGMAppUITests.m; sourceTree = SOURCE_ROOT; };
|
||||
1CD1FD2F1BDDEAF2004F7E1B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
1CE7064A1BF1EC0600BFC06D /* BGMOutputDevicePrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BGMOutputDevicePrefs.h; path = Preferences/BGMOutputDevicePrefs.h; sourceTree = "<group>"; };
|
||||
1CE7064B1BF1EC0600BFC06D /* BGMOutputDevicePrefs.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = BGMOutputDevicePrefs.mm; path = Preferences/BGMOutputDevicePrefs.mm; sourceTree = "<group>"; };
|
||||
|
@ -236,6 +247,13 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1CCC4F511E584081008053E4 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
27379B8C1C7F57DA0084A24C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -380,6 +398,7 @@
|
|||
27379B8F1C7F57DA0084A24C /* BGMXPCHelper.xpc */,
|
||||
278D71F11CABB6FF00899CF9 /* BGMXPCHelperTests.xctest */,
|
||||
2743C9F61D86CFF90089613B /* BGMAppUnitTests.xctest */,
|
||||
1CCC4F541E584081008053E4 /* BGMAppUITests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -428,6 +447,7 @@
|
|||
1CB8B34C1BBA75F0000E2DD1 /* BGMApp Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1CCC4F551E584081008053E4 /* UI Tests */,
|
||||
1CCC4F4F1E581C52008053E4 /* Unit Tests */,
|
||||
1CCC4F481E581BAA008053E4 /* Supporting Files */,
|
||||
);
|
||||
|
@ -456,6 +476,7 @@
|
|||
1CCC4F481E581BAA008053E4 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1CCC4F5F1E5840EF008053E4 /* BGMAppUITests-Info.plist */,
|
||||
1CCC4F491E581C0D008053E4 /* BGMAppUnitTests-Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
|
@ -470,6 +491,15 @@
|
|||
name = "Unit Tests";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1CCC4F551E584081008053E4 /* UI Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1CCC4F611E584100008053E4 /* BGMAppUITests.m */,
|
||||
);
|
||||
name = "UI Tests";
|
||||
path = ../BGMAppUITests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1CF69BA31BCFF59C009B5D1F /* OptimizationProfiles */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -548,6 +578,24 @@
|
|||
productReference = 1CB8B3361BBA75EF000E2DD1 /* Background Music.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
1CCC4F531E584081008053E4 /* BGMAppUITests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1CCC4F5B1E584081008053E4 /* Build configuration list for PBXNativeTarget "BGMAppUITests" */;
|
||||
buildPhases = (
|
||||
1CCC4F501E584081008053E4 /* Sources */,
|
||||
1CCC4F511E584081008053E4 /* Frameworks */,
|
||||
1CCC4F521E584081008053E4 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1CCC4F5A1E584081008053E4 /* PBXTargetDependency */,
|
||||
);
|
||||
name = BGMAppUITests;
|
||||
productName = BGMAppUITests;
|
||||
productReference = 1CCC4F541E584081008053E4 /* BGMAppUITests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.ui-testing";
|
||||
};
|
||||
27379B8E1C7F57DA0084A24C /* BGMXPCHelper */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 27379B981C7F57DB0084A24C /* Build configuration list for PBXNativeTarget "BGMXPCHelper" */;
|
||||
|
@ -608,7 +656,7 @@
|
|||
isa = PBXProject;
|
||||
attributes = {
|
||||
CLASSPREFIX = BGM;
|
||||
LastUpgradeCheck = 0810;
|
||||
LastUpgradeCheck = 0820;
|
||||
ORGANIZATIONNAME = "Background Music contributors";
|
||||
TargetAttributes = {
|
||||
1CB8B3351BBA75EF000E2DD1 = {
|
||||
|
@ -619,6 +667,11 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
1CCC4F531E584081008053E4 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
ProvisioningStyle = Manual;
|
||||
TestTargetID = 1CB8B3351BBA75EF000E2DD1;
|
||||
};
|
||||
27379B8E1C7F57DA0084A24C = {
|
||||
CreatedOnToolsVersion = 7.2.1;
|
||||
DevelopmentTeam = PR7PXC66S5;
|
||||
|
@ -643,6 +696,7 @@
|
|||
projectRoot = "";
|
||||
targets = (
|
||||
1CB8B3351BBA75EF000E2DD1 /* Background Music */,
|
||||
1CCC4F531E584081008053E4 /* BGMAppUITests */,
|
||||
2743C9F51D86CFF90089613B /* BGMAppUnitTests */,
|
||||
27379B8E1C7F57DA0084A24C /* BGMXPCHelper */,
|
||||
278D71E51CABB6FF00899CF9 /* BGMXPCHelperTests */,
|
||||
|
@ -661,6 +715,13 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1CCC4F521E584081008053E4 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
27379B8D1C7F57DA0084A24C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -748,6 +809,14 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1CCC4F501E584081008053E4 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1CCC4F621E584100008053E4 /* BGMAppUITests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
27379B8B1C7F57DA0084A24C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -806,6 +875,11 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
1CCC4F5A1E584081008053E4 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 1CB8B3351BBA75EF000E2DD1 /* Background Music */;
|
||||
targetProxy = 1CCC4F591E584081008053E4 /* PBXContainerItemProxy */;
|
||||
};
|
||||
278D71F41CABB88B00899CF9 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 27379B8E1C7F57DA0084A24C /* BGMXPCHelper */;
|
||||
|
@ -1106,6 +1180,50 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
1CCC4F5C1E584081008053E4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
INFOPLIST_FILE = "BGMAppTests/UITests/BGMAppUITests-Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.bearisdriving.BGM.AppUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_TARGET_NAME = "Background Music";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1CCC4F5D1E584081008053E4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
INFOPLIST_FILE = "BGMAppTests/UITests/BGMAppUITests-Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.bearisdriving.BGM.AppUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_TARGET_NAME = "Background Music";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
1CCC4F5E1E584081008053E4 /* DebugOpt */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
INFOPLIST_FILE = "BGMAppTests/UITests/BGMAppUITests-Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.bearisdriving.BGM.AppUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_TARGET_NAME = "Background Music";
|
||||
};
|
||||
name = DebugOpt;
|
||||
};
|
||||
27379B991C7F57DB0084A24C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -1255,6 +1373,16 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1CCC4F5B1E584081008053E4 /* Build configuration list for PBXNativeTarget "BGMAppUITests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1CCC4F5C1E584081008053E4 /* Debug */,
|
||||
1CCC4F5D1E584081008053E4 /* Release */,
|
||||
1CCC4F5E1E584081008053E4 /* DebugOpt */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
27379B981C7F57DB0084A24C /* Build configuration list for PBXNativeTarget "BGMXPCHelper" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0810"
|
||||
LastUpgradeVersion = "0820"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0810"
|
||||
LastUpgradeVersion = "0820"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -33,9 +33,9 @@
|
|||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1CB8B3481BBA75F0000E2DD1"
|
||||
BuildableName = "BGMAppTests.xctest"
|
||||
BlueprintName = "BGMAppTests"
|
||||
BlueprintIdentifier = "2743C9F51D86CFF90089613B"
|
||||
BuildableName = "BGMAppUnitTests.xctest"
|
||||
BlueprintName = "BGMAppUnitTests"
|
||||
ReferencedContainer = "container:BGMApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
|
@ -43,9 +43,9 @@
|
|||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2743C9F51D86CFF90089613B"
|
||||
BuildableName = "BGMAppUnitTests.xctest"
|
||||
BlueprintName = "BGMAppUnitTests"
|
||||
BlueprintIdentifier = "1CCC4F531E584081008053E4"
|
||||
BuildableName = "BGMAppUITests.xctest"
|
||||
BlueprintName = "BGMAppUITests"
|
||||
ReferencedContainer = "container:BGMApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
// AppDelegate.mm
|
||||
// BGMApp
|
||||
//
|
||||
// Copyright © 2016 Kyle Neideck
|
||||
// Copyright © 2016, 2017 Kyle Neideck
|
||||
//
|
||||
|
||||
// Self Includes
|
||||
|
@ -58,6 +58,11 @@ static float const kStatusBarIconPadding = 0.25;
|
|||
}
|
||||
|
||||
- (void) awakeFromNib {
|
||||
// Show BGMApp in the dock, if the command-line option for that was passed. This is used by the UI tests.
|
||||
if ([NSProcessInfo.processInfo.arguments indexOfObject:@"--show-dock-icon"] != NSNotFound) {
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
}
|
||||
|
||||
haveShownXPCHelperErrorMessage = NO;
|
||||
|
||||
// Set up the status bar item
|
||||
|
@ -94,9 +99,6 @@ static float const kStatusBarIconPadding = 0.25;
|
|||
NSBundle.mainBundle.infoDictionary[@"CFBundleVersion"]);
|
||||
|
||||
// Set up the rest of the UI and other external interfaces.
|
||||
|
||||
BGMUserDefaults* userDefaults = [BGMUserDefaults new];
|
||||
[userDefaults registerDefaults];
|
||||
|
||||
// audioDevices coordinates BGMDevice and the output device. It manages playthrough, volume/mute controls, etc.
|
||||
{
|
||||
|
@ -115,7 +117,9 @@ static float const kStatusBarIconPadding = 0.25;
|
|||
informativeText:@"You might be able to set it yourself."];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BGMUserDefaults* userDefaults = [self createUserDefaults];
|
||||
|
||||
musicPlayers = [[BGMMusicPlayers alloc] initWithAudioDevices:audioDevices
|
||||
userDefaults:userDefaults];
|
||||
|
||||
|
@ -150,6 +154,12 @@ static float const kStatusBarIconPadding = 0.25;
|
|||
self.bgmMenu.delegate = self;
|
||||
}
|
||||
|
||||
- (BGMUserDefaults*) createUserDefaults {
|
||||
BOOL persistentDefaults = [NSProcessInfo.processInfo.arguments indexOfObject:@"--no-persistent-data"] == NSNotFound;
|
||||
NSUserDefaults* wrappedDefaults = persistentDefaults ? [NSUserDefaults standardUserDefaults] : nil;
|
||||
return [[BGMUserDefaults alloc] initWithDefaults:wrappedDefaults];
|
||||
}
|
||||
|
||||
- (void) applicationWillTerminate:(NSNotification*)aNotification {
|
||||
#pragma unused (aNotification)
|
||||
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
// BGMUserDefaults.h
|
||||
// BGMApp
|
||||
//
|
||||
// Copyright © 2016 Kyle Neideck
|
||||
// Copyright © 2016, 2017 Kyle Neideck
|
||||
//
|
||||
// A simple wrapper around our use of NSUserDefaults.
|
||||
// A simple wrapper around our use of NSUserDefaults. Used to store the preferences/state that only
|
||||
// apply to BGMApp. The others are stored on BGMDriver.
|
||||
//
|
||||
|
||||
// System includes
|
||||
|
@ -30,12 +31,11 @@
|
|||
|
||||
@interface BGMUserDefaults : NSObject
|
||||
|
||||
// Register the settings defaults. These are the preferences/state that only apply to BGMApp. The others are
|
||||
// persisted on BGMDriver.
|
||||
- (void) registerDefaults;
|
||||
// If inDefaults is nil, settings are not loaded from or saved to disk, which is useful for testing.
|
||||
- (instancetype) initWithDefaults:(NSUserDefaults* __nullable)inDefaults;
|
||||
|
||||
// The musicPlayerID (see BGMMusicPlayer.h), as a string, of the music player selected by the user. Must be either
|
||||
// null or a string that can be parsed by NSUUID.
|
||||
// The musicPlayerID (see BGMMusicPlayer.h), as a string, of the music player selected by the user.
|
||||
// Must be either null or a string that can be parsed by NSUUID.
|
||||
@property NSString* __nullable selectedMusicPlayerID;
|
||||
|
||||
@property BOOL autoPauseMusicEnabled;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
// BGMUserDefaults.m
|
||||
// BGMApp
|
||||
//
|
||||
// Copyright © 2016 Kyle Neideck
|
||||
// Copyright © 2016, 2017 Kyle Neideck
|
||||
//
|
||||
|
||||
// Self include
|
||||
|
@ -30,31 +30,74 @@
|
|||
static NSString* const BGMDefaults_AutoPauseMusicEnabled = @"AutoPauseMusicEnabled";
|
||||
static NSString* const BGMDefaults_SelectedMusicPlayerID = @"SelectedMusicPlayerID";
|
||||
|
||||
@implementation BGMUserDefaults
|
||||
@implementation BGMUserDefaults {
|
||||
// The defaults object wrapped by this object.
|
||||
NSUserDefaults* defaults;
|
||||
// When we're not persisting defaults, settings are stored in this dictionary instead. This
|
||||
// var should only be accessed if 'defaults' is nil.
|
||||
NSMutableDictionary<NSString*,id>* transientDefaults;
|
||||
}
|
||||
|
||||
- (void) registerDefaults {
|
||||
// iTunes is the default music player, but we don't set BGMDefaults_SelectedMusicPlayerID here so we know when
|
||||
// it's never been set. (If it hasn't, we try using BGMDevice's kAudioDeviceCustomPropertyMusicPlayerBundleID
|
||||
// property to tell which music player should be selected. See BGMMusicPlayers.)
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ BGMDefaults_AutoPauseMusicEnabled: @YES }];
|
||||
- (instancetype) initWithDefaults:(NSUserDefaults* __nullable)inDefaults {
|
||||
if ((self = [super init])) {
|
||||
defaults = inDefaults;
|
||||
|
||||
// Register the settings defaults.
|
||||
//
|
||||
// iTunes is the default music player, but we don't set BGMDefaults_SelectedMusicPlayerID
|
||||
// here so we know when it's never been set. (If it hasn't, we try using BGMDevice's
|
||||
// kAudioDeviceCustomPropertyMusicPlayerBundleID property to tell which music player should
|
||||
// be selected. See BGMMusicPlayers.)
|
||||
NSDictionary* defaultsDict = @{ BGMDefaults_AutoPauseMusicEnabled: @YES };
|
||||
|
||||
if (defaults) {
|
||||
[defaults registerDefaults:defaultsDict];
|
||||
} else {
|
||||
transientDefaults = [defaultsDict mutableCopy];
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString* __nullable) selectedMusicPlayerID {
|
||||
return [[NSUserDefaults standardUserDefaults] stringForKey:BGMDefaults_SelectedMusicPlayerID];
|
||||
return [self get:BGMDefaults_SelectedMusicPlayerID];
|
||||
}
|
||||
|
||||
- (void) setSelectedMusicPlayerID:(NSString* __nullable)selectedMusicPlayerID {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:selectedMusicPlayerID
|
||||
forKey:BGMDefaults_SelectedMusicPlayerID];
|
||||
[self set:BGMDefaults_SelectedMusicPlayerID to:selectedMusicPlayerID];
|
||||
}
|
||||
|
||||
- (BOOL) autoPauseMusicEnabled {
|
||||
return [[NSUserDefaults standardUserDefaults] boolForKey:BGMDefaults_AutoPauseMusicEnabled];
|
||||
return [self getBool:BGMDefaults_AutoPauseMusicEnabled];
|
||||
}
|
||||
|
||||
- (void) setAutoPauseMusicEnabled:(BOOL)autoPauseMusicEnabled {
|
||||
[[NSUserDefaults standardUserDefaults] setBool:autoPauseMusicEnabled
|
||||
forKey:BGMDefaults_AutoPauseMusicEnabled];
|
||||
[self setBool:BGMDefaults_AutoPauseMusicEnabled to:autoPauseMusicEnabled];
|
||||
}
|
||||
|
||||
- (id __nullable) get:(NSString*)key {
|
||||
return defaults ? [defaults objectForKey:key] : transientDefaults[key];
|
||||
}
|
||||
|
||||
- (void) set:(NSString*)key to:(NSObject<NSCopying,NSSecureCoding>* __nullable)value {
|
||||
if (defaults) {
|
||||
[defaults setObject:value forKey:key];
|
||||
} else {
|
||||
transientDefaults[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) getBool:(NSString*)key {
|
||||
return defaults ? [defaults boolForKey:key] : [transientDefaults[key] boolValue];
|
||||
}
|
||||
|
||||
- (void) setBool:(NSString*)key to:(BOOL)value {
|
||||
if (defaults) {
|
||||
[defaults setBool:value forKey:key];
|
||||
} else {
|
||||
transientDefaults[key] = [NSNumber numberWithBool:value];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<items>
|
||||
<menuItem title="Auto-pause Music" tag="2" id="nHv-T8-1nb">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<accessibility description="Enable to automatically pause your selected music player when a different app starts playing audio." identifier="Auto-pause enabled"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="ZGd-Pq-YeA"/>
|
||||
<menuItem title="App Volumes" tag="3" enabled="NO" id="8PP-wA-Pae">
|
||||
|
@ -101,7 +102,7 @@
|
|||
</configuration>
|
||||
</ciFilter>
|
||||
</contentFilters>
|
||||
<buttonCell key="cell" type="square" title="⌃" bezelStyle="shadowlessSquare" image="F928CF85-B22A-4634-8160-BC84F45043E3" alignment="center" lineBreakMode="truncatingTail" imageScaling="proportionallyDown" inset="2" id="IXo-C7-3uE">
|
||||
<buttonCell key="cell" type="square" title="⌃" bezelStyle="shadowlessSquare" image="747DB04F-A1B8-4533-9C4F-E9A8593F7F7F" alignment="center" lineBreakMode="truncatingTail" imageScaling="proportionallyDown" inset="2" id="IXo-C7-3uE">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
|
@ -132,14 +133,14 @@
|
|||
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="Cf4-3V-gl1" customClass="NSPanel">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" utility="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" topStrut="YES"/>
|
||||
<rect key="contentRect" x="248" y="350" width="980" height="335"/>
|
||||
<rect key="contentRect" x="248" y="350" width="1002" height="335"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="HlB-hX-Y0Y">
|
||||
<rect key="frame" x="0.0" y="0.0" width="980" height="335"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="1002" height="335"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r51-dd-LGP">
|
||||
<rect key="frame" x="61" y="125" width="240" height="22"/>
|
||||
<rect key="frame" x="71" y="125" width="240" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Background Music" id="Dw2-nu-eBQ">
|
||||
<font key="font" size="18" name=".HelveticaNeueDeskInterface-Regular"/>
|
||||
|
@ -148,7 +149,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="ekc-h0-I43">
|
||||
<rect key="frame" x="61" y="100" width="240" height="17"/>
|
||||
<rect key="frame" x="71" y="100" width="240" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Version 0.1.0" id="FDH-7l-wFf">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -157,29 +158,29 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="L5P-Lw-aCd">
|
||||
<rect key="frame" x="391" y="298" width="270" height="17"/>
|
||||
<rect key="frame" x="413" y="298" width="270" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Licensed under GPLv2 or any later version." id="ETh-En-bzX">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Licensed under GPL v2 or any later version." id="ETh-En-bzX">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box horizontalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="Zc9-gs-X8C">
|
||||
<rect key="frame" x="361" y="93" width="5" height="150"/>
|
||||
<rect key="frame" x="383" y="93" width="5" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="Vy4-dv-jQB">
|
||||
<rect key="frame" x="26" y="75" width="310" height="17"/>
|
||||
<rect key="frame" x="18" y="75" width="346" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Copyright © 2016 Background Music contributors" placeholderString="" id="ctF-95-uVu">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Copyright © 2016, 2017 Background Music contributors" placeholderString="" id="ctF-95-uVu">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" tag="3" translatesAutoresizingMaskIntoConstraints="NO" id="nx6-kQ-N8Z" customClass="BGMLinkField">
|
||||
<rect key="frame" x="26" y="50" width="310" height="17"/>
|
||||
<rect key="frame" x="36" y="50" width="310" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" tag="3" title="https://github.com/kyleneideck/BackgroundMusic" placeholderString="" id="VOb-5X-o3R">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -188,7 +189,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView wantsLayer="YES" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Tui-Hf-FLv">
|
||||
<rect key="frame" x="106" y="155" width="150" height="150"/>
|
||||
<rect key="frame" x="116" y="155" width="150" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<shadow key="shadow">
|
||||
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
@ -196,7 +197,7 @@
|
|||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyUpOrDown" image="FermataIcon" id="dBU-ZS-ZzA"/>
|
||||
</imageView>
|
||||
<imageView wantsLayer="YES" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="R1R-Rd-xPC">
|
||||
<rect key="frame" x="106" y="155" width="150" height="150"/>
|
||||
<rect key="frame" x="116" y="155" width="150" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<shadow key="shadow">
|
||||
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
@ -204,7 +205,7 @@
|
|||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyUpOrDown" image="FermataIcon" id="1VP-dU-RCe"/>
|
||||
</imageView>
|
||||
<scrollView fixedFrame="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eqz-ap-PAC">
|
||||
<rect key="frame" x="393" y="45" width="567" height="245"/>
|
||||
<rect key="frame" x="415" y="45" width="567" height="245"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="Cdb-RA-YK0">
|
||||
<rect key="frame" x="1" y="1" width="565" height="243"/>
|
||||
|
@ -234,7 +235,7 @@
|
|||
</scroller>
|
||||
</scrollView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6qu-yI-r00">
|
||||
<rect key="frame" x="391" y="20" width="203" height="11"/>
|
||||
<rect key="frame" x="413" y="20" width="203" height="11"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="The AirPlay Logo is a trademark of Apple Inc." id="lx7-k3-q16">
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
|
@ -244,7 +245,7 @@
|
|||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-177" y="232.5"/>
|
||||
<point key="canvasLocation" x="-200" y="232.5"/>
|
||||
</window>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" id="IoN-sN-cCx">
|
||||
<rect key="frame" x="0.0" y="0.0" width="471" height="180"/>
|
||||
|
@ -260,7 +261,7 @@
|
|||
</textField>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="F928CF85-B22A-4634-8160-BC84F45043E3" width="1" height="1">
|
||||
<image name="747DB04F-A1B8-4533-9C4F-E9A8593F7F7F" width="1" height="1">
|
||||
<mutableData key="keyedArchiveRepresentation">
|
||||
YnBsaXN0MDDUAQIDBAUGPT5YJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK4HCBMU
|
||||
GR4fIyQrLjE3OlUkbnVsbNUJCgsMDQ4PEBESVk5TU2l6ZVYkY2xhc3NcTlNJbWFnZUZsYWdzVk5TUmVw
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 Background Music contributors</string>
|
||||
<string>Copyright © 2016, 2017 Background Music contributors</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
|
22
BGMApp/BGMAppTests/UITests/BGMAppUITests-Info.plist
Normal file
22
BGMApp/BGMAppTests/UITests/BGMAppUITests-Info.plist
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
104
BGMApp/BGMAppTests/UITests/BGMAppUITests.m
Normal file
104
BGMApp/BGMAppTests/UITests/BGMAppUITests.m
Normal file
|
@ -0,0 +1,104 @@
|
|||
// This file is part of Background Music.
|
||||
//
|
||||
// Background Music is free software: you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation, either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// Background Music is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Background Music. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//
|
||||
// BGMAppUITests.m
|
||||
// BGMAppUITests
|
||||
//
|
||||
// Copyright © 2017 Kyle Neideck
|
||||
//
|
||||
// You'll probably want to use Xcode's UI test recording feature if you add new tests.
|
||||
//
|
||||
|
||||
// Local includes
|
||||
#import "BGM_TestUtils.h"
|
||||
|
||||
|
||||
// TODO: Skip these tests if macOS SDK 10.11 or higher isn't available.
|
||||
// TODO: Mock BGMDevice and music players.
|
||||
|
||||
@interface BGMAppUITests : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation BGMAppUITests {
|
||||
// The BGMApp instance.
|
||||
XCUIApplication* app;
|
||||
|
||||
// Convenience vars.
|
||||
//
|
||||
// The menu bar icon. (Called the status bar icon in some places.)
|
||||
XCUIElement* icon;
|
||||
// The menu items in the main menu.
|
||||
XCUIElementQuery* menuItems;
|
||||
// The Preferences menu item.
|
||||
XCUIElement* prefs;
|
||||
}
|
||||
|
||||
- (void) setUp {
|
||||
[super setUp];
|
||||
|
||||
// In UI tests it is usually best to stop immediately when a failure occurs.
|
||||
self.continueAfterFailure = NO;
|
||||
|
||||
// Set up the app object and some convenience vars.
|
||||
app = [[XCUIApplication alloc] init];
|
||||
menuItems = app.menuBars.menuItems;
|
||||
icon = [app.menuBars childrenMatchingType:XCUIElementTypeMenuBarItem].element;
|
||||
prefs = menuItems[@"Preferences"];
|
||||
|
||||
// Tell BGMApp not to load/store user defaults (settings) and to use
|
||||
// NSApplicationActivationPolicyRegular. If it used the "accessory" policy as usual, the tests
|
||||
// would fail to start because of a bug in Xcode.
|
||||
app.launchArguments = @[ @"--no-persistent-data", @"--show-dock-icon" ];
|
||||
|
||||
// Launch BGMApp.
|
||||
[app launch];
|
||||
}
|
||||
|
||||
- (void) tearDown {
|
||||
// Click the quit menu item.
|
||||
if (!menuItems.count) {
|
||||
[icon click];
|
||||
}
|
||||
|
||||
[menuItems[@"Quit Background Music"] click];
|
||||
|
||||
// BGMApp should quit.
|
||||
XCTAssert(!app.exists);
|
||||
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void) testSelectMusicPlayer {
|
||||
// Select VLC as the music player.
|
||||
[icon click];
|
||||
[prefs hover];
|
||||
[prefs.menuItems[@"VLC"] click];
|
||||
|
||||
// The name of the Auto-pause menu item should change. Also check the accessibility identifier.
|
||||
[icon click];
|
||||
XCTAssertEqualObjects(menuItems[@"Auto-pause VLC"].identifier, @"Auto-pause enabled");
|
||||
|
||||
// Select iTunes as the music player.
|
||||
[prefs hover];
|
||||
[prefs.menuItems[@"iTunes"] click];
|
||||
|
||||
// The name of the Auto-pause menu item should change back.
|
||||
[icon click];
|
||||
XCTAssert(menuItems[@"Auto-pause iTunes"].exists);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0810"
|
||||
LastUpgradeVersion = "0820"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0810"
|
||||
LastUpgradeVersion = "0820"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
Loading…
Reference in a new issue