From 401d0e7088474d2eb096549d24769983181a1bf5 Mon Sep 17 00:00:00 2001 From: Josh Heald Date: Thu, 3 Nov 2022 12:01:08 +0000 Subject: [PATCH 1/7] 8015 Add locale parameter to Jetpack requests --- .../Networking/Requests/JetpackRequest.swift | 11 ++++++++++- .../Requests/JetpackRequestTests.swift | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Networking/Networking/Requests/JetpackRequest.swift b/Networking/Networking/Requests/JetpackRequest.swift index f4c12e6b85c..21cd4d0bd4a 100644 --- a/Networking/Networking/Requests/JetpackRequest.swift +++ b/Networking/Networking/Requests/JetpackRequest.swift @@ -22,6 +22,10 @@ struct JetpackRequest: URLRequestConvertible { /// let siteID: Int64 + /// Locale identifier, simplified as `language_Region` e.g. `en_US` + /// + let locale: String? + /// Jetpack-Tunneled RPC /// let path: String @@ -40,13 +44,14 @@ struct JetpackRequest: URLRequestConvertible { /// - path: RPC that should be called. /// - parameters: Collection of Key/Value parameters, to be forwarded to the Jetpack Connected site. /// - init(wooApiVersion: WooAPIVersion, method: HTTPMethod, siteID: Int64, path: String, parameters: [String: Any]? = nil) { + init(wooApiVersion: WooAPIVersion, method: HTTPMethod, siteID: Int64, locale: String? = nil, path: String, parameters: [String: Any]? = nil) { if [.mark1, .mark2].contains(wooApiVersion) { DDLogWarn("⚠️ You are using an older version of the Woo REST API: \(wooApiVersion.rawValue), for path: \(path)") } self.wooApiVersion = wooApiVersion self.method = method self.siteID = siteID + self.locale = locale self.path = path self.parameters = parameters ?? [:] } @@ -102,6 +107,10 @@ private extension JetpackRequest { "path": jetpackPath + "&_method=" + method.rawValue.lowercased() ] + if let locale = locale { + output["locale"] = locale + } + if let jetpackQueryParams = jetpackQueryParams { output["query"] = jetpackQueryParams } diff --git a/Networking/NetworkingTests/Requests/JetpackRequestTests.swift b/Networking/NetworkingTests/Requests/JetpackRequestTests.swift index f859efcda35..c7c8bf7ea60 100644 --- a/Networking/NetworkingTests/Requests/JetpackRequestTests.swift +++ b/Networking/NetworkingTests/Requests/JetpackRequestTests.swift @@ -106,6 +106,20 @@ final class JetpackRequestTests: XCTestCase { XCTAssertEqual(output.httpMethod?.uppercased(), "POST") XCTAssertTrue(generatedBody.contains("%26_method%3Dput")) } + + /// Verifies that a JetpackRequest with `locale` encodes `&locale=fr_FR` query string parameter. + /// + func test_request_with_locale_includes_locale_parameter() { + let request = JetpackRequest(wooApiVersion: .mark3, + method: .get, + siteID: sampleSiteID, + locale: "fr_FR", + path: sampleRPC, + parameters: sampleParameters) + + let output = try! request.asURLRequest() + XCTAssertTrue((output.url?.absoluteString.contains("locale=fr_FR"))!) + } } From 4f4915ef60ad8d5dc8df512639f35365d516eb00 Mon Sep 17 00:00:00 2001 From: Josh Heald Date: Thu, 3 Nov 2022 14:06:43 +0000 Subject: [PATCH 2/7] 8015 Pass locale and JITM query in GET request --- .../Remote/JustInTimeMessagesRemote.swift | 34 +++++++- .../JustInTimeMessagesRemoteTests.swift | 77 ++++++++++++++++--- .../Stores/JustInTimeMessageStore.swift | 4 +- 3 files changed, 101 insertions(+), 14 deletions(-) diff --git a/Networking/Networking/Remote/JustInTimeMessagesRemote.swift b/Networking/Networking/Remote/JustInTimeMessagesRemote.swift index b2f475cc58c..945c955bb96 100644 --- a/Networking/Networking/Remote/JustInTimeMessagesRemote.swift +++ b/Networking/Networking/Remote/JustInTimeMessagesRemote.swift @@ -2,7 +2,9 @@ import Foundation public protocol JustInTimeMessagesRemoteProtocol { func loadAllJustInTimeMessages(for siteID: Int64, - messagePath: JustInTimeMessagesRemote.MessagePath) async -> Result<[JustInTimeMessage], Error> + messagePath: JustInTimeMessagesRemote.MessagePath, + query: [String: String?]?, + locale: String?) async -> Result<[JustInTimeMessage], Error> func dismissJustInTimeMessage(for siteID: Int64, messageID: String, featureClass: String) async -> Result @@ -18,16 +20,22 @@ public final class JustInTimeMessagesRemote: Remote, JustInTimeMessagesRemotePro /// - Parameters: /// - siteID: The site for which we'll fetch JustInTimeMessages. /// - messagePath: The location for JITMs to be displayed + /// - query: A dictionary of "query parameters" to include in the JITM request payload + /// - locale: the locale identifier (language and region only, e.g. en_US) for the current device. /// - Returns: /// Async result with an array of `[JustInTimeMessage]` (usually contains one element) or an error /// public func loadAllJustInTimeMessages(for siteID: Int64, - messagePath: JustInTimeMessagesRemote.MessagePath) async -> Result<[JustInTimeMessage], Error> { + messagePath: JustInTimeMessagesRemote.MessagePath, + query: [String: String?]?, + locale: String?) async -> Result<[JustInTimeMessage], Error> { let request = JetpackRequest(wooApiVersion: .none, method: .get, siteID: siteID, + locale: locale, path: Path.jitm, - parameters: [ParameterKey.messagePath: messagePath.requestValue]) + parameters: getParameters(messagePath: messagePath, + query: query)) let mapper = JustInTimeMessageListMapper(siteID: siteID) @@ -39,6 +47,25 @@ public final class JustInTimeMessagesRemote: Remote, JustInTimeMessagesRemotePro } } + private func getParameters(messagePath: JustInTimeMessagesRemote.MessagePath, + query: [String: String?]?) -> [String: String] { + var parameters = [ParameterKey.messagePath: messagePath.requestValue] + if let query = query, + let queryString = justInTimeMessageQuery(from: query) { + parameters[ParameterKey.query] = queryString + } + return parameters + } + + private func justInTimeMessageQuery(from parameters: [String: String?]) -> String? { + let queryItems = parameters.map { (key: String, value: String?) in + URLQueryItem(name: key, value: value) + } + var components = URLComponents() + components.queryItems = queryItems + return components.query + } + /// Dismisses a `JustInTimeMessage` using the API. /// /// - Parameters: @@ -81,6 +108,7 @@ public extension JustInTimeMessagesRemote { static let messagePath = "message_path" static let featureClass = "feature_class" static let messageID = "id" + static let query = "query" } /// Message Path parameter diff --git a/Networking/NetworkingTests/Remote/JustInTimeMessagesRemoteTests.swift b/Networking/NetworkingTests/Remote/JustInTimeMessagesRemoteTests.swift index 7db3c286ba9..240d9fa1354 100644 --- a/Networking/NetworkingTests/Remote/JustInTimeMessagesRemoteTests.swift +++ b/Networking/NetworkingTests/Remote/JustInTimeMessagesRemoteTests.swift @@ -16,11 +16,6 @@ final class JustInTimeMessagesRemoteTests: XCTestCase { network = MockNetwork() } - override func tearDown() { - network = nil - super.tearDown() - } - // MARK: - Load all Just In Time Messages tests /// Verifies that loadAllJustInTimeMessages properly parses the `just-in-time-message-list` sample response. @@ -37,7 +32,9 @@ final class JustInTimeMessagesRemoteTests: XCTestCase { messagePath: JustInTimeMessagesRemote.MessagePath( app: .wooMobile, screen: "my_store", - hook: .adminNotices)) + hook: .adminNotices), + query: nil, + locale: "en_US") // Then XCTAssert(result.isSuccess) @@ -57,7 +54,9 @@ final class JustInTimeMessagesRemoteTests: XCTestCase { messagePath: JustInTimeMessagesRemote.MessagePath( app: .wooMobile, screen: "my_store", - hook: .adminNotices)) + hook: .adminNotices), + query: nil, + locale: "en_US") // Then let request = try XCTUnwrap(network.requestsForResponseData.first as? JetpackRequest) @@ -78,7 +77,9 @@ final class JustInTimeMessagesRemoteTests: XCTestCase { messagePath: JustInTimeMessagesRemote.MessagePath( app: .wooMobile, screen: "my_store", - hook: .adminNotices)) + hook: .adminNotices), + query: nil, + locale: "en_US") // Then let justInTimeMessages = try result.get() @@ -97,7 +98,9 @@ final class JustInTimeMessagesRemoteTests: XCTestCase { messagePath: JustInTimeMessagesRemote.MessagePath( app: .wooMobile, screen: "my_store", - hook: .adminNotices)) + hook: .adminNotices), + query: nil, + locale: "en_US") // Then let request = try XCTUnwrap(network.requestsForResponseData.first as? JetpackRequest) @@ -122,11 +125,65 @@ final class JustInTimeMessagesRemoteTests: XCTestCase { messagePath: JustInTimeMessagesRemote.MessagePath( app: .wooMobile, screen: "my_store", - hook: .adminNotices)) + hook: .adminNotices), + query: nil, + locale: "en_US") // Then XCTAssertTrue(result.isFailure) let resultError = try XCTUnwrap(result.failure as? NetworkError) assertEqual(error, resultError) } + + func test_test_loadAllJustInTimeMessages_uses_passed_locale_for_request() async throws { + // Given + let remote = JustInTimeMessagesRemote(network: network) + + // When + _ = await remote.loadAllJustInTimeMessages( + for: self.sampleSiteID, + messagePath: JustInTimeMessagesRemote.MessagePath( + app: .wooMobile, + screen: "my_store", + hook: .adminNotices), + query: nil, + locale: "en_US") + + // Then + let request = try XCTUnwrap(network.requestsForResponseData.first as? JetpackRequest) + let url = try XCTUnwrap(request.urlRequest?.url) + let queryItems = try XCTUnwrap(URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems) + let locale = try XCTUnwrap(queryItems.first { $0.name == "locale" }?.value) + assertEqual("en_US", locale) + } + + func test_test_loadAllJustInTimeMessages_uses_passed_query_for_request() async throws { + // Given + let remote = JustInTimeMessagesRemote(network: network) + + // When + _ = await remote.loadAllJustInTimeMessages( + for: self.sampleSiteID, + messagePath: JustInTimeMessagesRemote.MessagePath( + app: .wooMobile, + screen: "my_store", + hook: .adminNotices), + query: [ + "platform": "ios", + "version": "11.1" + ], + locale: "en_US") + + // Then + let request = try XCTUnwrap(network.requestsForResponseData.first as? JetpackRequest) + let url = try XCTUnwrap(request.urlRequest?.url) + let queryItems = try XCTUnwrap(URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems) + let queryJson = try XCTUnwrap(queryItems.first { $0.name == "query" }?.value) + assertThat(queryJson, contains: "\"query\":") + let parameters = request.parameters + let jitmQuery = try XCTUnwrap(request.parameters["query"] as? String) + // Individually check query items because dictionaries aren't ordered + assertThat(jitmQuery, contains: "platform=ios") // platform=ios + assertThat(jitmQuery, contains: "version=11.1") // version=11.1 + } } diff --git a/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift b/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift index 3f30bb365b7..eaa6c766664 100644 --- a/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift +++ b/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift @@ -50,7 +50,9 @@ private extension JustInTimeMessageStore { for: siteID, messagePath: .init(app: .wooMobile, screen: screen, - hook: hook)) + hook: hook), + query: nil, + locale: "") let displayResult = result.map(displayMessages(_:)) await MainActor.run { completion(displayResult) From 128887fb3371f509f46ffbfa085a96df717f4b18 Mon Sep 17 00:00:00 2001 From: Josh Heald Date: Thu, 3 Nov 2022 14:45:08 +0000 Subject: [PATCH 3/7] 8015 Pass platform and build identifiers in JITM --- .../Networking.xcodeproj/project.pbxproj | 2 +- .../WooFoundation.xcodeproj/project.pbxproj | 4 ++ .../Extensions/Bundle+Woo.swift | 4 +- .../Stores/JustInTimeMessageStore.swift | 50 ++++++++++++++++++- 4 files changed, 55 insertions(+), 5 deletions(-) rename {Networking/Networking => WooFoundation/WooFoundation}/Extensions/Bundle+Woo.swift (83%) diff --git a/Networking/Networking.xcodeproj/project.pbxproj b/Networking/Networking.xcodeproj/project.pbxproj index 02acd64b376..c3bb7344379 100644 --- a/Networking/Networking.xcodeproj/project.pbxproj +++ b/Networking/Networking.xcodeproj/project.pbxproj @@ -865,7 +865,7 @@ 09885C7F27C3FFD200910A62 /* product-variations-bulk-update.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "product-variations-bulk-update.json"; sourceTree = ""; }; 09EA564A27C75FCE00407D40 /* ProductVariationsBulkUpdateMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductVariationsBulkUpdateMapper.swift; sourceTree = ""; }; 24F98C512502E79800F49B68 /* FeatureFlagsRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureFlagsRemote.swift; sourceTree = ""; }; - 24F98C532502E8DD00F49B68 /* Bundle+Woo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+Woo.swift"; sourceTree = ""; }; + 24F98C532502E8DD00F49B68 /* Bundle+Woo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Bundle+Woo.swift"; path = "../../../WooFoundation/WooFoundation/Extensions/Bundle+Woo.swift"; sourceTree = ""; }; 24F98C552502EA4800F49B68 /* FeatureFlag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureFlag.swift; sourceTree = ""; }; 24F98C572502EA8800F49B68 /* FeatureFlagMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureFlagMapper.swift; sourceTree = ""; }; 24F98C5D2502EDCF00F49B68 /* BundleWooTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleWooTests.swift; sourceTree = ""; }; diff --git a/WooFoundation/WooFoundation.xcodeproj/project.pbxproj b/WooFoundation/WooFoundation.xcodeproj/project.pbxproj index 5f429afa15b..e26c237ee73 100644 --- a/WooFoundation/WooFoundation.xcodeproj/project.pbxproj +++ b/WooFoundation/WooFoundation.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 03597A9D28F93409005E4A98 /* WooCommerceComUTMProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03597A9C28F93409005E4A98 /* WooCommerceComUTMProviderTests.swift */; }; 035BA3A6290FF98D0056F0AD /* UTMProviderProtocolExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035BA3A5290FF98D0056F0AD /* UTMProviderProtocolExtensionTests.swift */; }; 036563D728F93F8D00D84BFD /* TestKit in Frameworks */ = {isa = PBXBuildFile; productRef = 036563D628F93F8D00D84BFD /* TestKit */; }; + 03B8C3892914083F002235B1 /* Bundle+Woo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B8C3882914083F002235B1 /* Bundle+Woo.swift */; }; 265C99D828B93F04005E6117 /* ColorPalette.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 265C99D728B93F04005E6117 /* ColorPalette.xcassets */; }; 265C99DD28B941D5005E6117 /* UIColor+Muriel-Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 265C99DC28B941D5005E6117 /* UIColor+Muriel-Tests.swift */; }; 265C99DF28B94271005E6117 /* MurielColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 265C99DE28B94271005E6117 /* MurielColorTests.swift */; }; @@ -56,6 +57,7 @@ 03597A9A28F87BFC005E4A98 /* WooCommerceComUTMProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooCommerceComUTMProvider.swift; sourceTree = ""; }; 03597A9C28F93409005E4A98 /* WooCommerceComUTMProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooCommerceComUTMProviderTests.swift; sourceTree = ""; }; 035BA3A5290FF98D0056F0AD /* UTMProviderProtocolExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMProviderProtocolExtensionTests.swift; sourceTree = ""; }; + 03B8C3882914083F002235B1 /* Bundle+Woo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+Woo.swift"; sourceTree = ""; }; 265C99D728B93F04005E6117 /* ColorPalette.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ColorPalette.xcassets; sourceTree = ""; }; 265C99DC28B941D5005E6117 /* UIColor+Muriel-Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Muriel-Tests.swift"; sourceTree = ""; }; 265C99DE28B94271005E6117 /* MurielColorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MurielColorTests.swift; sourceTree = ""; }; @@ -243,6 +245,7 @@ B9C9C65F283E71F4001B879F /* Double+Woo.swift */, B9C9C658283E7195001B879F /* NSDecimalNumber+Helpers.swift */, 68FBC5B228926B2C00A05461 /* Collection+Extensions.swift */, + 03B8C3882914083F002235B1 /* Bundle+Woo.swift */, ); path = Extensions; sourceTree = ""; @@ -471,6 +474,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 03B8C3892914083F002235B1 /* Bundle+Woo.swift in Sources */, B9C9C659283E7195001B879F /* NSDecimalNumber+Helpers.swift in Sources */, 26AF1F5328B8362800937BA9 /* UIColor+SemanticColors.swift in Sources */, 03597A9B28F87BFC005E4A98 /* WooCommerceComUTMProvider.swift in Sources */, diff --git a/Networking/Networking/Extensions/Bundle+Woo.swift b/WooFoundation/WooFoundation/Extensions/Bundle+Woo.swift similarity index 83% rename from Networking/Networking/Extensions/Bundle+Woo.swift rename to WooFoundation/WooFoundation/Extensions/Bundle+Woo.swift index 3a0aad8819b..b2999893c9c 100644 --- a/Networking/Networking/Extensions/Bundle+Woo.swift +++ b/WooFoundation/WooFoundation/Extensions/Bundle+Woo.swift @@ -1,7 +1,7 @@ import Foundation extension Bundle { - var buildNumber: String { + public var buildNumber: String { guard let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String else { return "unknown" } @@ -9,7 +9,7 @@ extension Bundle { return buildNumber } - var marketingVersion: String { + public var marketingVersion: String { guard let marketingVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { return "unknown" } diff --git a/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift b/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift index eaa6c766664..d6f83916794 100644 --- a/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift +++ b/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift @@ -51,8 +51,8 @@ private extension JustInTimeMessageStore { messagePath: .init(app: .wooMobile, screen: screen, hook: hook), - query: nil, - locale: "") + query: justInTimeMessageQuery(), + locale: localeLanguageRegionIdentifier()) let displayResult = result.map(displayMessages(_:)) await MainActor.run { completion(displayResult) @@ -60,6 +60,52 @@ private extension JustInTimeMessageStore { } } + func justInTimeMessageQuery() -> [String: String] { + var queryItems = [ + "platform": "ios", + "version": Bundle.main.marketingVersion + ] + + if let device = deviceIdiomName() { + queryItems["device"] = device + } + + if let buildType = buildType() { + queryItems["build_type"] = buildType + } + + return queryItems + } + + func deviceIdiomName() -> String? { + switch UIDevice.current.userInterfaceIdiom { + case .phone: + return "phone" + case .pad: + return "pad" + default: + return nil + } + } + + func buildType() -> String? { + #if DEBUG + return "developer" + #else + return nil + #endif + } + + func localeLanguageRegionIdentifier() -> String? { + guard let languageCode = Locale.current.languageCode else { + return nil + } + guard let regionCode = Locale.current.regionCode else { + return languageCode + } + return "\(languageCode)_\(regionCode)" + } + func displayMessages(_ messages: [Networking.JustInTimeMessage]) -> [JustInTimeMessage] { return messages.map { JustInTimeMessage(message: $0) } } From bd203291f373c92349fe26a825584962db8ece0d Mon Sep 17 00:00:00 2001 From: Josh Heald Date: Thu, 3 Nov 2022 14:49:33 +0000 Subject: [PATCH 4/7] Add Just In Time Messages to 11.1 release Release notes added, feature flag set to true. --- Experiments/Experiments/DefaultFeatureFlagService.swift | 2 +- RELEASE-NOTES.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Experiments/Experiments/DefaultFeatureFlagService.swift b/Experiments/Experiments/DefaultFeatureFlagService.swift index a65c5d99c9a..a3ffb23212c 100644 --- a/Experiments/Experiments/DefaultFeatureFlagService.swift +++ b/Experiments/Experiments/DefaultFeatureFlagService.swift @@ -48,7 +48,7 @@ public struct DefaultFeatureFlagService: FeatureFlagService { case .simplifiedLoginFlowI1: return buildConfig == .localDeveloper || buildConfig == .alpha case .justInTimeMessagesOnDashboard: - return buildConfig == .localDeveloper || buildConfig == .alpha + return true case .productsOnboarding: return buildConfig == .localDeveloper || buildConfig == .alpha case .performanceMonitoring, diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 5bac2612171..9b8a7076711 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -2,7 +2,7 @@ 11.1 ----- - +- [**] Relevant Just In Time Messages will be displayed on the My Store screen [https://github.com/woocommerce/woocommerce-ios/issues/7853] 11.0 ----- From 2770591c5fac42a5af566eefb4fe0c9df66c9664 Mon Sep 17 00:00:00 2001 From: Josh Heald Date: Thu, 3 Nov 2022 17:01:55 +0000 Subject: [PATCH 5/7] 8015 Set ALPHA flag for all targets to use --- Hardware/Hardware.xcodeproj/project.pbxproj | 1 + Networking/Networking.xcodeproj/project.pbxproj | 5 +---- Storage/Storage.xcodeproj/project.pbxproj | 1 + WooFoundation/WooFoundation.xcodeproj/project.pbxproj | 1 + Yosemite/Yosemite.xcodeproj/project.pbxproj | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Hardware/Hardware.xcodeproj/project.pbxproj b/Hardware/Hardware.xcodeproj/project.pbxproj index fb48825336d..c846dda8385 100644 --- a/Hardware/Hardware.xcodeproj/project.pbxproj +++ b/Hardware/Hardware.xcodeproj/project.pbxproj @@ -1241,6 +1241,7 @@ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ALPHA; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/Networking/Networking.xcodeproj/project.pbxproj b/Networking/Networking.xcodeproj/project.pbxproj index c3bb7344379..557b4701fb3 100644 --- a/Networking/Networking.xcodeproj/project.pbxproj +++ b/Networking/Networking.xcodeproj/project.pbxproj @@ -132,7 +132,6 @@ 09EA564B27C75FCE00407D40 /* ProductVariationsBulkUpdateMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EA564A27C75FCE00407D40 /* ProductVariationsBulkUpdateMapper.swift */; }; 21DB5B99C4107CF69C0A57EC /* Pods_NetworkingTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 69314EDE650855CAF927057E /* Pods_NetworkingTests.framework */; }; 24F98C522502E79800F49B68 /* FeatureFlagsRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F98C512502E79800F49B68 /* FeatureFlagsRemote.swift */; }; - 24F98C542502E8DD00F49B68 /* Bundle+Woo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F98C532502E8DD00F49B68 /* Bundle+Woo.swift */; }; 24F98C562502EA4800F49B68 /* FeatureFlag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F98C552502EA4800F49B68 /* FeatureFlag.swift */; }; 24F98C582502EA8800F49B68 /* FeatureFlagMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F98C572502EA8800F49B68 /* FeatureFlagMapper.swift */; }; 24F98C5E2502EDCF00F49B68 /* BundleWooTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F98C5D2502EDCF00F49B68 /* BundleWooTests.swift */; }; @@ -865,7 +864,6 @@ 09885C7F27C3FFD200910A62 /* product-variations-bulk-update.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "product-variations-bulk-update.json"; sourceTree = ""; }; 09EA564A27C75FCE00407D40 /* ProductVariationsBulkUpdateMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductVariationsBulkUpdateMapper.swift; sourceTree = ""; }; 24F98C512502E79800F49B68 /* FeatureFlagsRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureFlagsRemote.swift; sourceTree = ""; }; - 24F98C532502E8DD00F49B68 /* Bundle+Woo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Bundle+Woo.swift"; path = "../../../WooFoundation/WooFoundation/Extensions/Bundle+Woo.swift"; sourceTree = ""; }; 24F98C552502EA4800F49B68 /* FeatureFlag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureFlag.swift; sourceTree = ""; }; 24F98C572502EA8800F49B68 /* FeatureFlagMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureFlagMapper.swift; sourceTree = ""; }; 24F98C5D2502EDCF00F49B68 /* BundleWooTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleWooTests.swift; sourceTree = ""; }; @@ -2346,7 +2344,6 @@ 021C7BF623863D1800A3BCBD /* Encodable+Serialization.swift */, 02BDB83423EA98C800BCC63E /* String+HTML.swift */, 57E8FED2246616AC0057CD68 /* Result+Extensions.swift */, - 24F98C532502E8DD00F49B68 /* Bundle+Woo.swift */, 265EFBDB285257950033BD33 /* Order+Fallbacks.swift */, ); path = Extensions; @@ -3011,7 +3008,6 @@ D88E229025AC990A0023F3B1 /* OrderFeeLine.swift in Sources */, 74046E1F217A6B70007DD7BF /* SiteSettingsMapper.swift in Sources */, 26B2F74524C5573F0065CCC8 /* LeaderboardListMapper.swift in Sources */, - 24F98C542502E8DD00F49B68 /* Bundle+Woo.swift in Sources */, 31D27C812602889C002EDB1D /* SitePluginsRemote.swift in Sources */, 02BE0A7B274B695F001176D2 /* WordPressMediaMapper.swift in Sources */, 45150A9A268340D2006922EA /* Country.swift in Sources */, @@ -3484,6 +3480,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.automattic.woo.Networking; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ALPHA; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "$(inherited)"; diff --git a/Storage/Storage.xcodeproj/project.pbxproj b/Storage/Storage.xcodeproj/project.pbxproj index 739d4c39d74..15d73b35f2a 100644 --- a/Storage/Storage.xcodeproj/project.pbxproj +++ b/Storage/Storage.xcodeproj/project.pbxproj @@ -1506,6 +1506,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.automattic.woo.Storage; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ALPHA; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "$(inherited)"; diff --git a/WooFoundation/WooFoundation.xcodeproj/project.pbxproj b/WooFoundation/WooFoundation.xcodeproj/project.pbxproj index e26c237ee73..2ecd09b8ac9 100644 --- a/WooFoundation/WooFoundation.xcodeproj/project.pbxproj +++ b/WooFoundation/WooFoundation.xcodeproj/project.pbxproj @@ -621,6 +621,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.automattic.woo.WooFoundationTests; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ALPHA; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/Yosemite/Yosemite.xcodeproj/project.pbxproj b/Yosemite/Yosemite.xcodeproj/project.pbxproj index 3c74ae0bbb3..ad652f6bf66 100644 --- a/Yosemite/Yosemite.xcodeproj/project.pbxproj +++ b/Yosemite/Yosemite.xcodeproj/project.pbxproj @@ -2371,6 +2371,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.automattic.Yosemite; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ALPHA; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; From a2128cbd3112fc93e92c80a555f0d7b2cc0d0af7 Mon Sep 17 00:00:00 2001 From: Josh Heald Date: Thu, 3 Nov 2022 17:38:25 +0000 Subject: [PATCH 6/7] 8015 Set build_type=developer for CI build on JITM --- Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift b/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift index d6f83916794..6ba9915b6cc 100644 --- a/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift +++ b/Yosemite/Yosemite/Stores/JustInTimeMessageStore.swift @@ -89,7 +89,7 @@ private extension JustInTimeMessageStore { } func buildType() -> String? { - #if DEBUG + #if DEBUG || ALPHA return "developer" #else return nil From 0ac84df046dafe91140e32d9f825ccfbe713b137 Mon Sep 17 00:00:00 2001 From: Josh Heald Date: Fri, 4 Nov 2022 11:46:52 +0000 Subject: [PATCH 7/7] 8015 Provide query items in priority order This adds a workaround for an apparent backend bug: only the first query item is used in the `with_query_string` rule. For that reason, we send `build_type` first, followed by `platform`, followed by alphabetical order. --- .../Remote/JustInTimeMessagesRemote.swift | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Networking/Networking/Remote/JustInTimeMessagesRemote.swift b/Networking/Networking/Remote/JustInTimeMessagesRemote.swift index 945c955bb96..4bad6351c31 100644 --- a/Networking/Networking/Remote/JustInTimeMessagesRemote.swift +++ b/Networking/Networking/Remote/JustInTimeMessagesRemote.swift @@ -62,7 +62,23 @@ public final class JustInTimeMessagesRemote: Remote, JustInTimeMessagesRemotePro URLQueryItem(name: key, value: value) } var components = URLComponents() - components.queryItems = queryItems + /// This is a workaround for a backend bug where only the first param can be used for targeting JITMs. + /// `build_type` is the most important, but absent in release builds. In release builds, `platform` is the most important + /// This can be removed when the backend bug is fixed, order should not matter here. + components.queryItems = queryItems.sorted(by: { lhs, rhs in + switch (lhs.name, rhs.name) { + case (_, "build_type"): + return false + case ("build_type", "platform"): + return true + case (_, "platform"): + return false + case ("platform", _): + return true + default: + return lhs.name < rhs.name + } + }) return components.query }