From ff61e6594677572df051b96905cc2a7a12cffd10 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Wed, 26 Jun 2024 18:17:17 +0200 Subject: [PATCH] Add ConfigureTipKit Module (#38) # Add ConfigureTipKit Module ## :recycle: Current situation & Problem This PR adds the `ConfigureTipKit` module to easily configure TipKit (or require TipKit to be configured) across the Spezi framework ecosystem. ## :gear: Release Notes * Add new `ConfigureTipKit` module. ## :books: Documentation Documentation catalog was adjusted. ## :white_check_mark: Testing Basic testing was added that calls the new code paths. ## :pencil: Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md). --- Package.swift | 56 ++++++++++++++++-- .../SpeziViews/Modules/ConfigureTipKit.swift | 57 +++++++++++++++++++ .../Resources/Localizable.xcstrings | 3 + Sources/SpeziViews/SpeziViews.docc/SPI.md | 41 +++++++++++++ .../SpeziViews/SpeziViews.docc/SpeziViews.md | 7 +++ Tests/UITests/TestApp/TestApp.swift | 14 +++++ .../PersonalInfoViewsTests.swift | 3 + .../SpeziValidation/ValidationTests.swift | 3 + .../SpeziViews/EnvironmentTests.swift | 2 + .../SpeziViews/ModelTests.swift | 6 ++ .../SpeziViews/ViewsTests.swift | 8 +++ .../UITests/UITests.xcodeproj/project.pbxproj | 25 +++++++- .../xcshareddata/xcschemes/TestApp.xcscheme | 2 +- 13 files changed, 220 insertions(+), 7 deletions(-) create mode 100644 Sources/SpeziViews/Modules/ConfigureTipKit.swift create mode 100644 Sources/SpeziViews/SpeziViews.docc/SPI.md diff --git a/Package.swift b/Package.swift index 77dd0ee..4ae2cab 100644 --- a/Package.swift +++ b/Package.swift @@ -8,9 +8,17 @@ // SPDX-License-Identifier: MIT // +import class Foundation.ProcessInfo import PackageDescription +#if swift(<6) +let swiftConcurrency: SwiftSetting = .enableExperimentalFeature("SwiftConcurrency") +#else +let swiftConcurrency: SwiftSetting = .enableUpcomingFeature("SwiftConcurrency") +#endif + + let package = Package( name: "SpeziViews", defaultLocalization: "en", @@ -27,25 +35,41 @@ let package = Package( .library(name: "SpeziValidation", targets: ["SpeziValidation"]) ], dependencies: [ + .package(url: "https://github.com/StanfordSpezi/Spezi.git", from: "1.3.0"), .package(url: "https://github.com/apple/swift-collections.git", from: "1.1.0"), .package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", from: "1.15.3") - ], + ] + swiftLintPackage(), targets: [ .target( - name: "SpeziViews" + name: "SpeziViews", + dependencies: [ + .product(name: "Spezi", package: "Spezi") + ], + swiftSettings: [ + swiftConcurrency + ], + plugins: [] + swiftLintPlugin() ), .target( name: "SpeziPersonalInfo", dependencies: [ .target(name: "SpeziViews") - ] + ], + swiftSettings: [ + swiftConcurrency + ], + plugins: [] + swiftLintPlugin() ), .target( name: "SpeziValidation", dependencies: [ .target(name: "SpeziViews"), .product(name: "OrderedCollections", package: "swift-collections") - ] + ], + swiftSettings: [ + swiftConcurrency + ], + plugins: [] + swiftLintPlugin() ), .testTarget( name: "SpeziViewsTests", @@ -53,7 +77,29 @@ let package = Package( .target(name: "SpeziViews"), .target(name: "SpeziValidation"), .product(name: "SnapshotTesting", package: "swift-snapshot-testing") - ] + ], + swiftSettings: [ + swiftConcurrency + ], + plugins: [] + swiftLintPlugin() ) ] ) + + +func swiftLintPlugin() -> [Target.PluginUsage] { + // Fully quit Xcode and open again with `open --env SPEZI_DEVELOPMENT_SWIFTLINT /Applications/Xcode.app` + if ProcessInfo.processInfo.environment["SPEZI_DEVELOPMENT_SWIFTLINT"] != nil { + [.plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLint")] + } else { + [] + } +} + +func swiftLintPackage() -> [PackageDescription.Package.Dependency] { + if ProcessInfo.processInfo.environment["SPEZI_DEVELOPMENT_SWIFTLINT"] != nil { + [.package(url: "https://github.com/realm/SwiftLint.git", .upToNextMinor(from: "0.55.1"))] + } else { + [] + } +} diff --git a/Sources/SpeziViews/Modules/ConfigureTipKit.swift b/Sources/SpeziViews/Modules/ConfigureTipKit.swift new file mode 100644 index 0000000..04fcaab --- /dev/null +++ b/Sources/SpeziViews/Modules/ConfigureTipKit.swift @@ -0,0 +1,57 @@ +// +// This source file is part of the Stanford Spezi open-source project +// +// SPDX-FileCopyrightText: 2024 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import Spezi +@_spi(TestingSupport) import SpeziFoundation +import TipKit + + +/// Configure TipKit. +/// +/// This module allows to easily and globally configure [TipKit](https://developer.apple.com/documentation/TipKit) by calling +/// [`Tips/configure(_:)`](https://developer.apple.com/documentation/tipkit/tips/configure(_:)). +/// You can use the Spezi Dependency system to require TipKit to be configured or can use the `@Environment` property wrapper in your +/// SwiftUI views to verify that TipKit was configured when using TipKit-based View components. +/// +/// - Note: The Module will automatically [`showAllTipsForTesting()`](https://developer.apple.com/documentation/tipkit/tips/showalltipsfortesting()) +/// if either the Module is initialized within a SwiftUI preview or the `testingTips` is supplied via the command line. +public class ConfigureTipKit: Module, DefaultInitializable, EnvironmentAccessible { + private let configuration: [Tips.ConfigurationOption] + + @Application(\.logger) private var logger + + + /// Configure TipKit. + /// - Parameter configuration: TipKit configuration options. + public init(_ configuration: [Tips.ConfigurationOption]) { + self.configuration = configuration + } + + /// Configure TipKit with default options. + public required convenience init() { + self.init([]) + } + + public func configure() { + if RuntimeConfig.testingTips || ProcessInfo.processInfo.isPreviewSimulator { + Tips.showAllTipsForTesting() + } + do { + try Tips.configure(configuration) + } catch { + logger.error("Failed to configure TipKit: \(error)") + } + } +} + + +extension RuntimeConfig { + /// Enable testing tips + @_spi(TestingSupport) + public static let testingTips = CommandLine.arguments.contains("--testTips") +} diff --git a/Sources/SpeziViews/Resources/Localizable.xcstrings b/Sources/SpeziViews/Resources/Localizable.xcstrings index 689ee9c..9d02275 100644 --- a/Sources/SpeziViews/Resources/Localizable.xcstrings +++ b/Sources/SpeziViews/Resources/Localizable.xcstrings @@ -16,6 +16,9 @@ } } } + }, + "Dismiss" : { + }, "Error" : { "comment" : "View State default error title", diff --git a/Sources/SpeziViews/SpeziViews.docc/SPI.md b/Sources/SpeziViews/SpeziViews.docc/SPI.md new file mode 100644 index 0000000..f624542 --- /dev/null +++ b/Sources/SpeziViews/SpeziViews.docc/SPI.md @@ -0,0 +1,41 @@ +# System Programming Interfaces + + + +An overview of System Programming Interfaces (SPIs) provided by SpeziViews. + +## Overview + +A [System Programming Interface](https://blog.eidinger.info/system-programming-interfaces-spi-in-swift-explained) is a subset of API +that is targeted only for certain users (e.g., framework developers) and might not be necessary or useful for app development. +Therefore, these interfaces are not visible by default and need to be explicitly imported. +This article provides an overview of supported SPI provided by SpeziFoundation + +### TestingSupport + +The `TestingSupport` SPI provides additional interfaces that are useful for unit and UI testing. +Annotate your import statement as follows. + +```swift +@_spi(TestingSupport) import SpeziViews +``` + +#### RuntimeConfig + +[`RuntimeConfig`](https://swiftpackageindex.com/stanfordspezi/spezifoundation/documentation/spezifoundation/spi#RuntimeConfig) is provided by +[SpeziFoundation](https://swiftpackageindex.com/stanfordspezi/spezifoundation/documentation/spezifoundation) for a central place to +provide runtime configurations. + +SpeziViews adds the following extensions: + +- `RuntimeConfig/testingTips`: Holds `true` if the `--testTips` command line flag was supplied to indicate to always show Tips when using + ``ConfigureTipKit``. + diff --git a/Sources/SpeziViews/SpeziViews.docc/SpeziViews.md b/Sources/SpeziViews/SpeziViews.docc/SpeziViews.md index 064bbeb..2f0bd5f 100644 --- a/Sources/SpeziViews/SpeziViews.docc/SpeziViews.md +++ b/Sources/SpeziViews/SpeziViews.docc/SpeziViews.md @@ -95,3 +95,10 @@ Automatically adapt your view layouts to dynamic type sizes, device orientation, - ``AnyLocalizedError`` - ``SwiftUI/EnvironmentValues/defaultErrorDescription`` + +### Modules + +- ``ConfigureTipKit`` + +### System Programming Interfaces +- diff --git a/Tests/UITests/TestApp/TestApp.swift b/Tests/UITests/TestApp/TestApp.swift index a8e1577..537869a 100644 --- a/Tests/UITests/TestApp/TestApp.swift +++ b/Tests/UITests/TestApp/TestApp.swift @@ -6,15 +6,29 @@ // SPDX-License-Identifier: MIT // +import Spezi +import SpeziViews import SwiftUI import XCTestApp +class TestDelegate: SpeziAppDelegate { + override var configuration: Configuration { + Configuration { + ConfigureTipKit() + } + } +} + + @main struct UITestsApp: App { + @ApplicationDelegateAdaptor(TestDelegate.self) private var delegate + var body: some Scene { WindowGroup { SpeziViewsTargetsTests() + .spezi(delegate) } } } diff --git a/Tests/UITests/TestAppUITests/SpeziPersonalInfo/PersonalInfoViewsTests.swift b/Tests/UITests/TestAppUITests/SpeziPersonalInfo/PersonalInfoViewsTests.swift index 6ef8c39..e49134d 100644 --- a/Tests/UITests/TestAppUITests/SpeziPersonalInfo/PersonalInfoViewsTests.swift +++ b/Tests/UITests/TestAppUITests/SpeziPersonalInfo/PersonalInfoViewsTests.swift @@ -11,6 +11,7 @@ import XCTestExtensions final class PersonalInfoViewsTests: XCTestCase { + @MainActor override func setUpWithError() throws { try super.setUpWithError() @@ -22,6 +23,7 @@ final class PersonalInfoViewsTests: XCTestCase { app.open(target: "SpeziPersonalInfo") } + @MainActor func testNameFields() throws { let app = XCUIApplication() @@ -38,6 +40,7 @@ final class PersonalInfoViewsTests: XCTestCase { XCTAssert(app.textFields["Stanford"].waitForExistence(timeout: 2)) } + @MainActor func testUserProfile() throws { let app = XCUIApplication() diff --git a/Tests/UITests/TestAppUITests/SpeziValidation/ValidationTests.swift b/Tests/UITests/TestAppUITests/SpeziValidation/ValidationTests.swift index 9b79d5c..6ddd05f 100644 --- a/Tests/UITests/TestAppUITests/SpeziValidation/ValidationTests.swift +++ b/Tests/UITests/TestAppUITests/SpeziValidation/ValidationTests.swift @@ -11,6 +11,7 @@ import XCTestExtensions final class ValidationTests: XCTestCase { + @MainActor override func setUpWithError() throws { try super.setUpWithError() @@ -22,6 +23,7 @@ final class ValidationTests: XCTestCase { app.open(target: "SpeziValidation") } + @MainActor func testDefaultRules() { let app = XCUIApplication() @@ -29,6 +31,7 @@ final class ValidationTests: XCTestCase { app.buttons["ValidationRules"].tap() } + @MainActor func testValidationWithFocus() throws { let app = XCUIApplication() diff --git a/Tests/UITests/TestAppUITests/SpeziViews/EnvironmentTests.swift b/Tests/UITests/TestAppUITests/SpeziViews/EnvironmentTests.swift index 6c84b59..d61e717 100644 --- a/Tests/UITests/TestAppUITests/SpeziViews/EnvironmentTests.swift +++ b/Tests/UITests/TestAppUITests/SpeziViews/EnvironmentTests.swift @@ -11,6 +11,7 @@ import XCTestExtensions final class EnvironmentTests: XCTestCase { + @MainActor override func setUpWithError() throws { try super.setUpWithError() @@ -22,6 +23,7 @@ final class EnvironmentTests: XCTestCase { app.open(target: "SpeziViews") } + @MainActor func testDefaultErrorDescription() throws { let app = XCUIApplication() diff --git a/Tests/UITests/TestAppUITests/SpeziViews/ModelTests.swift b/Tests/UITests/TestAppUITests/SpeziViews/ModelTests.swift index a0e1393..a338cea 100644 --- a/Tests/UITests/TestAppUITests/SpeziViews/ModelTests.swift +++ b/Tests/UITests/TestAppUITests/SpeziViews/ModelTests.swift @@ -11,6 +11,7 @@ import XCTestExtensions final class ModelTests: XCTestCase { + @MainActor override func setUpWithError() throws { try super.setUpWithError() @@ -22,6 +23,7 @@ final class ModelTests: XCTestCase { app.open(target: "SpeziViews") } + @MainActor func testViewState() throws { let app = XCUIApplication() @@ -50,6 +52,7 @@ final class ModelTests: XCTestCase { XCTAssert(app.staticTexts["View State: idle"].waitForExistence(timeout: 2)) } + @MainActor func testOperationState() throws { let app = XCUIApplication() @@ -81,6 +84,7 @@ final class ModelTests: XCTestCase { XCTAssert(content.contains("Operation State: error")) } + @MainActor func testViewStateMapper() throws { let app = XCUIApplication() @@ -117,6 +121,7 @@ final class ModelTests: XCTestCase { XCTAssert(content.contains("Operation State: error")) } + @MainActor func testConditionalModifier() throws { let app = XCUIApplication() @@ -149,6 +154,7 @@ final class ModelTests: XCTestCase { XCTAssert(app.staticTexts["Closure Condition present"].waitForExistence(timeout: 2)) } + @MainActor func testDefaultErrorDescription() throws { let app = XCUIApplication() diff --git a/Tests/UITests/TestAppUITests/SpeziViews/ViewsTests.swift b/Tests/UITests/TestAppUITests/SpeziViews/ViewsTests.swift index 8617e49..c451a49 100644 --- a/Tests/UITests/TestAppUITests/SpeziViews/ViewsTests.swift +++ b/Tests/UITests/TestAppUITests/SpeziViews/ViewsTests.swift @@ -11,6 +11,7 @@ import XCTestExtensions final class ViewsTests: XCTestCase { + @MainActor override func setUpWithError() throws { try super.setUpWithError() @@ -22,6 +23,7 @@ final class ViewsTests: XCTestCase { app.open(target: "SpeziViews") } + @MainActor func testCanvas() throws { #if !canImport(PencilKit) || os(macOS) throw XCTSkip("PencilKit is not supported on this platform") @@ -69,6 +71,7 @@ final class ViewsTests: XCTestCase { canvasView.swipeUp() } + @MainActor func testGeometryReader() throws { let app = XCUIApplication() @@ -79,6 +82,7 @@ final class ViewsTests: XCTestCase { XCTAssert(app.staticTexts["200.000000"].exists) } + @MainActor func testLabel() throws { #if os(macOS) throw XCTSkip("Label is not supported on non-UIKit platforms") @@ -96,6 +100,7 @@ final class ViewsTests: XCTestCase { XCTAssertEqual(app.staticTexts.allElementsBoundByIndex.filter { $0.label.replacingOccurrences(of: "\n", with: " ").contains(text) }.count, 2) } + @MainActor func testLazyText() throws { let app = XCUIApplication() @@ -108,6 +113,7 @@ final class ViewsTests: XCTestCase { XCTAssert(app.staticTexts["An other lazy text ..."].exists) } + @MainActor func testMarkdownView() throws { let app = XCUIApplication() @@ -121,6 +127,7 @@ final class ViewsTests: XCTestCase { XCTAssert(app.staticTexts["This is a markdown example taking 5 seconds to load."].exists) } + @MainActor func testAsyncButtonView() throws { let app = XCUIApplication() @@ -151,6 +158,7 @@ final class ViewsTests: XCTestCase { XCTAssert(app.buttons["Hello Throwing World"].isEnabled) } + @MainActor func testListRowAccessibility() throws { let app = XCUIApplication() diff --git a/Tests/UITests/UITests.xcodeproj/project.pbxproj b/Tests/UITests/UITests.xcodeproj/project.pbxproj index 32915fc..e79aba6 100644 --- a/Tests/UITests/UITests.xcodeproj/project.pbxproj +++ b/Tests/UITests/UITests.xcodeproj/project.pbxproj @@ -33,6 +33,7 @@ A99A65122AF57CA200E63582 /* FocusedValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A65112AF57CA200E63582 /* FocusedValidationTests.swift */; }; A99A65152AF5923800E63582 /* ValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A65142AF5923800E63582 /* ValidationTests.swift */; }; A9A3535B2AF60A9E00661848 /* DefaultValidationRules.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9A3535A2AF60A9E00661848 /* DefaultValidationRules.swift */; }; + A9BA82B42C29FF7C00472FF3 /* Spezi in Frameworks */ = {isa = PBXBuildFile; productRef = A9BA82B32C29FF7C00472FF3 /* Spezi */; }; A9F85B702B32A041005F16E6 /* ValidationExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F85B6F2B32A041005F16E6 /* ValidationExample.swift */; }; A9F85B722B32A052005F16E6 /* NameFieldsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F85B712B32A052005F16E6 /* NameFieldsExample.swift */; }; A9F85B742B32A05C005F16E6 /* ViewStateExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F85B732B32A05C005F16E6 /* ViewStateExample.swift */; }; @@ -93,6 +94,7 @@ buildActionMask = 2147483647; files = ( 2FA9486F29DE91A30081C086 /* SpeziViews in Frameworks */, + A9BA82B42C29FF7C00472FF3 /* Spezi in Frameworks */, A963ACB02AF4692500D745F2 /* SpeziValidation in Frameworks */, 977CF55C2AD2B92C006D9B54 /* XCTestApp in Frameworks */, A95B6E652AF4298500919504 /* SpeziPersonalInfo in Frameworks */, @@ -257,6 +259,7 @@ 977CF55B2AD2B92C006D9B54 /* XCTestApp */, A95B6E642AF4298500919504 /* SpeziPersonalInfo */, A963ACAF2AF4692500D745F2 /* SpeziValidation */, + A9BA82B32C29FF7C00472FF3 /* Spezi */, ); productName = Example; productReference = 2F6D139228F5F384007C25D6 /* TestApp.app */; @@ -291,7 +294,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1410; - LastUpgradeCheck = 1530; + LastUpgradeCheck = 1540; TargetAttributes = { 2F6D139128F5F384007C25D6 = { CreatedOnToolsVersion = 14.1; @@ -314,6 +317,7 @@ mainGroup = 2F6D138928F5F384007C25D6; packageReferences = ( 977CF55A2AD2B92C006D9B54 /* XCRemoteSwiftPackageReference "XCTestExtensions" */, + A9BA82B22C29FF7C00472FF3 /* XCRemoteSwiftPackageReference "Spezi" */, ); productRefGroup = 2F6D139328F5F384007C25D6 /* Products */; projectDirPath = ""; @@ -433,6 +437,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -454,6 +459,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_STRICT_CONCURRENCY = complete; TVOS_DEPLOYMENT_TARGET = 17.0; XROS_DEPLOYMENT_TARGET = 1.0; }; @@ -496,6 +502,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -510,6 +517,7 @@ SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_STRICT_CONCURRENCY = complete; TVOS_DEPLOYMENT_TARGET = 17.0; VALIDATE_PRODUCT = YES; XROS_DEPLOYMENT_TARGET = 1.0; @@ -671,6 +679,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -692,6 +701,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = TEST; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_STRICT_CONCURRENCY = complete; TVOS_DEPLOYMENT_TARGET = 17.0; XROS_DEPLOYMENT_TARGET = 1.0; }; @@ -800,6 +810,14 @@ minimumVersion = 0.4.9; }; }; + A9BA82B22C29FF7C00472FF3 /* XCRemoteSwiftPackageReference "Spezi" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/StanfordSpezi/Spezi.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.3.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -825,6 +843,11 @@ isa = XCSwiftPackageProductDependency; productName = SpeziValidation; }; + A9BA82B32C29FF7C00472FF3 /* Spezi */ = { + isa = XCSwiftPackageProductDependency; + package = A9BA82B22C29FF7C00472FF3 /* XCRemoteSwiftPackageReference "Spezi" */; + productName = Spezi; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 2F6D138A28F5F384007C25D6 /* Project object */; diff --git a/Tests/UITests/UITests.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme b/Tests/UITests/UITests.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme index 1bd298f..ee7cc8d 100644 --- a/Tests/UITests/UITests.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme +++ b/Tests/UITests/UITests.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme @@ -1,6 +1,6 @@