From a00aa8651d48eb1b003e5d00c054b42fc4d64ced Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Tue, 24 Sep 2024 12:20:31 -0500 Subject: [PATCH 01/13] add winBackOffer to StoreMessageType --- Sources/Support/StoreMessageType.swift | 8 ++++++++ Tests/StoreKitUnitTests/StoreMessageTypeTests.swift | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/Sources/Support/StoreMessageType.swift b/Sources/Support/StoreMessageType.swift index d3ab8d6fe5..1eed79579e 100644 --- a/Sources/Support/StoreMessageType.swift +++ b/Sources/Support/StoreMessageType.swift @@ -25,6 +25,10 @@ import StoreKit case priceIncreaseConsent /// Generic Store messages case generic + /// Message shown when a win-back offer is purchased through the App Store + /// with Streamlined Purchasing enabled. More information can be found here: + /// https://developer.apple.com/documentation/storekit/in-app_purchase/supporting_win-back_offers_in_your_app#4480115 + case winBackOffer } #if os(iOS) || targetEnvironment(macCatalyst) || VISION_OS @@ -40,6 +44,10 @@ extension Message.Reason { case .priceIncreaseConsent: return .priceIncreaseConsent case .generic: return .generic default: + if #available(iOS 18.0, *), case .winBackOffer = self { + return .winBackOffer + } + // billingIssue message reason was added in iOS 16.4, but it's not recognized by older xcode versions. // https://developer.apple.com/documentation/xcode-release-notes/xcode-14_3-release-notes #if swift(>=5.8) diff --git a/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift b/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift index cb13031697..ace86ed516 100644 --- a/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift +++ b/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift @@ -36,6 +36,10 @@ class StoreMessagesTypeTests: TestCase { #endif expect(Message.Reason.priceIncreaseConsent.messageType) == .priceIncreaseConsent expect(Message.Reason.generic.messageType) == .generic + + if #available(iOS 18.0, *) { + expect(Message.Reason.winBackOffer.messageType) == .winBackOffer + } } } From c9e24921715e93057d14328b01f0f3f71042b4f4 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Tue, 24 Sep 2024 13:29:43 -0500 Subject: [PATCH 02/13] update docs --- Sources/Purchasing/Configuration.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Purchasing/Configuration.swift b/Sources/Purchasing/Configuration.swift index 00083bdb68..4685a062ea 100644 --- a/Sources/Purchasing/Configuration.swift +++ b/Sources/Purchasing/Configuration.swift @@ -195,8 +195,8 @@ import Foundation } /// Set `showStoreMessagesAutomatically`. Enabled by default. - /// If enabled, if the user has billing issues, has yet to accept a price increase consent or - /// there are other messages from StoreKit, they will be displayed automatically when the app is initialized. + /// If enabled, if the user has billing issues, has yet to accept a price increase consent, is eligible for a + /// win-back offer, or there are other messages from StoreKit, they will be displayed automahen the app is initialized. /// /// If you want to disable this behavior so that you can customize when these messages are shown, make sure /// you configure the SDK as early as possible in the app's lifetime, otherwise messages will be displayed From 6cd47628407fa6d6811e4d380e1d44927fe62bb3 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Tue, 1 Oct 2024 09:21:57 -0500 Subject: [PATCH 03/13] update doc --- Sources/Support/StoreMessageType.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sources/Support/StoreMessageType.swift b/Sources/Support/StoreMessageType.swift index 1eed79579e..24fe9e68af 100644 --- a/Sources/Support/StoreMessageType.swift +++ b/Sources/Support/StoreMessageType.swift @@ -25,9 +25,10 @@ import StoreKit case priceIncreaseConsent /// Generic Store messages case generic - /// Message shown when a win-back offer is purchased through the App Store - /// with Streamlined Purchasing enabled. More information can be found here: - /// https://developer.apple.com/documentation/storekit/in-app_purchase/supporting_win-back_offers_in_your_app#4480115 + /// Message shown when a subscriber is eligible to redeem a win-back offer that you've configured in App Store Connect. + /// More information can be found + /// [here](https://developer.apple.com/documentation/storekit/message/reason/4418230-winbackoffer). + /// case winBackOffer } From f12b407ae67f9559a1a1454f5465fad9684a7eac Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Tue, 1 Oct 2024 09:55:20 -0500 Subject: [PATCH 04/13] doc formatting --- Sources/Support/StoreMessageType.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Support/StoreMessageType.swift b/Sources/Support/StoreMessageType.swift index 24fe9e68af..15d45a064a 100644 --- a/Sources/Support/StoreMessageType.swift +++ b/Sources/Support/StoreMessageType.swift @@ -25,8 +25,8 @@ import StoreKit case priceIncreaseConsent /// Generic Store messages case generic - /// Message shown when a subscriber is eligible to redeem a win-back offer that you've configured in App Store Connect. - /// More information can be found + /// Message shown when a subscriber is eligible to redeem a win-back offer that you've + /// configured in App Store Connect. More information can be found /// [here](https://developer.apple.com/documentation/storekit/message/reason/4418230-winbackoffer). /// case winBackOffer From 36d2788b7a1cd536909bd0a9b8f53e11b6b5bd62 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 10:46:56 -0500 Subject: [PATCH 05/13] fix bug where we remove messages that weren't shown --- Sources/Support/StoreMessagesHelper.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sources/Support/StoreMessagesHelper.swift b/Sources/Support/StoreMessagesHelper.swift index 73df30d6f4..10f764d100 100644 --- a/Sources/Support/StoreMessagesHelper.swift +++ b/Sources/Support/StoreMessagesHelper.swift @@ -57,16 +57,20 @@ actor StoreMessagesHelper: StoreMessagesHelperType { } func showStoreMessages(types: Set) async { + var messagesToKeep: [StoreMessage] = [] for message in self.deferredMessages { if let messageType = message.reason.messageType, types.contains(messageType) { do { try await message.display(in: self.systemInfo.currentWindowScene) } catch { Logger.error(Strings.storeKit.error_displaying_store_message(error)) + messagesToKeep.append(message) } + } else { + messagesToKeep.append(message) } } - self.deferredMessages.removeAll() + self.deferredMessages = messagesToKeep } #endif From f1f454a3ef0d6e78f86c1f72fb3b12d9180fde69 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 10:47:01 -0500 Subject: [PATCH 06/13] formatting --- Sources/Support/StoreMessageType.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/Support/StoreMessageType.swift b/Sources/Support/StoreMessageType.swift index 15d45a064a..02fc36c04f 100644 --- a/Sources/Support/StoreMessageType.swift +++ b/Sources/Support/StoreMessageType.swift @@ -21,14 +21,16 @@ import StoreKit /// Message shown when there are billing issues in a subscription case billingIssue = 0 + /// Message shown when there is a price increase in a subscription that requires consent case priceIncreaseConsent + /// Generic Store messages case generic + /// Message shown when a subscriber is eligible to redeem a win-back offer that you've /// configured in App Store Connect. More information can be found /// [here](https://developer.apple.com/documentation/storekit/message/reason/4418230-winbackoffer). - /// case winBackOffer } From 246111d719dc789caa75cd3e1e6f242639d619ab Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 10:48:09 -0500 Subject: [PATCH 07/13] Revert "fix bug where we remove messages that weren't shown" This reverts commit 36d2788b7a1cd536909bd0a9b8f53e11b6b5bd62. --- Sources/Support/StoreMessagesHelper.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Sources/Support/StoreMessagesHelper.swift b/Sources/Support/StoreMessagesHelper.swift index 10f764d100..73df30d6f4 100644 --- a/Sources/Support/StoreMessagesHelper.swift +++ b/Sources/Support/StoreMessagesHelper.swift @@ -57,20 +57,16 @@ actor StoreMessagesHelper: StoreMessagesHelperType { } func showStoreMessages(types: Set) async { - var messagesToKeep: [StoreMessage] = [] for message in self.deferredMessages { if let messageType = message.reason.messageType, types.contains(messageType) { do { try await message.display(in: self.systemInfo.currentWindowScene) } catch { Logger.error(Strings.storeKit.error_displaying_store_message(error)) - messagesToKeep.append(message) } - } else { - messagesToKeep.append(message) } } - self.deferredMessages = messagesToKeep + self.deferredMessages.removeAll() } #endif From 179542fb70bb9fdebdc8cdcc29e2e3e16e809232 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 10:52:03 -0500 Subject: [PATCH 08/13] linting --- Sources/Purchasing/Configuration.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/Purchasing/Configuration.swift b/Sources/Purchasing/Configuration.swift index 4685a062ea..e456655700 100644 --- a/Sources/Purchasing/Configuration.swift +++ b/Sources/Purchasing/Configuration.swift @@ -196,7 +196,8 @@ import Foundation /// Set `showStoreMessagesAutomatically`. Enabled by default. /// If enabled, if the user has billing issues, has yet to accept a price increase consent, is eligible for a - /// win-back offer, or there are other messages from StoreKit, they will be displayed automahen the app is initialized. + /// win-back offer, or there are other messages from StoreKit, they will be displayed automahen the app is + /// initialized. /// /// If you want to disable this behavior so that you can customize when these messages are shown, make sure /// you configure the SDK as early as possible in the app's lifetime, otherwise messages will be displayed From 760b526dbd4eac36ce95ce36b7a8e90968219d40 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 10:53:56 -0500 Subject: [PATCH 09/13] typo fix --- Sources/Purchasing/Configuration.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Purchasing/Configuration.swift b/Sources/Purchasing/Configuration.swift index e456655700..826e707d77 100644 --- a/Sources/Purchasing/Configuration.swift +++ b/Sources/Purchasing/Configuration.swift @@ -196,8 +196,8 @@ import Foundation /// Set `showStoreMessagesAutomatically`. Enabled by default. /// If enabled, if the user has billing issues, has yet to accept a price increase consent, is eligible for a - /// win-back offer, or there are other messages from StoreKit, they will be displayed automahen the app is - /// initialized. + /// win-back offer, or there are other messages from StoreKit, they will be displayed automatically when + /// the app is initialized. /// /// If you want to disable this behavior so that you can customize when these messages are shown, make sure /// you configure the SDK as early as possible in the app's lifetime, otherwise messages will be displayed From 7c04579639ce329d2f9a9d4ec435e0524f6c9a78 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 11:46:59 -0500 Subject: [PATCH 10/13] add visionOS OS requirement --- Sources/Support/StoreMessageType.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Support/StoreMessageType.swift b/Sources/Support/StoreMessageType.swift index 02fc36c04f..65378d8a1a 100644 --- a/Sources/Support/StoreMessageType.swift +++ b/Sources/Support/StoreMessageType.swift @@ -47,7 +47,7 @@ extension Message.Reason { case .priceIncreaseConsent: return .priceIncreaseConsent case .generic: return .generic default: - if #available(iOS 18.0, *), case .winBackOffer = self { + if #available(iOS 18.0, visionOS 2.0, *), case .winBackOffer = self { return .winBackOffer } From d0ca973a8ad2581483c9918435f598873b0545e8 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 12:42:14 -0500 Subject: [PATCH 11/13] add Swift 6 check --- Sources/Support/StoreMessageType.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/Support/StoreMessageType.swift b/Sources/Support/StoreMessageType.swift index 65378d8a1a..246eeaca99 100644 --- a/Sources/Support/StoreMessageType.swift +++ b/Sources/Support/StoreMessageType.swift @@ -47,9 +47,13 @@ extension Message.Reason { case .priceIncreaseConsent: return .priceIncreaseConsent case .generic: return .generic default: + // winBackOffer message reason was added in iOS 18.0, but it's not recognized by xcode versions <16.0. + // https://developer.apple.com/documentation/xcode-release-notes/xcode-14_3-release-notes + #if swift(>=6.0) if #available(iOS 18.0, visionOS 2.0, *), case .winBackOffer = self { return .winBackOffer } + #endif // billingIssue message reason was added in iOS 16.4, but it's not recognized by older xcode versions. // https://developer.apple.com/documentation/xcode-release-notes/xcode-14_3-release-notes From c5ba78e6551ce176e3d93ca3604c07b9d2d40ac9 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 12:43:49 -0500 Subject: [PATCH 12/13] more checks --- Tests/StoreKitUnitTests/StoreMessageTypeTests.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift b/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift index ace86ed516..236f90d460 100644 --- a/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift +++ b/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift @@ -37,9 +37,11 @@ class StoreMessagesTypeTests: TestCase { expect(Message.Reason.priceIncreaseConsent.messageType) == .priceIncreaseConsent expect(Message.Reason.generic.messageType) == .generic - if #available(iOS 18.0, *) { + #if swift(>=6.0) + if #available(iOS 18.0, visionOS 2.0, *) { expect(Message.Reason.winBackOffer.messageType) == .winBackOffer } + #endif } } From 086dce6a8a23877eeae163aeb0a6c44033409712 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 2 Oct 2024 13:30:31 -0500 Subject: [PATCH 13/13] use compiler compilation condition --- Sources/Support/StoreMessageType.swift | 2 +- Tests/StoreKitUnitTests/StoreMessageTypeTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Support/StoreMessageType.swift b/Sources/Support/StoreMessageType.swift index 246eeaca99..cf417d1f1f 100644 --- a/Sources/Support/StoreMessageType.swift +++ b/Sources/Support/StoreMessageType.swift @@ -49,7 +49,7 @@ extension Message.Reason { default: // winBackOffer message reason was added in iOS 18.0, but it's not recognized by xcode versions <16.0. // https://developer.apple.com/documentation/xcode-release-notes/xcode-14_3-release-notes - #if swift(>=6.0) + #if compiler(>=6.0) if #available(iOS 18.0, visionOS 2.0, *), case .winBackOffer = self { return .winBackOffer } diff --git a/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift b/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift index 236f90d460..0ffefa00cc 100644 --- a/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift +++ b/Tests/StoreKitUnitTests/StoreMessageTypeTests.swift @@ -37,7 +37,7 @@ class StoreMessagesTypeTests: TestCase { expect(Message.Reason.priceIncreaseConsent.messageType) == .priceIncreaseConsent expect(Message.Reason.generic.messageType) == .generic - #if swift(>=6.0) + #if compiler(>=6.0) if #available(iOS 18.0, visionOS 2.0, *) { expect(Message.Reason.winBackOffer.messageType) == .winBackOffer }