diff --git a/apple/AppStoreScreenshots/AppStoreScreenshots.swift b/apple/AppStoreScreenshots/AppStoreScreenshots.swift new file mode 100644 index 000000000..974b76e81 --- /dev/null +++ b/apple/AppStoreScreenshots/AppStoreScreenshots.swift @@ -0,0 +1,105 @@ +// +// AppStoreScreenshots.swift +// AppStoreScreenshots +// +// Created by Jackson Harper on 9/28/22. +// + +import XCTest + +// swiftlint:disable line_length +final class AppStoreScreenshots: XCTestCase { + override func setUpWithError() throws {} + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testScreenshotLibrary() throws { + let app = XCUIApplication() + setupSnapshot(app) + snapshot("Library") + } + + func testScreenshotLibraryActions() throws { + let app = XCUIApplication() + setupSnapshot(app) + + // Display the context menu of the first item in the libary + app.collectionViews.cells.firstMatch.press(forDuration: 2) + snapshot("LibraryActions") + + app.children(matching: .window).element(boundBy: 0).tap() + } + + func testScreenshotReader() throws { + let app = XCUIApplication() + setupSnapshot(app) + + // Move into the reader + app.collectionViews.cells.firstMatch.tap() + snapshot("Reader") + } + + // For this screenshot we manually set the reader position, highlight + // the text, and then run the test to take the screenshot + func testScreenshotReaderHighlight() throws { + let app = XCUIApplication() + setupSnapshot(app) + // app.collectionViews.cells.firstMatch.tap() + snapshot("ReaderHighlight") + + // let webViewsQuery = app.webViews.element.swipeUp() + } + + // For this screenshot we manually setup the audio player then run the test + func testScreenshotReaderPlayer() throws { + let app = XCUIApplication() + setupSnapshot(app) +// app.collectionViews.cells.firstMatch.tap() +// print("BUTTONS: ", app.buttons.allElementsBoundByIndex.count) +// app.buttons["Audiobook"].tap() +// +// print("MINIPLAYER BUTTONS: ", app.buttons.allElementsBoundByIndex) +// + snapshot("ReaderTTSPlayer") + + /// app.children(matching: .window).element(boundBy: 0).tap() + // XCUIApplication().buttons["Back"].tap() + } + + func testScreenshotReaderActions() throws { + let app = XCUIApplication() + setupSnapshot(app) + app.collectionViews.cells.firstMatch.tap() + app.buttons["_profile"].tap() + + snapshot("ReaderActions") + + app.children(matching: .window).element(boundBy: 0).tap() + XCUIApplication().buttons["Back"].tap() + } + + func testScreenshotSubscriptions() throws { + let app = XCUIApplication() + setupSnapshot(app) + app.navigationBars["Home"]/*@START_MENU_TOKEN@*/ .buttons["_profile"]/*[[".otherElements[\"_profile\"].buttons[\"_profile\"]",".buttons[\"_profile\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/ .tap() + app.collectionViews.buttons["Subscriptions"].tap() + + snapshot("Newsletters") + + app.navigationBars["Profile"].buttons["Home"].tap() + } + + // Manually open Safari and then run the extension and then this test + func testScreenshotExtension() throws { + let app = XCUIApplication() + setupSnapshot(app) +// app.navigationBars["Home"]/*@START_MENU_TOKEN@*/ .buttons["_profile"]/*[[".otherElements[\"_profile\"].buttons[\"_profile\"]",".buttons[\"_profile\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/ .tap() +// app.collectionViews.buttons["Subscriptions"].tap() + + snapshot("SaveExtension") + + // app.navigationBars["Profile"].buttons["Home"].tap() + } +} diff --git a/apple/AppStoreScreenshots/SnapshotHelper.swift b/apple/AppStoreScreenshots/SnapshotHelper.swift new file mode 100644 index 000000000..d0edfd942 --- /dev/null +++ b/apple/AppStoreScreenshots/SnapshotHelper.swift @@ -0,0 +1,309 @@ +// +// SnapshotHelper.swift +// Example +// +// Created by Felix Krause on 10/8/15. +// + +// ----------------------------------------------------- +// IMPORTANT: When modifying this file, make sure to +// increment the version number at the very +// bottom of the file to notify users about +// the new SnapshotHelper.swift +// ----------------------------------------------------- + +import Foundation +import XCTest + +var deviceLanguage = "" +var locale = "" + +func setupSnapshot(_ app: XCUIApplication, waitForAnimations: Bool = true) { + Snapshot.setupSnapshot(app, waitForAnimations: waitForAnimations) +} + +func snapshot(_ name: String, waitForLoadingIndicator: Bool) { + if waitForLoadingIndicator { + Snapshot.snapshot(name) + } else { + Snapshot.snapshot(name, timeWaitingForIdle: 0) + } +} + +/// - Parameters: +/// - name: The name of the snapshot +/// - timeout: Amount of seconds to wait until the network loading indicator disappears. Pass `0` if you don't want to wait. +func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval = 20) { + Snapshot.snapshot(name, timeWaitingForIdle: timeout) +} + +enum SnapshotError: Error, CustomDebugStringConvertible { + case cannotFindSimulatorHomeDirectory + case cannotRunOnPhysicalDevice + + var debugDescription: String { + switch self { + case .cannotFindSimulatorHomeDirectory: + return "Couldn't find simulator home location. Please, check SIMULATOR_HOST_HOME env variable." + case .cannotRunOnPhysicalDevice: + return "Can't use Snapshot on a physical device." + } + } +} + +@objcMembers +open class Snapshot: NSObject { + static var app: XCUIApplication? + static var waitForAnimations = true + static var cacheDirectory: URL? + static var screenshotsDirectory: URL? { + cacheDirectory?.appendingPathComponent("screenshots", isDirectory: true) + } + + open class func setupSnapshot(_ app: XCUIApplication, waitForAnimations: Bool = true) { + Snapshot.app = app + Snapshot.waitForAnimations = waitForAnimations + + do { + let cacheDir = try getCacheDirectory() + Snapshot.cacheDirectory = cacheDir + setLanguage(app) + setLocale(app) + setLaunchArguments(app) + } catch { + NSLog(error.localizedDescription) + } + } + + class func setLanguage(_ app: XCUIApplication) { + guard let cacheDirectory = self.cacheDirectory else { + NSLog("CacheDirectory is not set - probably running on a physical device?") + return + } + + let path = cacheDirectory.appendingPathComponent("language.txt") + + do { + let trimCharacterSet = CharacterSet.whitespacesAndNewlines + deviceLanguage = try String(contentsOf: path, encoding: .utf8).trimmingCharacters(in: trimCharacterSet) + app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"] + } catch { + NSLog("Couldn't detect/set language...") + } + } + + class func setLocale(_ app: XCUIApplication) { + guard let cacheDirectory = self.cacheDirectory else { + NSLog("CacheDirectory is not set - probably running on a physical device?") + return + } + + let path = cacheDirectory.appendingPathComponent("locale.txt") + + do { + let trimCharacterSet = CharacterSet.whitespacesAndNewlines + locale = try String(contentsOf: path, encoding: .utf8).trimmingCharacters(in: trimCharacterSet) + } catch { + NSLog("Couldn't detect/set locale...") + } + + if locale.isEmpty, !deviceLanguage.isEmpty { + locale = Locale(identifier: deviceLanguage).identifier + } + + if !locale.isEmpty { + app.launchArguments += ["-AppleLocale", "\"\(locale)\""] + } + } + + class func setLaunchArguments(_ app: XCUIApplication) { + guard let cacheDirectory = self.cacheDirectory else { + NSLog("CacheDirectory is not set - probably running on a physical device?") + return + } + + let path = cacheDirectory.appendingPathComponent("snapshot-launch_arguments.txt") + app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"] + + do { + let launchArguments = try String(contentsOf: path, encoding: String.Encoding.utf8) + let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: []) + let matches = regex.matches(in: launchArguments, options: [], range: NSRange(location: 0, length: launchArguments.count)) + let results = matches.map { result -> String in + (launchArguments as NSString).substring(with: result.range) + } + app.launchArguments += results + } catch { + NSLog("Couldn't detect/set launch_arguments...") + } + } + + open class func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval = 20) { + if timeout > 0 { + waitForLoadingIndicatorToDisappear(within: timeout) + } + + NSLog("snapshot: \(name)") // more information about this, check out https://docs.fastlane.tools/actions/snapshot/#how-does-it-work + + if Snapshot.waitForAnimations { + sleep(1) // Waiting for the animation to be finished (kind of) + } + + #if os(OSX) + guard let app = self.app else { + NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().") + return + } + + app.typeKey(XCUIKeyboardKeySecondaryFn, modifierFlags: []) + #else + + guard self.app != nil else { + NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().") + return + } + + let screenshot = XCUIScreen.main.screenshot() + #if os(iOS) && !targetEnvironment(macCatalyst) + let image = XCUIDevice.shared.orientation.isLandscape ? fixLandscapeOrientation(image: screenshot.image) : screenshot.image + #else + let image = screenshot.image + #endif + + guard var simulator = ProcessInfo().environment["SIMULATOR_DEVICE_NAME"], let screenshotsDir = screenshotsDirectory else { return } + + do { + // The simulator name contains "Clone X of " inside the screenshot file when running parallelized UI Tests on concurrent devices + let regex = try NSRegularExpression(pattern: "Clone [0-9]+ of ") + let range = NSRange(location: 0, length: simulator.count) + simulator = regex.stringByReplacingMatches(in: simulator, range: range, withTemplate: "") + + let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png") + print("WRITING TO PATH ", path) + #if swift(<5.0) + UIImagePNGRepresentation(image)?.write(to: path, options: .atomic) + #else + try image.pngData()?.write(to: path, options: .atomic) + #endif + } catch { + print("Problem writing screenshot: \(name) to \(screenshotsDir)/\(simulator)-\(name).png") + NSLog(error.localizedDescription) + } + #endif + } + + class func fixLandscapeOrientation(image: UIImage) -> UIImage { + #if os(watchOS) + return image + #else + if #available(iOS 10.0, *) { + let format = UIGraphicsImageRendererFormat() + format.scale = image.scale + let renderer = UIGraphicsImageRenderer(size: image.size, format: format) + return renderer.image { _ in + image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)) + } + } else { + return image + } + #endif + } + + class func waitForLoadingIndicatorToDisappear(within timeout: TimeInterval) { + #if os(tvOS) + return + #endif + + guard let app = self.app else { + NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().") + return + } + + let networkLoadingIndicator = app.otherElements.deviceStatusBars.networkLoadingIndicators.element + let networkLoadingIndicatorDisappeared = XCTNSPredicateExpectation(predicate: NSPredicate(format: "exists == false"), object: networkLoadingIndicator) + _ = XCTWaiter.wait(for: [networkLoadingIndicatorDisappeared], timeout: timeout) + } + + class func getCacheDirectory() throws -> URL { + let cachePath = "Library/Caches/tools.fastlane" + // on OSX config is stored in /Users//Library + // and on iOS/tvOS/WatchOS it's in simulator's home dir + #if os(OSX) + let homeDir = URL(fileURLWithPath: NSHomeDirectory()) + return homeDir.appendingPathComponent(cachePath) + #elseif arch(i386) || arch(x86_64) || arch(arm64) + guard let simulatorHostHome = ProcessInfo().environment["SIMULATOR_HOST_HOME"] else { + throw SnapshotError.cannotFindSimulatorHomeDirectory + } + let homeDir = URL(fileURLWithPath: simulatorHostHome) + return homeDir.appendingPathComponent(cachePath) + #else + throw SnapshotError.cannotRunOnPhysicalDevice + #endif + } +} + +private extension XCUIElementAttributes { + var isNetworkLoadingIndicator: Bool { + if hasAllowListedIdentifier { return false } + + let hasOldLoadingIndicatorSize = frame.size == CGSize(width: 10, height: 20) + let hasNewLoadingIndicatorSize = frame.size.width.isBetween(46, and: 47) && frame.size.height.isBetween(2, and: 3) + + return hasOldLoadingIndicatorSize || hasNewLoadingIndicatorSize + } + + var hasAllowListedIdentifier: Bool { + let allowListedIdentifiers = ["GeofenceLocationTrackingOn", "StandardLocationTrackingOn"] + + return allowListedIdentifiers.contains(identifier) + } + + func isStatusBar(_ deviceWidth: CGFloat) -> Bool { + if elementType == .statusBar { return true } + guard frame.origin == .zero else { return false } + + let oldStatusBarSize = CGSize(width: deviceWidth, height: 20) + let newStatusBarSize = CGSize(width: deviceWidth, height: 44) + + return [oldStatusBarSize, newStatusBarSize].contains(frame.size) + } +} + +private extension XCUIElementQuery { + var networkLoadingIndicators: XCUIElementQuery { + let isNetworkLoadingIndicator = NSPredicate { evaluatedObject, _ in + guard let element = evaluatedObject as? XCUIElementAttributes else { return false } + + return element.isNetworkLoadingIndicator + } + + return containing(isNetworkLoadingIndicator) + } + + var deviceStatusBars: XCUIElementQuery { + guard let app = Snapshot.app else { + fatalError("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().") + } + + let deviceWidth = app.windows.firstMatch.frame.width + + let isStatusBar = NSPredicate { evaluatedObject, _ in + guard let element = evaluatedObject as? XCUIElementAttributes else { return false } + + return element.isStatusBar(deviceWidth) + } + + return containing(isStatusBar) + } +} + +private extension CGFloat { + func isBetween(_ numberA: CGFloat, and numberB: CGFloat) -> Bool { + numberA ... numberB ~= self + } +} + +// Please don't remove the lines below +// They are used to detect outdated configuration files +// SnapshotHelperVersion [1.28] diff --git a/apple/Omnivore.xcodeproj/project.pbxproj b/apple/Omnivore.xcodeproj/project.pbxproj index 24594bc28..6e9cfd0ec 100644 --- a/apple/Omnivore.xcodeproj/project.pbxproj +++ b/apple/Omnivore.xcodeproj/project.pbxproj @@ -42,6 +42,8 @@ 42321E882714E6B00056429F /* styles in Resources */ = {isa = PBXBuildFile; fileRef = 42321E832714E6B00056429F /* styles */; }; 42321E892714E6B00056429F /* views in Resources */ = {isa = PBXBuildFile; fileRef = 42321E842714E6B00056429F /* views */; }; 42321E8A2714E6B00056429F /* views in Resources */ = {isa = PBXBuildFile; fileRef = 42321E842714E6B00056429F /* views */; }; + 42704E7328E6BDB000C8C73E /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42704E7228E6BDAF00C8C73E /* SnapshotHelper.swift */; }; + 42E2BFB428E458E0007F29B2 /* AppStoreScreenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42E2BFB328E458E0007F29B2 /* AppStoreScreenshots.swift */; }; 42FF1B33271154A700B38C38 /* SafariWebExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42FF1AEB271154A600B38C38 /* SafariWebExtensionHandler.swift */; }; 42FF1B34271154A700B38C38 /* SafariWebExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42FF1AEB271154A600B38C38 /* SafariWebExtensionHandler.swift */; }; 42FF1B35271154A700B38C38 /* _locales in Resources */ = {isa = PBXBuildFile; fileRef = 42FF1AED271154A600B38C38 /* _locales */; }; @@ -101,6 +103,13 @@ remoteGlobalIDString = 42FF1B1F271154A700B38C38; remoteInfo = "SafariExtension (macOS)"; }; + 42E2BFB728E458E0007F29B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = AFFD4158DD5DF9B387039311 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8260E9C026EF983F8970EC05; + remoteInfo = "Omnivore-iOS"; + }; 9DEDC1A5B4AFF9CA06136F13 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AFFD4158DD5DF9B387039311 /* Project object */; @@ -209,6 +218,9 @@ 42321E822714E6B00056429F /* scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = scripts; sourceTree = ""; }; 42321E832714E6B00056429F /* styles */ = {isa = PBXFileReference; lastKnownFileType = folder; path = styles; sourceTree = ""; }; 42321E842714E6B00056429F /* views */ = {isa = PBXFileReference; lastKnownFileType = folder; path = views; sourceTree = ""; }; + 42704E7228E6BDAF00C8C73E /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = ""; }; + 42E2BFB128E458E0007F29B2 /* AppStoreScreenshots.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AppStoreScreenshots.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 42E2BFB328E458E0007F29B2 /* AppStoreScreenshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreScreenshots.swift; sourceTree = ""; }; 42FF1AEB271154A600B38C38 /* SafariWebExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariWebExtensionHandler.swift; sourceTree = ""; }; 42FF1AED271154A600B38C38 /* _locales */ = {isa = PBXFileReference; lastKnownFileType = folder; path = _locales; sourceTree = ""; }; 42FF1AEE271154A600B38C38 /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; path = images; sourceTree = ""; }; @@ -276,6 +288,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 42E2BFAE28E458E0007F29B2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 42FF1B13271154A700B38C38 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -417,6 +436,7 @@ 0480E70B26D8A07A006CAE2F /* Omnivore-Mac.xctestplan */, 0480E70C26D8A22D006CAE2F /* Omnivore-iOS.xctestplan */, 490C83F2909A01FFE92848AF /* Project */, + 42E2BFB228E458E0007F29B2 /* AppStoreScreenshots */, E601FA26367162479B614F0F /* Products */, 4958DE83E1725D3E7A166B8E /* OmnivoreKit */, 4214F6EE2714D2260096B644 /* Frameworks */, @@ -431,6 +451,15 @@ name = Frameworks; sourceTree = ""; }; + 42E2BFB228E458E0007F29B2 /* AppStoreScreenshots */ = { + isa = PBXGroup; + children = ( + 42E2BFB328E458E0007F29B2 /* AppStoreScreenshots.swift */, + 42704E7228E6BDAF00C8C73E /* SnapshotHelper.swift */, + ); + path = AppStoreScreenshots; + sourceTree = ""; + }; 42FF1AEA271154A600B38C38 /* SafariExtension */ = { isa = PBXGroup; children = ( @@ -521,6 +550,7 @@ 42FF1B0A271154A700B38C38 /* SafariExtension.app */, 42FF1B16271154A700B38C38 /* SafariExtension.appex */, 42FF1B20271154A700B38C38 /* SafariExtension.appex */, + 42E2BFB128E458E0007F29B2 /* AppStoreScreenshots.xctest */, ); name = Products; sourceTree = ""; @@ -648,6 +678,24 @@ productReference = 95D337DDCEA2007A9705A969 /* ShareExtension.appex */; productType = "com.apple.product-type.app-extension"; }; + 42E2BFB028E458E0007F29B2 /* AppStoreScreenshots */ = { + isa = PBXNativeTarget; + buildConfigurationList = 42E2BFBB28E458E0007F29B2 /* Build configuration list for PBXNativeTarget "AppStoreScreenshots" */; + buildPhases = ( + 42E2BFAD28E458E0007F29B2 /* Sources */, + 42E2BFAE28E458E0007F29B2 /* Frameworks */, + 42E2BFAF28E458E0007F29B2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 42E2BFB828E458E0007F29B2 /* PBXTargetDependency */, + ); + name = AppStoreScreenshots; + productName = AppStoreScreenshots; + productReference = 42E2BFB128E458E0007F29B2 /* AppStoreScreenshots.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; 42FF1B15271154A700B38C38 /* SafariExtension (iOS) */ = { isa = PBXNativeTarget; buildConfigurationList = 42FF1B4F271154A700B38C38 /* Build configuration list for PBXNativeTarget "SafariExtension (iOS)" */; @@ -743,7 +791,7 @@ AFFD4158DD5DF9B387039311 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1300; + LastSwiftUpdateCheck = 1400; LastUpgradeCheck = 1300; TargetAttributes = { 0411792626A22860004AE24F = { @@ -764,6 +812,10 @@ 048ECFFB26A0B1CB00469E57 = { CreatedOnToolsVersion = 12.5; }; + 42E2BFB028E458E0007F29B2 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 8260E9C026EF983F8970EC05; + }; 42FF1B15271154A700B38C38 = { CreatedOnToolsVersion = 13.0; }; @@ -802,6 +854,7 @@ 042F48D826DFD10E00BF98FC /* UITests-iOS */, 42FF1B15271154A700B38C38 /* SafariExtension (iOS) */, 42FF1B1F271154A700B38C38 /* SafariExtension (macOS) */, + 42E2BFB028E458E0007F29B2 /* AppStoreScreenshots */, ); }; /* End PBXProject section */ @@ -845,6 +898,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 42E2BFAF28E458E0007F29B2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 42FF1B14271154A700B38C38 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1031,6 +1091,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 42E2BFAD28E458E0007F29B2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 42E2BFB428E458E0007F29B2 /* AppStoreScreenshots.swift in Sources */, + 42704E7328E6BDB000C8C73E /* SnapshotHelper.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 42FF1B12271154A700B38C38 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1104,6 +1173,11 @@ target = 42FF1B1F271154A700B38C38 /* SafariExtension (macOS) */; targetProxy = 4214F6F32714D28E0096B644 /* PBXContainerItemProxy */; }; + 42E2BFB828E458E0007F29B2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8260E9C026EF983F8970EC05 /* Omnivore-iOS */; + targetProxy = 42E2BFB728E458E0007F29B2 /* PBXContainerItemProxy */; + }; 5062BFE08129B9B110FB8AF7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = ShareExtension; @@ -1460,6 +1534,53 @@ }; name = Release; }; + 42E2BFB928E458E0007F29B2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QJF2XZ86HB; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.AppStoreScreenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "Omnivore-iOS"; + }; + name = Debug; + }; + 42E2BFBA28E458E0007F29B2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QJF2XZ86HB; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.AppStoreScreenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "Omnivore-iOS"; + }; + name = Release; + }; 42FF1B4B271154A700B38C38 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1907,6 +2028,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 42E2BFBB28E458E0007F29B2 /* Build configuration list for PBXNativeTarget "AppStoreScreenshots" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 42E2BFB928E458E0007F29B2 /* Debug */, + 42E2BFBA28E458E0007F29B2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 42FF1B4F271154A700B38C38 /* Build configuration list for PBXNativeTarget "SafariExtension (iOS)" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/apple/Omnivore.xcodeproj/xcshareddata/xcschemes/AppStoreScreenshots.xcscheme b/apple/Omnivore.xcodeproj/xcshareddata/xcschemes/AppStoreScreenshots.xcscheme new file mode 100644 index 000000000..01a2adc95 --- /dev/null +++ b/apple/Omnivore.xcodeproj/xcshareddata/xcschemes/AppStoreScreenshots.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apple/Omnivore.xcodeproj/xcshareddata/xcschemes/Omnivore-iOS.xcscheme b/apple/Omnivore.xcodeproj/xcshareddata/xcschemes/Omnivore-iOS.xcscheme index 219adbd00..597b32eaf 100644 --- a/apple/Omnivore.xcodeproj/xcshareddata/xcschemes/Omnivore-iOS.xcscheme +++ b/apple/Omnivore.xcodeproj/xcshareddata/xcschemes/Omnivore-iOS.xcscheme @@ -20,6 +20,20 @@ ReferencedContainer = "container:Omnivore.xcodeproj"> + + + + + + + +