From b3955e5d8373f2378c7e48f7523a98b38d2fb555 Mon Sep 17 00:00:00 2001 From: Surik Date: Tue, 11 Jun 2024 18:49:20 +0400 Subject: [PATCH 01/25] Added fallbacks logic --- Qonversion.xcodeproj/project.pbxproj | 76 ++++++++++++++-- Sample/qonversion_fallbacks.json | 86 +++++++++++++++++++ Sources/Qonversion/Public/Qonversion.m | 5 +- .../QNProductCenterManager.h | 4 +- .../QNProductCenterManager.m | 37 ++++++-- .../QONRemoteConfigManager.h | 3 +- .../QONRemoteConfigManager.m | 35 ++++++-- .../Qonversion/Mappers/QNMapper/QNMapper.h | 10 ++- .../Qonversion/Mappers/QNMapper/QNMapper.m | 25 ++++++ .../QONFallbacksMapper/QONFallbacksMapper.h | 21 +++++ .../QONFallbacksMapper/QONFallbacksMapper.m | 53 ++++++++++++ .../QONFallbackObject/QONFallbackObject.h | 29 +++++++ .../QONFallbackObject/QONFallbackObject.m | 17 ++++ .../QONFallbacksService/QONFallbacksService.h | 21 +++++ .../QONFallbacksService/QONFallbacksService.m | 47 ++++++++++ .../Utils/NSError+Sugare/NSError+Sugare.h | 19 ++++ .../Utils/NSError+Sugare/NSError+Sugare.m | 18 ++++ 17 files changed, 478 insertions(+), 28 deletions(-) create mode 100644 Sample/qonversion_fallbacks.json create mode 100644 Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.h create mode 100644 Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m create mode 100644 Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.h create mode 100644 Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.m create mode 100644 Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.h create mode 100644 Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.m create mode 100644 Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.h create mode 100644 Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.m diff --git a/Qonversion.xcodeproj/project.pbxproj b/Qonversion.xcodeproj/project.pbxproj index 60d56502..c3e55c53 100644 --- a/Qonversion.xcodeproj/project.pbxproj +++ b/Qonversion.xcodeproj/project.pbxproj @@ -55,6 +55,14 @@ 6A95DEA529E40F2E00350BD6 /* XCTestCase+IntegrationTestsHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A95DEA429E40F2E00350BD6 /* XCTestCase+IntegrationTestsHelpers.m */; }; 6ABCBE182B99A79E003DB107 /* QONRemoteConfigLoadingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 6ABCBE162B99A79E003DB107 /* QONRemoteConfigLoadingState.h */; }; 6ABCBE192B99A79E003DB107 /* QONRemoteConfigLoadingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 6ABCBE172B99A79E003DB107 /* QONRemoteConfigLoadingState.m */; }; + 700635FB2C11C37B00BB9F9C /* QONFallbacksService.h in Headers */ = {isa = PBXBuildFile; fileRef = 700635F92C11C37B00BB9F9C /* QONFallbacksService.h */; }; + 700635FC2C11C37B00BB9F9C /* QONFallbacksService.m in Sources */ = {isa = PBXBuildFile; fileRef = 700635FA2C11C37B00BB9F9C /* QONFallbacksService.m */; }; + 700636062C11CEF700BB9F9C /* QONFallbackObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 700636042C11CEF700BB9F9C /* QONFallbackObject.h */; }; + 700636072C11CEF700BB9F9C /* QONFallbackObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 700636052C11CEF700BB9F9C /* QONFallbackObject.m */; }; + 7006360B2C11EE8400BB9F9C /* QONFallbacksMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 700636082C11EE8400BB9F9C /* QONFallbacksMapper.h */; }; + 7006360C2C11EE8400BB9F9C /* QONFallbacksMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 700636092C11EE8400BB9F9C /* QONFallbacksMapper.m */; }; + 700636142C12125900BB9F9C /* NSError+Sugare.h in Headers */ = {isa = PBXBuildFile; fileRef = 700636122C12125900BB9F9C /* NSError+Sugare.h */; }; + 700636152C12125900BB9F9C /* NSError+Sugare.m in Sources */ = {isa = PBXBuildFile; fileRef = 700636132C12125900BB9F9C /* NSError+Sugare.m */; }; 700EC173291277130032E205 /* QONExperimentGroup+Protected.h in Headers */ = {isa = PBXBuildFile; fileRef = 700EC171291277130032E205 /* QONExperimentGroup+Protected.h */; }; 701922732B10981200724926 /* QONSubscriptionPeriod.h in Headers */ = {isa = PBXBuildFile; fileRef = 701922712B10981200724926 /* QONSubscriptionPeriod.h */; settings = {ATTRIBUTES = (Public, ); }; }; 701922742B10981200724926 /* QONSubscriptionPeriod.m in Sources */ = {isa = PBXBuildFile; fileRef = 701922722B10981200724926 /* QONSubscriptionPeriod.m */; }; @@ -64,6 +72,7 @@ 70283DF729F66FAC00D138BC /* PurchasesMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70283DF629F66FAC00D138BC /* PurchasesMapper.swift */; }; 702BF8B629531A68000B6C3E /* QONScreenCustomizationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 702BF8B529531A68000B6C3E /* QONScreenCustomizationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 702DBDEC2A3216C900D590D0 /* QONExperiment+Protected.h in Headers */ = {isa = PBXBuildFile; fileRef = 702DBDEB2A3216C900D590D0 /* QONExperiment+Protected.h */; }; + 703666202C17512200B0C503 /* qonversion_fallbacks.json in Resources */ = {isa = PBXBuildFile; fileRef = 7036661F2C17512200B0C503 /* qonversion_fallbacks.json */; }; 707734F42A9F607700CFF742 /* QONRemoteConfigurationSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 707734F22A9F607700CFF742 /* QONRemoteConfigurationSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; 707734F52A9F607700CFF742 /* QONRemoteConfigurationSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 707734F32A9F607700CFF742 /* QONRemoteConfigurationSource.m */; }; 707734F72A9F6B8700CFF742 /* QONRemoteConfigurationSource+Protected.h in Headers */ = {isa = PBXBuildFile; fileRef = 707734F62A9F6B8700CFF742 /* QONRemoteConfigurationSource+Protected.h */; }; @@ -368,6 +377,14 @@ 6A95DEA429E40F2E00350BD6 /* XCTestCase+IntegrationTestsHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCTestCase+IntegrationTestsHelpers.m"; sourceTree = ""; }; 6ABCBE162B99A79E003DB107 /* QONRemoteConfigLoadingState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigLoadingState.h; sourceTree = ""; }; 6ABCBE172B99A79E003DB107 /* QONRemoteConfigLoadingState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRemoteConfigLoadingState.m; sourceTree = ""; }; + 700635F92C11C37B00BB9F9C /* QONFallbacksService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONFallbacksService.h; sourceTree = ""; }; + 700635FA2C11C37B00BB9F9C /* QONFallbacksService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONFallbacksService.m; sourceTree = ""; }; + 700636042C11CEF700BB9F9C /* QONFallbackObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONFallbackObject.h; sourceTree = ""; }; + 700636052C11CEF700BB9F9C /* QONFallbackObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONFallbackObject.m; sourceTree = ""; }; + 700636082C11EE8400BB9F9C /* QONFallbacksMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QONFallbacksMapper.h; sourceTree = ""; }; + 700636092C11EE8400BB9F9C /* QONFallbacksMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QONFallbacksMapper.m; sourceTree = ""; }; + 700636122C12125900BB9F9C /* NSError+Sugare.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+Sugare.h"; sourceTree = ""; }; + 700636132C12125900BB9F9C /* NSError+Sugare.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSError+Sugare.m"; sourceTree = ""; }; 700EC171291277130032E205 /* QONExperimentGroup+Protected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "QONExperimentGroup+Protected.h"; sourceTree = ""; }; 701922712B10981200724926 /* QONSubscriptionPeriod.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONSubscriptionPeriod.h; sourceTree = ""; }; 701922722B10981200724926 /* QONSubscriptionPeriod.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONSubscriptionPeriod.m; sourceTree = ""; }; @@ -377,6 +394,7 @@ 70283DF629F66FAC00D138BC /* PurchasesMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PurchasesMapper.swift; sourceTree = ""; }; 702BF8B529531A68000B6C3E /* QONScreenCustomizationDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONScreenCustomizationDelegate.h; sourceTree = ""; }; 702DBDEB2A3216C900D590D0 /* QONExperiment+Protected.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QONExperiment+Protected.h"; sourceTree = ""; }; + 7036661F2C17512200B0C503 /* qonversion_fallbacks.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = qonversion_fallbacks.json; sourceTree = ""; }; 7052136F29F1807A00164AAF /* PurchasesMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchasesMapper.swift; sourceTree = ""; }; 707734F22A9F607700CFF742 /* QONRemoteConfigurationSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigurationSource.h; sourceTree = ""; }; 707734F32A9F607700CFF742 /* QONRemoteConfigurationSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRemoteConfigurationSource.m; sourceTree = ""; }; @@ -623,6 +641,7 @@ 454EF63D24E5CC580070581E /* Sample */ = { isa = PBXGroup; children = ( + 7036661F2C17512200B0C503 /* qonversion_fallbacks.json */, 456215C8257D6AF800548A3D /* Sample.entitlements */, 454EF63E24E5CC580070581E /* AppDelegate.swift */, 454EF64224E5CC590070581E /* ViewController.swift */, @@ -693,7 +712,6 @@ children = ( 891DEA7E2703AF1D0079B439 /* Mappers */, 89673C2D26F49B6A008D209A /* Managers */, - 89A1931D2604B8C800C3FCD9 /* Core */, 89A192A32604973200C3FCD9 /* Services */, 456ECD35249BB67600D2BC40 /* Network */, 454BE219247C2EF7001FE771 /* Storage */, @@ -858,6 +876,42 @@ path = Helpers; sourceTree = ""; }; + 700635F82C11C36200BB9F9C /* QONFallbacksService */ = { + isa = PBXGroup; + children = ( + 700635F92C11C37B00BB9F9C /* QONFallbacksService.h */, + 700635FA2C11C37B00BB9F9C /* QONFallbacksService.m */, + ); + path = QONFallbacksService; + sourceTree = ""; + }; + 700635FD2C11C3EA00BB9F9C /* QONFallbackObject */ = { + isa = PBXGroup; + children = ( + 700636042C11CEF700BB9F9C /* QONFallbackObject.h */, + 700636052C11CEF700BB9F9C /* QONFallbackObject.m */, + ); + path = QONFallbackObject; + sourceTree = ""; + }; + 7006360A2C11EE8400BB9F9C /* QONFallbacksMapper */ = { + isa = PBXGroup; + children = ( + 700636082C11EE8400BB9F9C /* QONFallbacksMapper.h */, + 700636092C11EE8400BB9F9C /* QONFallbacksMapper.m */, + ); + path = QONFallbacksMapper; + sourceTree = ""; + }; + 7006360D2C1211F000BB9F9C /* NSError+Sugare */ = { + isa = PBXGroup; + children = ( + 700636122C12125900BB9F9C /* NSError+Sugare.h */, + 700636132C12125900BB9F9C /* NSError+Sugare.m */, + ); + path = "NSError+Sugare"; + sourceTree = ""; + }; 7023948E2923EBE8003126D5 /* QONNotificationsService */ = { isa = PBXGroup; children = ( @@ -1283,6 +1337,7 @@ 8957322526DD03A3009507A6 /* Utils */ = { isa = PBXGroup; children = ( + 7006360D2C1211F000BB9F9C /* NSError+Sugare */, 6A21BF4A2AB2018C005BDA7C /* QNRateLimiter */, 8957322626DD03A3009507A6 /* QNUtils */, 8957322926DD03A3009507A6 /* QNDevice */, @@ -1331,6 +1386,7 @@ 8957323226DD03A3009507A6 /* Models */ = { isa = PBXGroup; children = ( + 700635FD2C11C3EA00BB9F9C /* QONFallbackObject */, 8957323726DD03A3009507A6 /* QNMapperObject */, 8957323F26DD03A3009507A6 /* Protected */, ); @@ -1387,6 +1443,7 @@ 8957325126DD03A3009507A6 /* Mappers */ = { isa = PBXGroup; children = ( + 7006360A2C11EE8400BB9F9C /* QONFallbacksMapper */, 7098564A2A370F190023DFAB /* QONRemoteConfigMapper */, 8957325226DD03A3009507A6 /* QNUserInfoMapper */, 8957325626DD03A3009507A6 /* QNErrorsMapper */, @@ -1476,6 +1533,7 @@ 8957326A26DD03A3009507A6 /* Services */ = { isa = PBXGroup; children = ( + 700635F82C11C36200BB9F9C /* QONFallbacksService */, 70D05A9029C9FF2C00EA5DDF /* QONRemoteConfigService */, 8957326B26DD03A3009507A6 /* QNStoreKitService */, 8957326E26DD03A3009507A6 /* QNAPIClient */, @@ -1550,13 +1608,6 @@ path = Services; sourceTree = ""; }; - 89A1931D2604B8C800C3FCD9 /* Core */ = { - isa = PBXGroup; - children = ( - ); - path = Core; - sourceTree = ""; - }; A18393DDB513BB32EFB466E9 /* QONExceptionManager */ = { isa = PBXGroup; children = ( @@ -1640,6 +1691,7 @@ 70D0E2BB291AA21C004E8DE8 /* QONLaunchMode.h in Headers */, 895732D026DD03A3009507A6 /* QNUserInfo.h in Headers */, 895732B126DD03A3009507A6 /* QONAutomationsFlowAssembly.h in Headers */, + 700636142C12125900BB9F9C /* NSError+Sugare.h in Headers */, 6A21BF532AB2059F005BDA7C /* QONRequest.h in Headers */, 8957329026DD03A3009507A6 /* QONEntitlementsUpdateListener.h in Headers */, 8957329326DD03A3009507A6 /* QONExperimentGroup.h in Headers */, @@ -1671,10 +1723,13 @@ 7097C6BE2A38BFC800565DE4 /* QONRemoteConfig+Protected.h in Headers */, 895732DF26DD03A3009507A6 /* QONUser+Protected.h in Headers */, 70ED951029FAAF31005F5D00 /* QONStoreKit2PurchaseModel.h in Headers */, + 7006360B2C11EE8400BB9F9C /* QONFallbacksMapper.h in Headers */, 8957329126DD03A3009507A6 /* QONAutomations.h in Headers */, 895732ED26DD03A3009507A6 /* QNUserInfoMapper.h in Headers */, 701922762B10AB3300724926 /* QONSubscriptionPeriod+Protected.h in Headers */, + 700635FB2C11C37B00BB9F9C /* QONFallbacksService.h in Headers */, 70ADE70F2951CC7200CB4D2E /* QONScreenPresentationConfiguration.h in Headers */, + 700636062C11CEF700BB9F9C /* QONFallbackObject.h in Headers */, 8957327C26DD03A3009507A6 /* QONAutomationsDelegate.h in Headers */, 8957330126DD03A3009507A6 /* QNUserInfoServiceInterface.h in Headers */, 895732C926DD03A3009507A6 /* QNInternalConstants.h in Headers */, @@ -1843,6 +1898,7 @@ 454EF64B24E5CC5A0070581E /* LaunchScreen.storyboard in Resources */, 894278822759334D00A8A6EC /* GoogleService-Info.plist in Resources */, 454EF64824E5CC5A0070581E /* Assets.xcassets in Resources */, + 703666202C17512200B0C503 /* qonversion_fallbacks.json in Resources */, 454EF64624E5CC590070581E /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2017,8 +2073,10 @@ 895732CB26DD03A3009507A6 /* QNUtils.m in Sources */, 70ADE7102951CC7200CB4D2E /* QONScreenPresentationConfiguration.m in Sources */, 707734F52A9F607700CFF742 /* QONRemoteConfigurationSource.m in Sources */, + 7006360C2C11EE8400BB9F9C /* QONFallbacksMapper.m in Sources */, 6A21BF4E2AB20483005BDA7C /* QONRateLimiter.m in Sources */, 895732A626DD03A3009507A6 /* QONAutomationsScreen.m in Sources */, + 700636072C11CEF700BB9F9C /* QONFallbackObject.m in Sources */, 70ED951129FAAF31005F5D00 /* QONStoreKit2PurchaseModel.m in Sources */, 70EC019D29EEE94300E686E2 /* StoreKit2Service.swift in Sources */, 701922742B10981200724926 /* QONSubscriptionPeriod.m in Sources */, @@ -2040,6 +2098,8 @@ 895732FC26DD03A3009507A6 /* QNStoreKitService.m in Sources */, 895732FA26DD03A3009507A6 /* QNIdentityManager.m in Sources */, 8957330026DD03A3009507A6 /* QNUserInfoService.m in Sources */, + 700636152C12125900BB9F9C /* NSError+Sugare.m in Sources */, + 700635FC2C11C37B00BB9F9C /* QONFallbacksService.m in Sources */, 7098564E2A370F270023DFAB /* QONRemoteConfigMapper.m in Sources */, 895732AC26DD03A3009507A6 /* QONAutomationsFlowCoordinator.m in Sources */, 8957328326DD03A3009507A6 /* QONExperimentGroup.m in Sources */, diff --git a/Sample/qonversion_fallbacks.json b/Sample/qonversion_fallbacks.json new file mode 100644 index 00000000..0735fd54 --- /dev/null +++ b/Sample/qonversion_fallbacks.json @@ -0,0 +1,86 @@ +{ + "timestamp": 1586369519, + "products": [ + { + "duration": 4, + "id": "annual", + "store_id": "io.qonversion.subs.annual", + "type": 0 + }, + { + "duration": 1, + "id": "subs_plus_trial", + "store_id": "io.qonversion.subs.monthly.plus.trial", + "type": 0 + }, + { + "duration": 0, + "id": "weekly", + "store_id": "io.qonversion.weekly", + "type": 1 + } + ], + "offerings": [ + { + "id": "main", + "products": [ + { + "duration": 0, + "id": "weekly", + "store_id": "io.qonversion.weekly", + "type": 1 + }, + { + "duration": 4, + "id": "annual", + "store_id": "io.qonversion.subs.annual", + "type": 0 + }, + { + "duration": "", + "id": "consumable", + "store_id": "io.qonversion.consumable", + "type": 2 + } + ], + "tag": 1 + }, + { + "id": "discounted_offer", + "products": [], + "tag": 0 + } + ], + "products_permissions": { + "annual": [ + "standart", + "sample" + ], + "annual": [ + "standart" + ], + "subs_plus_trial": [ + "standart" + ], + "weekly": [ + "plus" + ] + }, + "remote_config": { + "experiment": "", + "payload": { + "CTA": "Start you trial", + "CTA_color": "red", + "main_image": 111, + "product_id": 123123123123123, + "show_close_button": 1 + }, + "source": { + "assignment_type": "auto", + "context_key": "", + "name": "Default settings", + "type": "remote_configuration", + "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" + } + } +} diff --git a/Sources/Qonversion/Public/Qonversion.m b/Sources/Qonversion/Public/Qonversion.m index 4334bd68..6560a302 100644 --- a/Sources/Qonversion/Public/Qonversion.m +++ b/Sources/Qonversion/Public/Qonversion.m @@ -14,6 +14,7 @@ #import "QONRemoteConfigManager.h" #import "QONExceptionManager.h" #import "QONUserProperty.h" +#import "QONFallbacksService.h" static id shared = nil; @@ -249,8 +250,8 @@ - (instancetype)initWithCustomUserDefaults:(NSUserDefaults *)userDefaults { _userInfoService = [servicesAssembly userInfoService]; _localStorage = [servicesAssembly localStorage]; id identityManager = [servicesAssembly identityManager]; - - _productCenterManager = [[QNProductCenterManager alloc] initWithUserInfoService:_userInfoService identityManager:identityManager localStorage:_localStorage]; + QONFallbacksService *fallbacksService = [QONFallbacksService new]; + _productCenterManager = [[QNProductCenterManager alloc] initWithUserInfoService:_userInfoService identityManager:identityManager localStorage:_localStorage fallbacksService:fallbacksService]; _propertiesManager = [QNUserPropertiesManager new]; _attributionManager = [QNAttributionManager new]; _remoteConfigManager = [QONRemoteConfigManager new]; diff --git a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.h b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.h index d9743450..f9c72d07 100644 --- a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.h +++ b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.h @@ -4,7 +4,7 @@ #import "QONLaunchMode.h" #import "QONRemoteConfigManager.h" -@class QONLaunchResult, QONStoreKit2PurchaseModel; +@class QONLaunchResult, QONStoreKit2PurchaseModel, QONFallbacksService; @protocol QONPromoPurchasesDelegate, QONEntitlementsUpdateListener, QNUserInfoServiceInterface, QNIdentityManagerInterface, QNLocalStorage; NS_ASSUME_NONNULL_BEGIN @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) QONLaunchMode launchMode; @property (nonatomic, strong) QONRemoteConfigManager *remoteConfigManager; -- (instancetype)initWithUserInfoService:(id)userInfoService identityManager:(id)identityManager localStorage:(id)localStorage; +- (instancetype)initWithUserInfoService:(id)userInfoService identityManager:(id)identityManager localStorage:(id)localStorage fallbacksService:(QONFallbacksService *)fallbacksService; - (BOOL)isUserStable; - (void)identify:(NSString *)userID completion:(nullable QONUserInfoCompletionHandler)completion; diff --git a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m index e97bb882..b6a45f96 100644 --- a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m +++ b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m @@ -19,6 +19,8 @@ #import "QNInternalConstants.h" #import "QONUser+Protected.h" #import "QONStoreKit2PurchaseModel.h" +#import "QONFallbacksService.h" +#import "QONFallbackObject.h" #if TARGET_OS_IOS #import "QONAutomations.h" @@ -37,6 +39,8 @@ @interface QNProductCenterManager() @property (nonatomic, strong) id persistentStorage; @property (nonatomic, strong) id identityManager; @property (nonatomic, strong) id userInfoService; +@property (nonatomic, strong) QONFallbacksService *fallbacksService; +@property (nonatomic, strong) QONFallbackObject *fallbackData; @property (nonatomic, copy) NSArray *restoredTransactions; @@ -68,7 +72,7 @@ @interface QNProductCenterManager() @implementation QNProductCenterManager -- (instancetype)initWithUserInfoService:(id)userInfoService identityManager:(id)identityManager localStorage:(id)localStorage { +- (instancetype)initWithUserInfoService:(id)userInfoService identityManager:(id)identityManager localStorage:(id)localStorage fallbacksService:(QONFallbacksService *)fallbacksService { self = super.init; if (self) { _launchingFinished = NO; @@ -76,6 +80,7 @@ - (instancetype)initWithUserInfoService:(id)userInfo _launchError = nil; _launchResult = nil; _cacheLifetime = QONEntitlementsCacheLifetimeMonth; + _fallbacksService = fallbacksService; #if TARGET_OS_IOS [QONAutomations sharedInstance]; @@ -152,6 +157,11 @@ - (NSTimeInterval)cachedLaunchResultTimeStamp { if (self.launchError) { QONLaunchResult *cachedResult = [self cachedLaunchResult]; products = cachedResult ? cachedResult.products : products; + + if (products.allValues.count == 0) { + self.fallbackData = self.fallbackData ?: [self.fallbacksService obtainFallbackData]; + products = self.fallbackData.products; + } } return products; @@ -163,6 +173,11 @@ - (QONOfferings * _Nullable)getActualOfferings { if (self.launchError) { QONLaunchResult *cachedResult = [self cachedLaunchResult]; offerings = cachedResult ? cachedResult.offerings : offerings; + + if (!offerings) { + self.fallbackData = self.fallbackData ?: [self.fallbacksService obtainFallbackData]; + offerings = self.fallbackData.offerings; + } } return offerings; @@ -349,8 +364,8 @@ - (void)purchase:(NSString *)productID offeringID:(NSString *)offeringID complet if (self.launchError) { __block __weak QNProductCenterManager *weakSelf = self; [self launchWithCompletion:^(QONLaunchResult * _Nonnull result, NSError * _Nullable error) { - QONLaunchResult *cachedResult = [weakSelf cachedLaunchResult]; - if (error && !cachedResult) { + NSDictionary *products = [weakSelf getActualProducts]; + if (error && products.count == 0) { run_block_on_main(completion, @{}, error, NO); return; } @@ -602,9 +617,9 @@ - (void)executeProductsBlocksWithError:(NSError * _Nullable)error { if (self.launchError) { // check if the cache is actual, set the products, and reset the error - QONLaunchResult *cachedResult = [self cachedLaunchResult]; - products = cachedResult ? cachedResult.products.allValues : products; - resultError = cachedResult ? nil : self.launchError; + NSDictionary *actualProducts = [self getActualProducts]; + products = actualProducts.allValues.count > 0 ? actualProducts.allValues : products; + resultError = actualProducts.count > 0 ? nil : self.launchError; } NSDictionary *resultProducts = [self enrichProductsWithStoreProducts:products]; @@ -1103,8 +1118,8 @@ - (void)handlePurchaseResult:(NSDictionary *)resul } NSMutableDictionary *qonversionProductsMap = [NSMutableDictionary new]; - QONLaunchResult *launchResult = self.launchError ? [self cachedLaunchResult] : self.launchResult; - for (QONProduct *value in launchResult.products.allValues) { + NSDictionary *qonversionProducts = self.launchError ? [self getActualProducts] : self.launchResult.products; + for (QONProduct *value in qonversionProducts.allValues) { if (value.storeID.length > 0) { qonversionProductsMap[value.storeID] = value; } @@ -1161,6 +1176,11 @@ - (void)handlePurchaseResult:(NSDictionary *)resul NSMutableDictionary *resultEntitlements = [NSMutableDictionary new]; QONProduct *qonversionProduct = productsMap[transaction.payment.productIdentifier]; + + if (self.productsEntitlementsRelation.count == 0) { + QONFallbackObject *fallbackData = [self.fallbacksService obtainFallbackData]; + self.productsEntitlementsRelation = fallbackData.productsEntitlementsRelation; + } NSArray *entitlementsIds = self.productsEntitlementsRelation[qonversionProduct.qonversionID]; for (NSString *entitlementId in entitlementsIds) { @@ -1184,6 +1204,7 @@ - (QONEntitlement *)createEntitlementsForId:(NSString *)entitlementId entitlement.productID = qonversionProduct.qonversionID; entitlement.startedDate = transaction.transactionDate; entitlement.expirationDate = expirationDate; + entitlement.transactions = @[]; return entitlement; } diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.h b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.h index 95d64d2a..6121b709 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.h +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.h @@ -10,13 +10,14 @@ #import "QONLaunchResult.h" #import "QONExperiment.h" -@class QONRemoteConfigService, QNProductCenterManager, QNUserPropertiesManager; +@class QONRemoteConfigService, QNProductCenterManager, QNUserPropertiesManager, QONFallbacksService; NS_ASSUME_NONNULL_BEGIN @interface QONRemoteConfigManager : NSObject @property (nonatomic, strong) QONRemoteConfigService *remoteConfigService; +@property (nonatomic, strong) QONFallbacksService *fallbacksService; @property (nonatomic, strong) QNProductCenterManager *productCenterManager; @property (nonatomic, strong) QNUserPropertiesManager *userPropertiesManager; diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 220407eb..2af29b57 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -15,6 +15,9 @@ #import "QONRemoteConfigLoadingState.h" #import "QONRemoteConfigListRequestData.h" #import "QNUserPropertiesManager.h" +#import "QONFallbacksService.h" +#import "NSError+Sugare.h" +#import "QONFallbackObject.h" static NSString *const kEmptyContextKey = @""; @@ -22,6 +25,7 @@ @interface QONRemoteConfigManager () @property (nonatomic, strong) NSMutableDictionary *loadingStates; @property (nonatomic, strong) NSMutableArray *listRequests; +@property (nonatomic, strong) QONFallbackObject *fallbackData; @end @@ -34,6 +38,7 @@ - (instancetype)init { _remoteConfigService = [QONRemoteConfigService new]; _loadingStates = [NSMutableDictionary new]; _listRequests = [NSMutableArray new]; + _fallbacksService = [QONFallbacksService new]; } return self; @@ -99,18 +104,36 @@ - (void)obtainRemoteConfigWithContextKey:(NSString * _Nullable)contextKey comple [weakSelf.remoteConfigService loadRemoteConfig:contextKey completion:^(QONRemoteConfig * _Nullable remoteConfig, NSError * _Nullable error) { loadingState.isInProgress = NO; if (error) { - [weakSelf executeRemoteConfigCompletionsWithContextKey:contextKey remoteConfig:nil error:error]; - completion(nil, error); - return; + if (error.shouldFireFallback) { + weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbacksService obtainFallbackData]; + if (weakSelf.fallbackData.remoteConfig) { + [weakSelf fireRemoteConfig:weakSelf.fallbackData.remoteConfig contextKey:contextKey loadingState:loadingState error:nil completion:completion]; + } else { + [weakSelf fireRemoteConfig:nil contextKey:contextKey loadingState:loadingState error:error completion:completion]; + return; + } + } else { + [weakSelf fireRemoteConfig:nil contextKey:contextKey loadingState:loadingState error:error completion:completion]; + return; + } } - loadingState.loadedConfig = remoteConfig; - [weakSelf executeRemoteConfigCompletionsWithContextKey:contextKey remoteConfig:remoteConfig error:nil]; - completion(remoteConfig, nil); + [weakSelf fireRemoteConfig:remoteConfig contextKey:contextKey loadingState:loadingState error:nil completion:completion]; }]; }]; } +- (void)fireRemoteConfig:(QONRemoteConfig *)remoteConfig contextKey:(NSString *)contextKey loadingState:(QONRemoteConfigLoadingState *)loadingState error:(NSError *)error completion:(QONRemoteConfigCompletionHandler)completion { + if (error) { + [self executeRemoteConfigCompletionsWithContextKey:contextKey remoteConfig:nil error:error]; + completion(nil, error); + } else { + loadingState.loadedConfig = remoteConfig; + [self executeRemoteConfigCompletionsWithContextKey:contextKey remoteConfig:remoteConfig error:nil]; + completion(remoteConfig, nil); + } +} + - (void)obtainRemoteConfigListWithContextKeys:(NSArray *)contextKeys includeEmptyContextKey:(BOOL)includeEmptyContextKey completion:(QONRemoteConfigListCompletionHandler)completion { NSMutableArray *allKeys = [contextKeys mutableCopy]; if (includeEmptyContextKey) { diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h index e4b2b2d1..509c3322 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h @@ -1,6 +1,6 @@ #import -@class QNMapperObject, QONLaunchResult, QONEntitlement, QONIntroEligibility, QONUser; +@class QNMapperObject, QONLaunchResult, QONEntitlement, QONIntroEligibility, QONUser, QONFallbackObject, QONOfferings; @interface QNMapper : NSObject @@ -16,4 +16,12 @@ + (NSInteger)mapInteger:(NSObject * _Nullable)object orReturn:(NSInteger)defaultValue; +- (QONOfferings * _Nonnull)mapOfferings:(NSDictionary *)data; + +- (NSDictionary *)mapProducts:(NSDictionary *)data; + +- (NSDictionary * _Nullable)mapProductsEntitlementsRelationships:(NSDictionary * _Nullable)dict; + +- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data; + @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m index 86aa643e..693f0703 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m @@ -17,6 +17,7 @@ #import "QONExperimentGroup+Protected.h" #import "QONUser+Protected.h" #import "QONTransaction+Protected.h" +#import "QONFallbackObject.h" @implementation QNMapper @@ -53,6 +54,10 @@ + (NSDictionary * _Nullable)mapProductsEntitlementsRelation:(NSDictionary * _Nul } } +- (NSDictionary * _Nullable)mapProductsEntitlementsRelationships:(NSDictionary * _Nullable)dict { + return [QNMapper mapProductsEntitlementsRelation:dict]; +} + + (QONUser *)fillUser:(NSDictionary * _Nullable)dict { NSString *userID = dict[@"uid"]; NSString *originalAppVersion = dict[@"apple_extra"][@"original_application_version"]; @@ -95,6 +100,11 @@ + (QONUser *)fillUser:(NSDictionary * _Nullable)dict { return [products copy]; } +- (NSDictionary *)mapProducts:(NSDictionary *)data { + NSArray *rawProducts = data[@"products"]; + return [QNMapper fillProducts:rawProducts]; +} + + (NSArray *)fillProductsToArray:(NSArray *)data { return [self fillProductsToArray:data offeringID:nil]; } @@ -293,6 +303,11 @@ + (QONOfferings * _Nonnull)fillOfferingsObject:(NSArray *)data { return offerings; } +- (QONOfferings * _Nonnull)mapOfferings:(NSDictionary *)data { + NSArray *rawOfferings = data[@"offerings"]; + return [QNMapper fillOfferingsObject:rawOfferings]; +} + + (NSArray * _Nonnull)fillOfferings:(NSArray *)data { NSMutableArray *offerings = [NSMutableArray new]; @@ -369,5 +384,15 @@ + (NSInteger)mapInteger:(NSObject *)object orReturn:(NSInteger)defaultValue { } } +- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { + if (![data isKindOfClass:[NSDictionary class]]) { + return nil; + } + + QONFallbackObject *fallback = [QONFallbackObject new]; + + return fallback; +} + @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.h b/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.h new file mode 100644 index 00000000..9762b5a1 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.h @@ -0,0 +1,21 @@ +// +// QONFallbacksMapper.h +// Qonversion +// +// Created by Suren Sarkisyan on 06.06.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import + +@class QONFallbackObject, QNMapper, QONRemoteConfigMapper; + +NS_ASSUME_NONNULL_BEGIN + +@interface QONFallbacksMapper : NSObject + +- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m b/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m new file mode 100644 index 00000000..97bcad39 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m @@ -0,0 +1,53 @@ +// +// QONFallbacksMapper.m +// Qonversion +// +// Created by Suren Sarkisyan on 06.06.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import "QONFallbacksMapper.h" +#import "QONFallbackObject.h" +#import "QNMapper.h" +#import "QONRemoteConfigMapper.h" + +@interface QONFallbacksMapper () + +@property (nonatomic, strong) QNMapper *mapper; +@property (nonatomic, strong) QONRemoteConfigMapper *remoteConfigMapper; + +@end + +@implementation QONFallbacksMapper + +- (instancetype)init +{ + self = [super init]; + if (self) { + _mapper = [QNMapper new]; + _remoteConfigMapper = [QONRemoteConfigMapper new]; + } + return self; +} + +- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { + if (![data isKindOfClass:[NSDictionary class]]) { + return nil; + } + + QONFallbackObject *fallback = [QONFallbackObject new]; + + fallback.products = [self.mapper mapProducts:data]; + fallback.offerings = [self.mapper mapOfferings:data]; + fallback.productsEntitlementsRelation = [self.mapper mapProductsEntitlementsRelationships:data]; + + NSDictionary *rawRemoteConfig = data[@"remote_config"]; + fallback.remoteConfig = [self.remoteConfigMapper mapRemoteConfig:rawRemoteConfig]; + + NSDictionary *rawRemoteConfigList = data[@"remote_config_list"]; + fallback.remoteConfigList = [self.remoteConfigMapper mapRemoteConfigList:rawRemoteConfigList]; + + return fallback; +} + +@end diff --git a/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.h b/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.h new file mode 100644 index 00000000..e51625f0 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.h @@ -0,0 +1,29 @@ +// +// QONFallbackObject.h +// Qonversion +// +// Created by Suren Sarkisyan on 06.06.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import + +@class QONProduct, QONOfferings, QONRemoteConfig, QONRemoteConfigList; + +NS_ASSUME_NONNULL_BEGIN + +@interface QONFallbackObject : NSObject + +@property (nonatomic, copy, nullable) NSDictionary *products; + +@property (nonatomic, strong, nullable) QONOfferings *offerings; + +@property (nonatomic, copy, nullable) NSDictionary *productsEntitlementsRelation; + +@property (nonatomic, strong, nullable) QONRemoteConfig *remoteConfig; + +@property (nonatomic, strong, nullable) QONRemoteConfigList *remoteConfigList; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.m b/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.m new file mode 100644 index 00000000..a8c2dce8 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.m @@ -0,0 +1,17 @@ +// +// QONFallbackObject.m +// Qonversion +// +// Created by Suren Sarkisyan on 06.06.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import "QONFallbackObject.h" +#import "QONProduct.h" +#import "QONOfferings.h" +#import "QONRemoteConfig.h" +#import "QONRemoteConfigList.h" + +@implementation QONFallbackObject + +@end diff --git a/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.h b/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.h new file mode 100644 index 00000000..3be3cd04 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.h @@ -0,0 +1,21 @@ +// +// QONFallbacksService.h +// Qonversion +// +// Created by Suren Sarkisyan on 06.06.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import + +@class QONFallbackObject, QONFallbacksMapper; + +NS_ASSUME_NONNULL_BEGIN + +@interface QONFallbacksService : NSObject + +- (QONFallbackObject * _Nullable)obtainFallbackData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.m b/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.m new file mode 100644 index 00000000..896c4b05 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.m @@ -0,0 +1,47 @@ +// +// QONFallbacksService.m +// Qonversion +// +// Created by Suren Sarkisyan on 06.06.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import "QONFallbacksService.h" +#import "QONFallbackObject.h" +#import "QONFallbacksMapper.h" + +NSString *const kFallbacksFileName = @"qonversion_fallbacks.json"; + +@interface QONFallbacksService () + +@property (nonatomic, strong) QONFallbacksMapper *mapper; + +@end + +@implementation QONFallbacksService + +- (instancetype)init { + self = [super init]; + if (self) { + _mapper = [QONFallbacksMapper new]; + } + return self; +} + +- (QONFallbackObject * _Nullable)obtainFallbackData { + NSBundle *bundle = [NSBundle mainBundle]; + + NSString *fileName = [kFallbacksFileName stringByDeletingPathExtension]; + NSString *fileExtension = [kFallbacksFileName pathExtension]; + NSString *pathToFile = [bundle pathForResource:fileName ofType:fileExtension]; + + NSData *fileData = [NSData dataWithContentsOfFile:pathToFile]; + + NSDictionary *resultMap = [NSJSONSerialization JSONObjectWithData:fileData options:kNilOptions error:nil]; + + QONFallbackObject *resultObject = [self.mapper mapFallback:resultMap]; + + return resultObject; +} + +@end diff --git a/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.h b/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.h new file mode 100644 index 00000000..4cb67347 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.h @@ -0,0 +1,19 @@ +// +// NSError+Sugare.h +// Qonversion +// +// Created by Suren Sarkisyan on 06.06.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSError (Sugare) + +- (BOOL)shouldFireFallback; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.m b/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.m new file mode 100644 index 00000000..8fe59cd1 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.m @@ -0,0 +1,18 @@ +// +// NSError+Sugare.m +// Qonversion +// +// Created by Suren Sarkisyan on 06.06.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import "NSError+Sugare.h" + +@implementation NSError (Sugare) + +- (BOOL)shouldFireFallback { + // TODO: update logic here + return YES; +} + +@end From bcfa07136ab18590c95c3702ee7840d0f75c2ba9 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 12 Jun 2024 16:42:18 +0400 Subject: [PATCH 02/25] Updated logic --- Sample/qonversion_fallbacks.json | 31 ++++++++++++--- .../QONRemoteConfigManager.m | 38 +++++++++++++++---- .../QONFallbacksMapper/QONFallbacksMapper.m | 3 -- .../QONFallbackObject/QONFallbackObject.h | 2 - .../Utils/NSError+Sugare/NSError+Sugare.m | 8 +++- 5 files changed, 62 insertions(+), 20 deletions(-) diff --git a/Sample/qonversion_fallbacks.json b/Sample/qonversion_fallbacks.json index 0735fd54..7deb10be 100644 --- a/Sample/qonversion_fallbacks.json +++ b/Sample/qonversion_fallbacks.json @@ -66,21 +66,40 @@ "plus" ] }, - "remote_config": { - "experiment": "", - "payload": { + "remote_configs": [ + { + "experiment": "", + "payload": { "CTA": "Start you trial", "CTA_color": "red", "main_image": 111, "product_id": 123123123123123, "show_close_button": 1 - }, - "source": { + }, + "source": { "assignment_type": "auto", "context_key": "", "name": "Default settings", "type": "remote_configuration", "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" + } + }, + { + "experiment": "", + "payload": { + "CTA": "New test", + "CTA_color": "blue", + "main_image": 1111, + "product_id": 2332, + "show_close_button": 1 + }, + "source": { + "assignment_type": "auto", + "context_key": "new_test", + "name": "Default settings", + "type": "remote_configuration", + "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" + } } - } + ] } diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 2af29b57..96a34e98 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -106,8 +106,9 @@ - (void)obtainRemoteConfigWithContextKey:(NSString * _Nullable)contextKey comple if (error) { if (error.shouldFireFallback) { weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbacksService obtainFallbackData]; - if (weakSelf.fallbackData.remoteConfig) { - [weakSelf fireRemoteConfig:weakSelf.fallbackData.remoteConfig contextKey:contextKey loadingState:loadingState error:nil completion:completion]; + QONRemoteConfig *remoteConfig = [weakSelf.fallbackData.remoteConfigList remoteConfigForEmptyContextKey]; + if (remoteConfig) { + [weakSelf fireRemoteConfig:remoteConfig contextKey:contextKey loadingState:loadingState error:nil completion:completion]; } else { [weakSelf fireRemoteConfig:nil contextKey:contextKey loadingState:loadingState error:error completion:completion]; return; @@ -165,7 +166,7 @@ - (void)obtainRemoteConfigListWithContextKeys:(NSArray *)contextKeys __block __weak QONRemoteConfigManager *weakSelf = self; [self.userPropertiesManager forceSendProperties:^{ - QONRemoteConfigListCompletionHandler completionWrapper = [weakSelf remoteConfigListCompletionWrapper:completion]; + QONRemoteConfigListCompletionHandler completionWrapper = [weakSelf remoteConfigListCompletionWrapper:completion contextKeys:contextKeys includeEmptyContextKey:includeEmptyContextKey]; [weakSelf.remoteConfigService loadRemoteConfigList:contextKeys includeEmptyContextKey:includeEmptyContextKey completion:completionWrapper]; }]; } @@ -182,7 +183,7 @@ - (void)obtainRemoteConfigList:(QONRemoteConfigListCompletionHandler)completion __block __weak QONRemoteConfigManager *weakSelf = self; [self.userPropertiesManager forceSendProperties:^{ - QONRemoteConfigListCompletionHandler completionWrapper = [weakSelf remoteConfigListCompletionWrapper:completion]; + QONRemoteConfigListCompletionHandler completionWrapper = [weakSelf remoteConfigListCompletionWrapper:completion contextKeys:@[] includeEmptyContextKey:YES]; [weakSelf.remoteConfigService loadRemoteConfigList:completionWrapper]; }]; } @@ -224,13 +225,25 @@ - (QONRemoteConfigLoadingState *)loadingStateForContextKey:(NSString *)contextKe return self.loadingStates[key]; } -- (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRemoteConfigListCompletionHandler)completion { +- (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRemoteConfigListCompletionHandler)completion contextKeys:(NSArray *)contextKeys includeEmptyContextKey:(BOOL)includeEmptyContextKey { NSMutableDictionary *localLoadingStates = self.loadingStates; + __block __weak QONRemoteConfigManager *weakSelf = self; + return ^(QONRemoteConfigList * _Nullable remoteConfigList, NSError * _Nullable error) { if (error) { - completion(nil, error); - return; + weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbacksService obtainFallbackData]; + if (weakSelf.fallbackData.remoteConfigList) { + if (contextKeys.count == 0) { + remoteConfigList = weakSelf.fallbackData.remoteConfigList; + } else { + NSArray *remoteConfigs = [weakSelf remoteConfigsForContextKeys:contextKeys remoteConfigList:remoteConfigList]; + remoteConfigList.remoteConfigs = remoteConfigs; + } + } else { + completion(nil, error); + return; + } } if (remoteConfigList) { @@ -246,4 +259,15 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe }; } +- (NSArray *_Nullable)remoteConfigsForContextKeys:(NSArray *)contextKeys remoteConfigList:(QONRemoteConfigList *)remoteConfigList { + NSMutableArray *remoteConfigs = [NSMutableArray new]; + for (QONRemoteConfig *remoteConfig in remoteConfigList.remoteConfigs) { + if ([contextKeys containsObject:remoteConfig.source.contextKey]) { + [remoteConfigs addObject:remoteConfig]; + } + } + + return [remoteConfigs mutableCopy]; +} + @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m b/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m index 97bcad39..9a05ca07 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m @@ -41,9 +41,6 @@ - (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { fallback.offerings = [self.mapper mapOfferings:data]; fallback.productsEntitlementsRelation = [self.mapper mapProductsEntitlementsRelationships:data]; - NSDictionary *rawRemoteConfig = data[@"remote_config"]; - fallback.remoteConfig = [self.remoteConfigMapper mapRemoteConfig:rawRemoteConfig]; - NSDictionary *rawRemoteConfigList = data[@"remote_config_list"]; fallback.remoteConfigList = [self.remoteConfigMapper mapRemoteConfigList:rawRemoteConfigList]; diff --git a/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.h b/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.h index e51625f0..996a8102 100644 --- a/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.h +++ b/Sources/Qonversion/Qonversion/Models/QONFallbackObject/QONFallbackObject.h @@ -20,8 +20,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) NSDictionary *productsEntitlementsRelation; -@property (nonatomic, strong, nullable) QONRemoteConfig *remoteConfig; - @property (nonatomic, strong, nullable) QONRemoteConfigList *remoteConfigList; @end diff --git a/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.m b/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.m index 8fe59cd1..8a4f4cd7 100644 --- a/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.m +++ b/Sources/Qonversion/Qonversion/Utils/NSError+Sugare/NSError+Sugare.m @@ -7,12 +7,16 @@ // #import "NSError+Sugare.h" +#import "QNInternalConstants.h" @implementation NSError (Sugare) - (BOOL)shouldFireFallback { - // TODO: update logic here - return YES; + if (self.code == NSURLErrorNotConnectedToInternet || (self.code >= kInternalServerErrorFirstCode && self.code <= kInternalServerErrorLastCode)) { + return YES; + } else { + return NO; + } } @end From 1fa733198a47f9b46481d3186261d9c577697417 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 12 Jun 2024 17:00:13 +0400 Subject: [PATCH 03/25] Updated key in json file --- Sample/qonversion_fallbacks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sample/qonversion_fallbacks.json b/Sample/qonversion_fallbacks.json index 7deb10be..b5421192 100644 --- a/Sample/qonversion_fallbacks.json +++ b/Sample/qonversion_fallbacks.json @@ -66,7 +66,7 @@ "plus" ] }, - "remote_configs": [ + "remote_config_list": [ { "experiment": "", "payload": { From c499f91e5b60848db42f8c3907ac761b2ad04b97 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 12 Jun 2024 17:05:55 +0400 Subject: [PATCH 04/25] Fixed logic for remote config for context key --- Sample/qonversion_fallbacks.json | 17 +++++++++++++++++ .../QONRemoteConfigManager.m | 8 +++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Sample/qonversion_fallbacks.json b/Sample/qonversion_fallbacks.json index b5421192..86c31bb4 100644 --- a/Sample/qonversion_fallbacks.json +++ b/Sample/qonversion_fallbacks.json @@ -100,6 +100,23 @@ "type": "remote_configuration", "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" } + }, + { + "experiment": "", + "payload": { + "CTA": "One more test", + "CTA_color": "yellow", + "main_image": 1111, + "product_id": 2332, + "show_close_button": 1 + }, + "source": { + "assignment_type": "auto", + "context_key": "one_more_test", + "name": "Default settings", + "type": "remote_configuration", + "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" + } } ] } diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 96a34e98..7b2f84c8 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -106,7 +106,13 @@ - (void)obtainRemoteConfigWithContextKey:(NSString * _Nullable)contextKey comple if (error) { if (error.shouldFireFallback) { weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbacksService obtainFallbackData]; - QONRemoteConfig *remoteConfig = [weakSelf.fallbackData.remoteConfigList remoteConfigForEmptyContextKey]; + QONRemoteConfig *remoteConfig; + if (contextKey.length == 0) { + remoteConfig = [weakSelf.fallbackData.remoteConfigList remoteConfigForEmptyContextKey]; + } else { + remoteConfig = [weakSelf.fallbackData.remoteConfigList remoteConfigForContextKey:contextKey]; + } + if (remoteConfig) { [weakSelf fireRemoteConfig:remoteConfig contextKey:contextKey loadingState:loadingState error:nil completion:completion]; } else { From 28b1e2a74fa27853f894428c83ef9e98c2ed97af Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 12 Jun 2024 17:34:51 +0400 Subject: [PATCH 05/25] Updated logic --- .../QONRemoteConfigManager.m | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 7b2f84c8..45d78318 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -189,7 +189,7 @@ - (void)obtainRemoteConfigList:(QONRemoteConfigListCompletionHandler)completion __block __weak QONRemoteConfigManager *weakSelf = self; [self.userPropertiesManager forceSendProperties:^{ - QONRemoteConfigListCompletionHandler completionWrapper = [weakSelf remoteConfigListCompletionWrapper:completion contextKeys:@[] includeEmptyContextKey:YES]; + QONRemoteConfigListCompletionHandler completionWrapper = [weakSelf remoteConfigListCompletionWrapper:completion contextKeys:nil includeEmptyContextKey:YES]; [weakSelf.remoteConfigService loadRemoteConfigList:completionWrapper]; }]; } @@ -239,11 +239,10 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe return ^(QONRemoteConfigList * _Nullable remoteConfigList, NSError * _Nullable error) { if (error) { weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbacksService obtainFallbackData]; - if (weakSelf.fallbackData.remoteConfigList) { - if (contextKeys.count == 0) { - remoteConfigList = weakSelf.fallbackData.remoteConfigList; - } else { - NSArray *remoteConfigs = [weakSelf remoteConfigsForContextKeys:contextKeys remoteConfigList:remoteConfigList]; + remoteConfigList = weakSelf.fallbackData.remoteConfigList; + if (remoteConfigList) { + if (contextKeys) { + NSArray *remoteConfigs = [weakSelf remoteConfigsForContextKeys:contextKeys remoteConfigList:remoteConfigList includeEmptyContextKey:includeEmptyContextKey]; remoteConfigList.remoteConfigs = remoteConfigs; } } else { @@ -265,10 +264,15 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe }; } -- (NSArray *_Nullable)remoteConfigsForContextKeys:(NSArray *)contextKeys remoteConfigList:(QONRemoteConfigList *)remoteConfigList { +- (NSArray *_Nullable)remoteConfigsForContextKeys:(NSArray *)contextKeys remoteConfigList:(QONRemoteConfigList *)remoteConfigList includeEmptyContextKey:(BOOL)includeEmptyContextKey { + if (contextKeys.count == 0 && !includeEmptyContextKey) { + return @[]; + } + NSMutableArray *remoteConfigs = [NSMutableArray new]; for (QONRemoteConfig *remoteConfig in remoteConfigList.remoteConfigs) { - if ([contextKeys containsObject:remoteConfig.source.contextKey]) { + BOOL shouldAddCurrentRemoteConfigWithEmptyContextKey = includeEmptyContextKey && remoteConfig.source.contextKey.length == 0; + if (shouldAddCurrentRemoteConfigWithEmptyContextKey || [contextKeys containsObject:remoteConfig.source.contextKey]) { [remoteConfigs addObject:remoteConfig]; } } From 95597c00b9cddff8a6572665c3c80f247043e833 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 12 Jun 2024 17:48:15 +0400 Subject: [PATCH 06/25] Fixed warnings --- Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h | 6 +++--- Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h index 509c3322..9ca4709c 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h @@ -16,12 +16,12 @@ + (NSInteger)mapInteger:(NSObject * _Nullable)object orReturn:(NSInteger)defaultValue; -- (QONOfferings * _Nonnull)mapOfferings:(NSDictionary *)data; +- (QONOfferings * _Nonnull)mapOfferings:(NSDictionary * _Nullable)data; -- (NSDictionary *)mapProducts:(NSDictionary *)data; +- (NSDictionary * _Nonnull)mapProducts:(NSDictionary * _Nullable)data; - (NSDictionary * _Nullable)mapProductsEntitlementsRelationships:(NSDictionary * _Nullable)dict; -- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data; +- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary * _Nullable)data; @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m index 693f0703..82f31a26 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m @@ -100,7 +100,7 @@ + (QONUser *)fillUser:(NSDictionary * _Nullable)dict { return [products copy]; } -- (NSDictionary *)mapProducts:(NSDictionary *)data { +- (NSDictionary * _Nonnull)mapProducts:(NSDictionary * _Nullable)data { NSArray *rawProducts = data[@"products"]; return [QNMapper fillProducts:rawProducts]; } @@ -303,7 +303,7 @@ + (QONOfferings * _Nonnull)fillOfferingsObject:(NSArray *)data { return offerings; } -- (QONOfferings * _Nonnull)mapOfferings:(NSDictionary *)data { +- (QONOfferings * _Nonnull)mapOfferings:(NSDictionary * _Nullable)data { NSArray *rawOfferings = data[@"offerings"]; return [QNMapper fillOfferingsObject:rawOfferings]; } From fa95dd363ecbdfef572bc609a2907ea62501cd82 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 12 Jun 2024 18:14:31 +0400 Subject: [PATCH 07/25] Fixed type --- .../Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m b/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m index 9a05ca07..ad45683e 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m @@ -41,7 +41,7 @@ - (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { fallback.offerings = [self.mapper mapOfferings:data]; fallback.productsEntitlementsRelation = [self.mapper mapProductsEntitlementsRelationships:data]; - NSDictionary *rawRemoteConfigList = data[@"remote_config_list"]; + NSArray *rawRemoteConfigList = data[@"remote_config_list"]; fallback.remoteConfigList = [self.remoteConfigMapper mapRemoteConfigList:rawRemoteConfigList]; return fallback; From 6cf91bdd05f72552b2d487b0d182181f645b5734 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 12 Jun 2024 18:29:31 +0400 Subject: [PATCH 08/25] Fixed SPM --- Package.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Package.swift b/Package.swift index a61a1ae5..fd3edce0 100644 --- a/Package.swift +++ b/Package.swift @@ -49,14 +49,17 @@ let sources: [String] = ["Qonversion/Automations/Constants", "Qonversion/Qonversion/Mappers/QNUserInfoMapper", "Qonversion/Qonversion/Mappers/QONRemoteConfigMapper", "Qonversion/Qonversion/Mappers/QONUserPropertiesMapper", + "Qonversion/Qonversion/Mappers/QONFallbacksMapper", "Qonversion/Qonversion/Models", "Qonversion/Qonversion/Models/Protected", "Qonversion/Qonversion/Models/QONStoreKit2PurchaseModel", + "Qonversion/Qonversion/Models/QONFallbackObject", "Qonversion/Qonversion/Models/QNMapperObject", "Qonversion/Qonversion/Services", "Qonversion/Qonversion/Services/QNAPIClient", "Qonversion/Qonversion/Services/QNIdentityService", "Qonversion/Qonversion/Services/QNStoreKitService", + "Qonversion/Qonversion/Services/QONFallbacksService", "Qonversion/Qonversion/Services/QNUserInfoService", "Qonversion/Qonversion/Services/QONRemoteConfigService", "Qonversion/Qonversion/Services/QONExceptionManager", @@ -65,6 +68,7 @@ let sources: [String] = ["Qonversion/Automations/Constants", "Qonversion/Qonversion/Utils/QNProperties", "Qonversion/Qonversion/Utils/QNRateLimiter", "Qonversion/Qonversion/Utils/QNUserInfo", + "Qonversion/Qonversion/Utils/NSError+Sugare", "Qonversion/Qonversion/Utils/QNUtils"] let package = Package( From 2fa500065d2452d5814ab0422ee15d77b21d49c6 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 12 Jun 2024 18:44:08 +0400 Subject: [PATCH 09/25] Fixed tests --- QonversionTests/ProductCenterManagerTests.m | 4 +++- Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/QonversionTests/ProductCenterManagerTests.m b/QonversionTests/ProductCenterManagerTests.m index 0171d15d..fd3ca790 100644 --- a/QonversionTests/ProductCenterManagerTests.m +++ b/QonversionTests/ProductCenterManagerTests.m @@ -9,6 +9,7 @@ #import "QNUserInfoService.h" #import "QNIdentityManager.h" #import "QNLocalStorage.h" +#import "QONFallbacksService.h" #import "Helpers/XCTestCase+TestJSON.h" @interface QNProductCenterManager (Private) @@ -46,7 +47,8 @@ - (void)setUp { id mockUserInfoService = OCMClassMock([QNUserInfoService class]); id mockIdentityManager = OCMClassMock([QNIdentityManager class]); id mockLocalStorage = OCMProtocolMock(@protocol(QNLocalStorage)); - _manager = [[QNProductCenterManager alloc] initWithUserInfoService:mockUserInfoService identityManager:mockIdentityManager localStorage:mockLocalStorage]; + id mockFallbackService = OCMClassMock([QONFallbacksService class]); + _manager = [[QNProductCenterManager alloc] initWithUserInfoService:mockUserInfoService identityManager:mockIdentityManager localStorage:mockLocalStorage fallbacksService:mockFallbackService]; [_manager setApiClient:_mockClient]; } diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h index 9ca4709c..a696e352 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h @@ -1,6 +1,6 @@ #import -@class QNMapperObject, QONLaunchResult, QONEntitlement, QONIntroEligibility, QONUser, QONFallbackObject, QONOfferings; +@class QNMapperObject, QONLaunchResult, QONEntitlement, QONIntroEligibility, QONUser, QONFallbackObject, QONOfferings, QONProduct; @interface QNMapper : NSObject From 4f33077443fae53f8bad3c5867b056cf9c7f9946 Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 13 Jun 2024 15:53:41 +0400 Subject: [PATCH 10/25] Fixed remote configs for context keys logic --- .../Main/QONRemoteConfigManager/QONRemoteConfigManager.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 45d78318..98819388 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -238,12 +238,13 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe return ^(QONRemoteConfigList * _Nullable remoteConfigList, NSError * _Nullable error) { if (error) { - weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbacksService obtainFallbackData]; - remoteConfigList = weakSelf.fallbackData.remoteConfigList; - if (remoteConfigList) { + weakSelf.fallbackData = [weakSelf.fallbacksService obtainFallbackData]; + if (weakSelf.fallbackData.remoteConfigList) { if (contextKeys) { NSArray *remoteConfigs = [weakSelf remoteConfigsForContextKeys:contextKeys remoteConfigList:remoteConfigList includeEmptyContextKey:includeEmptyContextKey]; - remoteConfigList.remoteConfigs = remoteConfigs; + remoteConfigList = [[QONRemoteConfigList alloc] initWithRemoteConfigs:remoteConfigs]; + } else { + remoteConfigList = [[QONRemoteConfigList alloc] initWithRemoteConfigs:weakSelf.fallbackData.remoteConfigList.remoteConfigs]; } } else { completion(nil, error); From eb7f1c0e5c8e4a78e0765cdf403451eef0adb283 Mon Sep 17 00:00:00 2001 From: Surik Date: Fri, 14 Jun 2024 15:19:49 +0400 Subject: [PATCH 11/25] Fixed naming fallbacks -> fallback --- Package.swift | 4 +- Qonversion.xcodeproj/project.pbxproj | 64 +++++++++---------- QonversionTests/QonversionMapperTests.m | 1 + Sources/Qonversion/Public/Qonversion.m | 6 +- .../QNProductCenterManager.h | 4 +- .../QNProductCenterManager.m | 14 ++-- .../QONRemoteConfigManager.h | 4 +- .../QONRemoteConfigManager.m | 8 +-- .../QONFallbackMapper.h} | 4 +- .../QONFallbackMapper.m} | 8 +-- .../QONFallbackService.h} | 6 +- .../QONFallbackService.m} | 14 ++-- 12 files changed, 69 insertions(+), 68 deletions(-) rename Sources/Qonversion/Qonversion/Mappers/{QONFallbacksMapper/QONFallbacksMapper.h => QONFallbackMapper/QONFallbackMapper.h} (84%) rename Sources/Qonversion/Qonversion/Mappers/{QONFallbacksMapper/QONFallbacksMapper.m => QONFallbackMapper/QONFallbackMapper.m} (90%) rename Sources/Qonversion/Qonversion/Services/{QONFallbacksService/QONFallbacksService.h => QONFallbackService/QONFallbackService.h} (70%) rename Sources/Qonversion/Qonversion/Services/{QONFallbacksService/QONFallbacksService.m => QONFallbackService/QONFallbackService.m} (78%) diff --git a/Package.swift b/Package.swift index fd3edce0..4feed775 100644 --- a/Package.swift +++ b/Package.swift @@ -49,7 +49,7 @@ let sources: [String] = ["Qonversion/Automations/Constants", "Qonversion/Qonversion/Mappers/QNUserInfoMapper", "Qonversion/Qonversion/Mappers/QONRemoteConfigMapper", "Qonversion/Qonversion/Mappers/QONUserPropertiesMapper", - "Qonversion/Qonversion/Mappers/QONFallbacksMapper", + "Qonversion/Qonversion/Mappers/QONFallbackMapper", "Qonversion/Qonversion/Models", "Qonversion/Qonversion/Models/Protected", "Qonversion/Qonversion/Models/QONStoreKit2PurchaseModel", @@ -59,7 +59,7 @@ let sources: [String] = ["Qonversion/Automations/Constants", "Qonversion/Qonversion/Services/QNAPIClient", "Qonversion/Qonversion/Services/QNIdentityService", "Qonversion/Qonversion/Services/QNStoreKitService", - "Qonversion/Qonversion/Services/QONFallbacksService", + "Qonversion/Qonversion/Services/QONFallbackService", "Qonversion/Qonversion/Services/QNUserInfoService", "Qonversion/Qonversion/Services/QONRemoteConfigService", "Qonversion/Qonversion/Services/QONExceptionManager", diff --git a/Qonversion.xcodeproj/project.pbxproj b/Qonversion.xcodeproj/project.pbxproj index c3e55c53..2eb0d98c 100644 --- a/Qonversion.xcodeproj/project.pbxproj +++ b/Qonversion.xcodeproj/project.pbxproj @@ -55,12 +55,8 @@ 6A95DEA529E40F2E00350BD6 /* XCTestCase+IntegrationTestsHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A95DEA429E40F2E00350BD6 /* XCTestCase+IntegrationTestsHelpers.m */; }; 6ABCBE182B99A79E003DB107 /* QONRemoteConfigLoadingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 6ABCBE162B99A79E003DB107 /* QONRemoteConfigLoadingState.h */; }; 6ABCBE192B99A79E003DB107 /* QONRemoteConfigLoadingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 6ABCBE172B99A79E003DB107 /* QONRemoteConfigLoadingState.m */; }; - 700635FB2C11C37B00BB9F9C /* QONFallbacksService.h in Headers */ = {isa = PBXBuildFile; fileRef = 700635F92C11C37B00BB9F9C /* QONFallbacksService.h */; }; - 700635FC2C11C37B00BB9F9C /* QONFallbacksService.m in Sources */ = {isa = PBXBuildFile; fileRef = 700635FA2C11C37B00BB9F9C /* QONFallbacksService.m */; }; 700636062C11CEF700BB9F9C /* QONFallbackObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 700636042C11CEF700BB9F9C /* QONFallbackObject.h */; }; 700636072C11CEF700BB9F9C /* QONFallbackObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 700636052C11CEF700BB9F9C /* QONFallbackObject.m */; }; - 7006360B2C11EE8400BB9F9C /* QONFallbacksMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 700636082C11EE8400BB9F9C /* QONFallbacksMapper.h */; }; - 7006360C2C11EE8400BB9F9C /* QONFallbacksMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 700636092C11EE8400BB9F9C /* QONFallbacksMapper.m */; }; 700636142C12125900BB9F9C /* NSError+Sugare.h in Headers */ = {isa = PBXBuildFile; fileRef = 700636122C12125900BB9F9C /* NSError+Sugare.h */; }; 700636152C12125900BB9F9C /* NSError+Sugare.m in Sources */ = {isa = PBXBuildFile; fileRef = 700636132C12125900BB9F9C /* NSError+Sugare.m */; }; 700EC173291277130032E205 /* QONExperimentGroup+Protected.h in Headers */ = {isa = PBXBuildFile; fileRef = 700EC171291277130032E205 /* QONExperimentGroup+Protected.h */; }; @@ -73,6 +69,10 @@ 702BF8B629531A68000B6C3E /* QONScreenCustomizationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 702BF8B529531A68000B6C3E /* QONScreenCustomizationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 702DBDEC2A3216C900D590D0 /* QONExperiment+Protected.h in Headers */ = {isa = PBXBuildFile; fileRef = 702DBDEB2A3216C900D590D0 /* QONExperiment+Protected.h */; }; 703666202C17512200B0C503 /* qonversion_fallbacks.json in Resources */ = {isa = PBXBuildFile; fileRef = 7036661F2C17512200B0C503 /* qonversion_fallbacks.json */; }; + 7042E7822C1C5DB700C5AECF /* QONFallbackService.h in Headers */ = {isa = PBXBuildFile; fileRef = 7042E77F2C1C5DB700C5AECF /* QONFallbackService.h */; }; + 7042E7832C1C5DB700C5AECF /* QONFallbackService.m in Sources */ = {isa = PBXBuildFile; fileRef = 7042E7802C1C5DB700C5AECF /* QONFallbackService.m */; }; + 7042E7872C1C5DDE00C5AECF /* QONFallbackMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 7042E7842C1C5DDE00C5AECF /* QONFallbackMapper.h */; }; + 7042E7882C1C5DDE00C5AECF /* QONFallbackMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7042E7852C1C5DDE00C5AECF /* QONFallbackMapper.m */; }; 707734F42A9F607700CFF742 /* QONRemoteConfigurationSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 707734F22A9F607700CFF742 /* QONRemoteConfigurationSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; 707734F52A9F607700CFF742 /* QONRemoteConfigurationSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 707734F32A9F607700CFF742 /* QONRemoteConfigurationSource.m */; }; 707734F72A9F6B8700CFF742 /* QONRemoteConfigurationSource+Protected.h in Headers */ = {isa = PBXBuildFile; fileRef = 707734F62A9F6B8700CFF742 /* QONRemoteConfigurationSource+Protected.h */; }; @@ -377,12 +377,8 @@ 6A95DEA429E40F2E00350BD6 /* XCTestCase+IntegrationTestsHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCTestCase+IntegrationTestsHelpers.m"; sourceTree = ""; }; 6ABCBE162B99A79E003DB107 /* QONRemoteConfigLoadingState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigLoadingState.h; sourceTree = ""; }; 6ABCBE172B99A79E003DB107 /* QONRemoteConfigLoadingState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRemoteConfigLoadingState.m; sourceTree = ""; }; - 700635F92C11C37B00BB9F9C /* QONFallbacksService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONFallbacksService.h; sourceTree = ""; }; - 700635FA2C11C37B00BB9F9C /* QONFallbacksService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONFallbacksService.m; sourceTree = ""; }; 700636042C11CEF700BB9F9C /* QONFallbackObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONFallbackObject.h; sourceTree = ""; }; 700636052C11CEF700BB9F9C /* QONFallbackObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONFallbackObject.m; sourceTree = ""; }; - 700636082C11EE8400BB9F9C /* QONFallbacksMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QONFallbacksMapper.h; sourceTree = ""; }; - 700636092C11EE8400BB9F9C /* QONFallbacksMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QONFallbacksMapper.m; sourceTree = ""; }; 700636122C12125900BB9F9C /* NSError+Sugare.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+Sugare.h"; sourceTree = ""; }; 700636132C12125900BB9F9C /* NSError+Sugare.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSError+Sugare.m"; sourceTree = ""; }; 700EC171291277130032E205 /* QONExperimentGroup+Protected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "QONExperimentGroup+Protected.h"; sourceTree = ""; }; @@ -395,6 +391,10 @@ 702BF8B529531A68000B6C3E /* QONScreenCustomizationDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONScreenCustomizationDelegate.h; sourceTree = ""; }; 702DBDEB2A3216C900D590D0 /* QONExperiment+Protected.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QONExperiment+Protected.h"; sourceTree = ""; }; 7036661F2C17512200B0C503 /* qonversion_fallbacks.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = qonversion_fallbacks.json; sourceTree = ""; }; + 7042E77F2C1C5DB700C5AECF /* QONFallbackService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QONFallbackService.h; sourceTree = ""; }; + 7042E7802C1C5DB700C5AECF /* QONFallbackService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QONFallbackService.m; sourceTree = ""; }; + 7042E7842C1C5DDE00C5AECF /* QONFallbackMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QONFallbackMapper.h; sourceTree = ""; }; + 7042E7852C1C5DDE00C5AECF /* QONFallbackMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QONFallbackMapper.m; sourceTree = ""; }; 7052136F29F1807A00164AAF /* PurchasesMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchasesMapper.swift; sourceTree = ""; }; 707734F22A9F607700CFF742 /* QONRemoteConfigurationSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigurationSource.h; sourceTree = ""; }; 707734F32A9F607700CFF742 /* QONRemoteConfigurationSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRemoteConfigurationSource.m; sourceTree = ""; }; @@ -876,15 +876,6 @@ path = Helpers; sourceTree = ""; }; - 700635F82C11C36200BB9F9C /* QONFallbacksService */ = { - isa = PBXGroup; - children = ( - 700635F92C11C37B00BB9F9C /* QONFallbacksService.h */, - 700635FA2C11C37B00BB9F9C /* QONFallbacksService.m */, - ); - path = QONFallbacksService; - sourceTree = ""; - }; 700635FD2C11C3EA00BB9F9C /* QONFallbackObject */ = { isa = PBXGroup; children = ( @@ -894,15 +885,6 @@ path = QONFallbackObject; sourceTree = ""; }; - 7006360A2C11EE8400BB9F9C /* QONFallbacksMapper */ = { - isa = PBXGroup; - children = ( - 700636082C11EE8400BB9F9C /* QONFallbacksMapper.h */, - 700636092C11EE8400BB9F9C /* QONFallbacksMapper.m */, - ); - path = QONFallbacksMapper; - sourceTree = ""; - }; 7006360D2C1211F000BB9F9C /* NSError+Sugare */ = { isa = PBXGroup; children = ( @@ -932,6 +914,24 @@ path = Sources/Swift; sourceTree = SOURCE_ROOT; }; + 7042E7812C1C5DB700C5AECF /* QONFallbackService */ = { + isa = PBXGroup; + children = ( + 7042E77F2C1C5DB700C5AECF /* QONFallbackService.h */, + 7042E7802C1C5DB700C5AECF /* QONFallbackService.m */, + ); + path = QONFallbackService; + sourceTree = ""; + }; + 7042E7862C1C5DDE00C5AECF /* QONFallbackMapper */ = { + isa = PBXGroup; + children = ( + 7042E7842C1C5DDE00C5AECF /* QONFallbackMapper.h */, + 7042E7852C1C5DDE00C5AECF /* QONFallbackMapper.m */, + ); + path = QONFallbackMapper; + sourceTree = ""; + }; 70523C8D29F2853F009F01D2 /* Recovered References */ = { isa = PBXGroup; children = ( @@ -1443,7 +1443,7 @@ 8957325126DD03A3009507A6 /* Mappers */ = { isa = PBXGroup; children = ( - 7006360A2C11EE8400BB9F9C /* QONFallbacksMapper */, + 7042E7862C1C5DDE00C5AECF /* QONFallbackMapper */, 7098564A2A370F190023DFAB /* QONRemoteConfigMapper */, 8957325226DD03A3009507A6 /* QNUserInfoMapper */, 8957325626DD03A3009507A6 /* QNErrorsMapper */, @@ -1533,7 +1533,7 @@ 8957326A26DD03A3009507A6 /* Services */ = { isa = PBXGroup; children = ( - 700635F82C11C36200BB9F9C /* QONFallbacksService */, + 7042E7812C1C5DB700C5AECF /* QONFallbackService */, 70D05A9029C9FF2C00EA5DDF /* QONRemoteConfigService */, 8957326B26DD03A3009507A6 /* QNStoreKitService */, 8957326E26DD03A3009507A6 /* QNAPIClient */, @@ -1723,11 +1723,9 @@ 7097C6BE2A38BFC800565DE4 /* QONRemoteConfig+Protected.h in Headers */, 895732DF26DD03A3009507A6 /* QONUser+Protected.h in Headers */, 70ED951029FAAF31005F5D00 /* QONStoreKit2PurchaseModel.h in Headers */, - 7006360B2C11EE8400BB9F9C /* QONFallbacksMapper.h in Headers */, 8957329126DD03A3009507A6 /* QONAutomations.h in Headers */, 895732ED26DD03A3009507A6 /* QNUserInfoMapper.h in Headers */, 701922762B10AB3300724926 /* QONSubscriptionPeriod+Protected.h in Headers */, - 700635FB2C11C37B00BB9F9C /* QONFallbacksService.h in Headers */, 70ADE70F2951CC7200CB4D2E /* QONScreenPresentationConfiguration.h in Headers */, 700636062C11CEF700BB9F9C /* QONFallbackObject.h in Headers */, 8957327C26DD03A3009507A6 /* QONAutomationsDelegate.h in Headers */, @@ -1739,6 +1737,7 @@ 702DBDEC2A3216C900D590D0 /* QONExperiment+Protected.h in Headers */, 8957328D26DD03A3009507A6 /* QONOfferings.h in Headers */, 895732F926DD03A3009507A6 /* QNIdentityManagerInterface.h in Headers */, + 7042E7822C1C5DB700C5AECF /* QONFallbackService.h in Headers */, 8957328C26DD03A3009507A6 /* QONPromoPurchasesDelegate.h in Headers */, 895732F726DD03A3009507A6 /* QNProductCenterManager.h in Headers */, 70A26ADE2A31BC44008CE4A7 /* QONExperiment.h in Headers */, @@ -1750,6 +1749,7 @@ 8957328226DD03A3009507A6 /* QONLaunchResult.h in Headers */, 895732C526DD03A3009507A6 /* QNRequestBuilder.h in Headers */, A1839332BA452C481BDC499C /* QONExceptionManager.h in Headers */, + 7042E7872C1C5DDE00C5AECF /* QONFallbackMapper.h in Headers */, A1839F56181BFBE72A0DD0DF /* QONUserProperty.h in Headers */, A18397AF5F2CFB8C9E51769B /* QONUserProperties.h in Headers */, A18396F8EAB1D96E22ECA3B5 /* QONUserPropertiesMapper.h in Headers */, @@ -2073,7 +2073,6 @@ 895732CB26DD03A3009507A6 /* QNUtils.m in Sources */, 70ADE7102951CC7200CB4D2E /* QONScreenPresentationConfiguration.m in Sources */, 707734F52A9F607700CFF742 /* QONRemoteConfigurationSource.m in Sources */, - 7006360C2C11EE8400BB9F9C /* QONFallbacksMapper.m in Sources */, 6A21BF4E2AB20483005BDA7C /* QONRateLimiter.m in Sources */, 895732A626DD03A3009507A6 /* QONAutomationsScreen.m in Sources */, 700636072C11CEF700BB9F9C /* QONFallbackObject.m in Sources */, @@ -2092,6 +2091,7 @@ 895732BD26DD03A3009507A6 /* QNRequestSerializer.m in Sources */, 895732F526DD03A3009507A6 /* QNAttributionManager.m in Sources */, 895732EF26DD03A3009507A6 /* QNErrorsMapper.m in Sources */, + 7042E7882C1C5DDE00C5AECF /* QONFallbackMapper.m in Sources */, 6A121DB32BBB10AA0073B330 /* QONRemoteConfigListRequestData.m in Sources */, 895732A426DD03A3009507A6 /* QONUserActionPoint.m in Sources */, 8957330A26DE5532009507A6 /* QNKeyedArchiver.m in Sources */, @@ -2099,7 +2099,6 @@ 895732FA26DD03A3009507A6 /* QNIdentityManager.m in Sources */, 8957330026DD03A3009507A6 /* QNUserInfoService.m in Sources */, 700636152C12125900BB9F9C /* NSError+Sugare.m in Sources */, - 700635FC2C11C37B00BB9F9C /* QONFallbacksService.m in Sources */, 7098564E2A370F270023DFAB /* QONRemoteConfigMapper.m in Sources */, 895732AC26DD03A3009507A6 /* QONAutomationsFlowCoordinator.m in Sources */, 8957328326DD03A3009507A6 /* QONExperimentGroup.m in Sources */, @@ -2121,6 +2120,7 @@ A1839D7723FB8E18EC0294C9 /* QONExceptionManager.m in Sources */, A18393481F6CF124F055056C /* QONUserProperty.m in Sources */, A183981A2075084AD1E3D0AB /* QONUserProperties.m in Sources */, + 7042E7832C1C5DB700C5AECF /* QONFallbackService.m in Sources */, A1839D70E9E06E327527B4B9 /* QONUserPropertiesMapper.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/QonversionTests/QonversionMapperTests.m b/QonversionTests/QonversionMapperTests.m index 4d83e4b5..d3846d21 100644 --- a/QonversionTests/QonversionMapperTests.m +++ b/QonversionTests/QonversionMapperTests.m @@ -8,6 +8,7 @@ #import "QNMapperObject.h" #import "QONEntitlement.h" #import "QONLaunchResult.h" +#import "QONProduct.h" @interface QNMapperTests : XCTestCase @property (nonatomic, strong) NSDictionary *userInitSuccess; diff --git a/Sources/Qonversion/Public/Qonversion.m b/Sources/Qonversion/Public/Qonversion.m index 6560a302..43056803 100644 --- a/Sources/Qonversion/Public/Qonversion.m +++ b/Sources/Qonversion/Public/Qonversion.m @@ -14,7 +14,7 @@ #import "QONRemoteConfigManager.h" #import "QONExceptionManager.h" #import "QONUserProperty.h" -#import "QONFallbacksService.h" +#import "QONFallbackService.h" static id shared = nil; @@ -250,8 +250,8 @@ - (instancetype)initWithCustomUserDefaults:(NSUserDefaults *)userDefaults { _userInfoService = [servicesAssembly userInfoService]; _localStorage = [servicesAssembly localStorage]; id identityManager = [servicesAssembly identityManager]; - QONFallbacksService *fallbacksService = [QONFallbacksService new]; - _productCenterManager = [[QNProductCenterManager alloc] initWithUserInfoService:_userInfoService identityManager:identityManager localStorage:_localStorage fallbacksService:fallbacksService]; + QONFallbackService *fallbackService = [QONFallbackService new]; + _productCenterManager = [[QNProductCenterManager alloc] initWithUserInfoService:_userInfoService identityManager:identityManager localStorage:_localStorage fallbackService:fallbackService]; _propertiesManager = [QNUserPropertiesManager new]; _attributionManager = [QNAttributionManager new]; _remoteConfigManager = [QONRemoteConfigManager new]; diff --git a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.h b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.h index f9c72d07..f4ec3578 100644 --- a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.h +++ b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.h @@ -4,7 +4,7 @@ #import "QONLaunchMode.h" #import "QONRemoteConfigManager.h" -@class QONLaunchResult, QONStoreKit2PurchaseModel, QONFallbacksService; +@class QONLaunchResult, QONStoreKit2PurchaseModel, QONFallbackService; @protocol QONPromoPurchasesDelegate, QONEntitlementsUpdateListener, QNUserInfoServiceInterface, QNIdentityManagerInterface, QNLocalStorage; NS_ASSUME_NONNULL_BEGIN @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) QONLaunchMode launchMode; @property (nonatomic, strong) QONRemoteConfigManager *remoteConfigManager; -- (instancetype)initWithUserInfoService:(id)userInfoService identityManager:(id)identityManager localStorage:(id)localStorage fallbacksService:(QONFallbacksService *)fallbacksService; +- (instancetype)initWithUserInfoService:(id)userInfoService identityManager:(id)identityManager localStorage:(id)localStorage fallbackService:(QONFallbackService *)fallbackService; - (BOOL)isUserStable; - (void)identify:(NSString *)userID completion:(nullable QONUserInfoCompletionHandler)completion; diff --git a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m index b6a45f96..8b391ac4 100644 --- a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m +++ b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m @@ -19,7 +19,7 @@ #import "QNInternalConstants.h" #import "QONUser+Protected.h" #import "QONStoreKit2PurchaseModel.h" -#import "QONFallbacksService.h" +#import "QONFallbackService.h" #import "QONFallbackObject.h" #if TARGET_OS_IOS @@ -39,7 +39,7 @@ @interface QNProductCenterManager() @property (nonatomic, strong) id persistentStorage; @property (nonatomic, strong) id identityManager; @property (nonatomic, strong) id userInfoService; -@property (nonatomic, strong) QONFallbacksService *fallbacksService; +@property (nonatomic, strong) QONFallbackService *fallbackService; @property (nonatomic, strong) QONFallbackObject *fallbackData; @property (nonatomic, copy) NSArray *restoredTransactions; @@ -72,7 +72,7 @@ @interface QNProductCenterManager() @implementation QNProductCenterManager -- (instancetype)initWithUserInfoService:(id)userInfoService identityManager:(id)identityManager localStorage:(id)localStorage fallbacksService:(QONFallbacksService *)fallbacksService { +- (instancetype)initWithUserInfoService:(id)userInfoService identityManager:(id)identityManager localStorage:(id)localStorage fallbackService:(QONFallbackService *)fallbackService { self = super.init; if (self) { _launchingFinished = NO; @@ -80,7 +80,7 @@ - (instancetype)initWithUserInfoService:(id)userInfo _launchError = nil; _launchResult = nil; _cacheLifetime = QONEntitlementsCacheLifetimeMonth; - _fallbacksService = fallbacksService; + _fallbackService = fallbackService; #if TARGET_OS_IOS [QONAutomations sharedInstance]; @@ -159,7 +159,7 @@ - (NSTimeInterval)cachedLaunchResultTimeStamp { products = cachedResult ? cachedResult.products : products; if (products.allValues.count == 0) { - self.fallbackData = self.fallbackData ?: [self.fallbacksService obtainFallbackData]; + self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; products = self.fallbackData.products; } } @@ -175,7 +175,7 @@ - (QONOfferings * _Nullable)getActualOfferings { offerings = cachedResult ? cachedResult.offerings : offerings; if (!offerings) { - self.fallbackData = self.fallbackData ?: [self.fallbacksService obtainFallbackData]; + self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; offerings = self.fallbackData.offerings; } } @@ -1178,7 +1178,7 @@ - (void)handlePurchaseResult:(NSDictionary *)resul QONProduct *qonversionProduct = productsMap[transaction.payment.productIdentifier]; if (self.productsEntitlementsRelation.count == 0) { - QONFallbackObject *fallbackData = [self.fallbacksService obtainFallbackData]; + QONFallbackObject *fallbackData = [self.fallbackService obtainFallbackData]; self.productsEntitlementsRelation = fallbackData.productsEntitlementsRelation; } diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.h b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.h index 6121b709..7b1bdf79 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.h +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.h @@ -10,14 +10,14 @@ #import "QONLaunchResult.h" #import "QONExperiment.h" -@class QONRemoteConfigService, QNProductCenterManager, QNUserPropertiesManager, QONFallbacksService; +@class QONRemoteConfigService, QNProductCenterManager, QNUserPropertiesManager, QONFallbackService; NS_ASSUME_NONNULL_BEGIN @interface QONRemoteConfigManager : NSObject @property (nonatomic, strong) QONRemoteConfigService *remoteConfigService; -@property (nonatomic, strong) QONFallbacksService *fallbacksService; +@property (nonatomic, strong) QONFallbackService *fallbackService; @property (nonatomic, strong) QNProductCenterManager *productCenterManager; @property (nonatomic, strong) QNUserPropertiesManager *userPropertiesManager; diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 98819388..a2e71b18 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -15,7 +15,7 @@ #import "QONRemoteConfigLoadingState.h" #import "QONRemoteConfigListRequestData.h" #import "QNUserPropertiesManager.h" -#import "QONFallbacksService.h" +#import "QONFallbackService.h" #import "NSError+Sugare.h" #import "QONFallbackObject.h" @@ -38,7 +38,7 @@ - (instancetype)init { _remoteConfigService = [QONRemoteConfigService new]; _loadingStates = [NSMutableDictionary new]; _listRequests = [NSMutableArray new]; - _fallbacksService = [QONFallbacksService new]; + _fallbackService = [QONFallbackService new]; } return self; @@ -105,7 +105,7 @@ - (void)obtainRemoteConfigWithContextKey:(NSString * _Nullable)contextKey comple loadingState.isInProgress = NO; if (error) { if (error.shouldFireFallback) { - weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbacksService obtainFallbackData]; + weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbackService obtainFallbackData]; QONRemoteConfig *remoteConfig; if (contextKey.length == 0) { remoteConfig = [weakSelf.fallbackData.remoteConfigList remoteConfigForEmptyContextKey]; @@ -238,7 +238,7 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe return ^(QONRemoteConfigList * _Nullable remoteConfigList, NSError * _Nullable error) { if (error) { - weakSelf.fallbackData = [weakSelf.fallbacksService obtainFallbackData]; + weakSelf.fallbackData = [weakSelf.fallbackService obtainFallbackData]; if (weakSelf.fallbackData.remoteConfigList) { if (contextKeys) { NSArray *remoteConfigs = [weakSelf remoteConfigsForContextKeys:contextKeys remoteConfigList:remoteConfigList includeEmptyContextKey:includeEmptyContextKey]; diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.h b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h similarity index 84% rename from Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.h rename to Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h index 9762b5a1..519e231c 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.h +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h @@ -1,5 +1,5 @@ // -// QONFallbacksMapper.h +// QONFallbackMapper.h // Qonversion // // Created by Suren Sarkisyan on 06.06.2024. @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface QONFallbacksMapper : NSObject +@interface QONFallbackMapper : NSObject - (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data; diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m similarity index 90% rename from Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m rename to Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m index ad45683e..b03d18c1 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QONFallbacksMapper/QONFallbacksMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m @@ -1,24 +1,24 @@ // -// QONFallbacksMapper.m +// QONFallbackMapper.m // Qonversion // // Created by Suren Sarkisyan on 06.06.2024. // Copyright © 2024 Qonversion Inc. All rights reserved. // -#import "QONFallbacksMapper.h" +#import "QONFallbackMapper.h" #import "QONFallbackObject.h" #import "QNMapper.h" #import "QONRemoteConfigMapper.h" -@interface QONFallbacksMapper () +@interface QONFallbackMapper () @property (nonatomic, strong) QNMapper *mapper; @property (nonatomic, strong) QONRemoteConfigMapper *remoteConfigMapper; @end -@implementation QONFallbacksMapper +@implementation QONFallbackMapper - (instancetype)init { diff --git a/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.h b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.h similarity index 70% rename from Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.h rename to Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.h index 3be3cd04..fd97f507 100644 --- a/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.h +++ b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.h @@ -1,5 +1,5 @@ // -// QONFallbacksService.h +// QONFallbackService.h // Qonversion // // Created by Suren Sarkisyan on 06.06.2024. @@ -8,11 +8,11 @@ #import -@class QONFallbackObject, QONFallbacksMapper; +@class QONFallbackObject, QONFallbackMapper; NS_ASSUME_NONNULL_BEGIN -@interface QONFallbacksService : NSObject +@interface QONFallbackService : NSObject - (QONFallbackObject * _Nullable)obtainFallbackData; diff --git a/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.m b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m similarity index 78% rename from Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.m rename to Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m index 896c4b05..6bcb4745 100644 --- a/Sources/Qonversion/Qonversion/Services/QONFallbacksService/QONFallbacksService.m +++ b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m @@ -1,29 +1,29 @@ // -// QONFallbacksService.m +// QONFallbackService.m // Qonversion // // Created by Suren Sarkisyan on 06.06.2024. // Copyright © 2024 Qonversion Inc. All rights reserved. // -#import "QONFallbacksService.h" +#import "QONFallbackService.h" #import "QONFallbackObject.h" -#import "QONFallbacksMapper.h" +#import "QONFallbackMapper.h" NSString *const kFallbacksFileName = @"qonversion_fallbacks.json"; -@interface QONFallbacksService () +@interface QONFallbackService () -@property (nonatomic, strong) QONFallbacksMapper *mapper; +@property (nonatomic, strong) QONFallbackMapper *mapper; @end -@implementation QONFallbacksService +@implementation QONFallbackService - (instancetype)init { self = [super init]; if (self) { - _mapper = [QONFallbacksMapper new]; + _mapper = [QONFallbackMapper new]; } return self; } From e3541a85f59558c0d6f5f16f7c8fa2017b4c9e7e Mon Sep 17 00:00:00 2001 From: Surik Date: Fri, 14 Jun 2024 16:56:40 +0400 Subject: [PATCH 12/25] Code review fixes --- .../QNProductCenterManager/QNProductCenterManager.m | 4 ++-- .../QONRemoteConfigManager/QONRemoteConfigManager.m | 4 ++-- .../Qonversion/Mappers/QNMapper/QNMapper.h | 4 +--- .../Qonversion/Mappers/QNMapper/QNMapper.m | 12 +----------- .../Mappers/QONFallbackMapper/QONFallbackMapper.h | 2 +- .../Mappers/QONFallbackMapper/QONFallbackMapper.m | 4 ++-- 6 files changed, 9 insertions(+), 21 deletions(-) diff --git a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m index 8b391ac4..c0f0c6e7 100644 --- a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m +++ b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m @@ -1178,8 +1178,8 @@ - (void)handlePurchaseResult:(NSDictionary *)resul QONProduct *qonversionProduct = productsMap[transaction.payment.productIdentifier]; if (self.productsEntitlementsRelation.count == 0) { - QONFallbackObject *fallbackData = [self.fallbackService obtainFallbackData]; - self.productsEntitlementsRelation = fallbackData.productsEntitlementsRelation; + self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; + self.productsEntitlementsRelation = self.fallbackData.productsEntitlementsRelation; } NSArray *entitlementsIds = self.productsEntitlementsRelation[qonversionProduct.qonversionID]; diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index a2e71b18..65193f5e 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -238,7 +238,7 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe return ^(QONRemoteConfigList * _Nullable remoteConfigList, NSError * _Nullable error) { if (error) { - weakSelf.fallbackData = [weakSelf.fallbackService obtainFallbackData]; + weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbackService obtainFallbackData]; if (weakSelf.fallbackData.remoteConfigList) { if (contextKeys) { NSArray *remoteConfigs = [weakSelf remoteConfigsForContextKeys:contextKeys remoteConfigList:remoteConfigList includeEmptyContextKey:includeEmptyContextKey]; @@ -278,7 +278,7 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe } } - return [remoteConfigs mutableCopy]; + return [remoteConfigs copy]; } @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h index a696e352..f749d796 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h @@ -20,8 +20,6 @@ - (NSDictionary * _Nonnull)mapProducts:(NSDictionary * _Nullable)data; -- (NSDictionary * _Nullable)mapProductsEntitlementsRelationships:(NSDictionary * _Nullable)dict; - -- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary * _Nullable)data; +- (NSDictionary * _Nullable)mapProductsEntitlementsRelations:(NSDictionary * _Nullable)dict; @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m index 82f31a26..322689db 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m @@ -54,7 +54,7 @@ + (NSDictionary * _Nullable)mapProductsEntitlementsRelation:(NSDictionary * _Nul } } -- (NSDictionary * _Nullable)mapProductsEntitlementsRelationships:(NSDictionary * _Nullable)dict { +- (NSDictionary * _Nullable)mapProductsEntitlementsRelations:(NSDictionary * _Nullable)dict { return [QNMapper mapProductsEntitlementsRelation:dict]; } @@ -384,15 +384,5 @@ + (NSInteger)mapInteger:(NSObject *)object orReturn:(NSInteger)defaultValue { } } -- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { - if (![data isKindOfClass:[NSDictionary class]]) { - return nil; - } - - QONFallbackObject *fallback = [QONFallbackObject new]; - - return fallback; -} - @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h index 519e231c..f77f0df3 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @interface QONFallbackMapper : NSObject -- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data; +- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data; @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m index b03d18c1..b06ffa25 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m @@ -30,7 +30,7 @@ - (instancetype)init return self; } -- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { +- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { if (![data isKindOfClass:[NSDictionary class]]) { return nil; } @@ -39,7 +39,7 @@ - (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { fallback.products = [self.mapper mapProducts:data]; fallback.offerings = [self.mapper mapOfferings:data]; - fallback.productsEntitlementsRelation = [self.mapper mapProductsEntitlementsRelationships:data]; + fallback.productsEntitlementsRelation = [self.mapper mapProductsEntitlementsRelations:data]; NSArray *rawRemoteConfigList = data[@"remote_config_list"]; fallback.remoteConfigList = [self.remoteConfigMapper mapRemoteConfigList:rawRemoteConfigList]; From 590fd2339c52af7a1ded6c3e975d59dfae8ef067 Mon Sep 17 00:00:00 2001 From: Surik Date: Fri, 14 Jun 2024 17:45:55 +0400 Subject: [PATCH 13/25] Fixed unitialized value --- QonversionTests/StoreKitServiceTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QonversionTests/StoreKitServiceTests.m b/QonversionTests/StoreKitServiceTests.m index 84b82b81..653733f2 100644 --- a/QonversionTests/StoreKitServiceTests.m +++ b/QonversionTests/StoreKitServiceTests.m @@ -98,7 +98,7 @@ - (void)testGroupTransactions { NSArray *resultArray = resultTransactions[key]; XCTAssertEqual(expectedArray.count, resultArray.count); - for (NSUInteger i; i < expectedArray.count; i++) { + for (NSUInteger i = 0; i < expectedArray.count; i++) { NSArray *expectedTransaction = expectedArray[i]; NSArray *resultTransaction = resultArray[i]; XCTAssertEqual(expectedTransaction, resultTransaction); From 89e7eb43a4c5e5b9a0fa0c81484855c31f9b8498 Mon Sep 17 00:00:00 2001 From: Surik Date: Fri, 14 Jun 2024 17:48:36 +0400 Subject: [PATCH 14/25] Fixed import --- QonversionTests/ProductCenterManagerTests.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/QonversionTests/ProductCenterManagerTests.m b/QonversionTests/ProductCenterManagerTests.m index fd3ca790..f9eda24c 100644 --- a/QonversionTests/ProductCenterManagerTests.m +++ b/QonversionTests/ProductCenterManagerTests.m @@ -9,7 +9,7 @@ #import "QNUserInfoService.h" #import "QNIdentityManager.h" #import "QNLocalStorage.h" -#import "QONFallbacksService.h" +#import "QONFallbackService.h" #import "Helpers/XCTestCase+TestJSON.h" @interface QNProductCenterManager (Private) @@ -47,8 +47,8 @@ - (void)setUp { id mockUserInfoService = OCMClassMock([QNUserInfoService class]); id mockIdentityManager = OCMClassMock([QNIdentityManager class]); id mockLocalStorage = OCMProtocolMock(@protocol(QNLocalStorage)); - id mockFallbackService = OCMClassMock([QONFallbacksService class]); - _manager = [[QNProductCenterManager alloc] initWithUserInfoService:mockUserInfoService identityManager:mockIdentityManager localStorage:mockLocalStorage fallbacksService:mockFallbackService]; + id mockFallbackService = OCMClassMock([QONFallbackService class]); + _manager = [[QNProductCenterManager alloc] initWithUserInfoService:mockUserInfoService identityManager:mockIdentityManager localStorage:mockLocalStorage fallbackService:mockFallbackService]; [_manager setApiClient:_mockClient]; } From 56e551c885f920e8a7e7ef18e408313f47554f1d Mon Sep 17 00:00:00 2001 From: Surik Date: Fri, 14 Jun 2024 18:25:45 +0400 Subject: [PATCH 15/25] Another part of review fixes --- .../QNProductCenterManager.m | 12 +++++++++--- .../QONRemoteConfigManager.m | 16 ++++++++++------ .../Qonversion/Mappers/QNMapper/QNMapper.h | 4 ++-- .../Qonversion/Mappers/QNMapper/QNMapper.m | 4 ++-- .../QONFallbackMapper/QONFallbackMapper.h | 2 +- .../QONFallbackMapper/QONFallbackMapper.m | 6 +++--- .../QONFallbackService/QONFallbackService.m | 2 +- 7 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m index c0f0c6e7..7b11fecf 100644 --- a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m +++ b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m @@ -159,7 +159,7 @@ - (NSTimeInterval)cachedLaunchResultTimeStamp { products = cachedResult ? cachedResult.products : products; if (products.allValues.count == 0) { - self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; + self.fallbackData = [self getActualFallbackData]; products = self.fallbackData.products; } } @@ -167,6 +167,12 @@ - (NSTimeInterval)cachedLaunchResultTimeStamp { return products; } +- (QONFallbackObject *)getActualFallbackData { + self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; + + return self.fallbackData; +} + - (QONOfferings * _Nullable)getActualOfferings { QONOfferings *offerings = self.launchResult.offerings ?: nil; @@ -175,7 +181,7 @@ - (QONOfferings * _Nullable)getActualOfferings { offerings = cachedResult ? cachedResult.offerings : offerings; if (!offerings) { - self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; + self.fallbackData = [self getActualFallbackData]; offerings = self.fallbackData.offerings; } } @@ -1178,7 +1184,7 @@ - (void)handlePurchaseResult:(NSDictionary *)resul QONProduct *qonversionProduct = productsMap[transaction.payment.productIdentifier]; if (self.productsEntitlementsRelation.count == 0) { - self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; + self.fallbackData = [self getActualFallbackData]; self.productsEntitlementsRelation = self.fallbackData.productsEntitlementsRelation; } diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 65193f5e..2c017c0b 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -105,7 +105,7 @@ - (void)obtainRemoteConfigWithContextKey:(NSString * _Nullable)contextKey comple loadingState.isInProgress = NO; if (error) { if (error.shouldFireFallback) { - weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbackService obtainFallbackData]; + weakSelf.fallbackData = [weakSelf getActualFallbackData]; QONRemoteConfig *remoteConfig; if (contextKey.length == 0) { remoteConfig = [weakSelf.fallbackData.remoteConfigList remoteConfigForEmptyContextKey]; @@ -117,15 +117,13 @@ - (void)obtainRemoteConfigWithContextKey:(NSString * _Nullable)contextKey comple [weakSelf fireRemoteConfig:remoteConfig contextKey:contextKey loadingState:loadingState error:nil completion:completion]; } else { [weakSelf fireRemoteConfig:nil contextKey:contextKey loadingState:loadingState error:error completion:completion]; - return; } } else { [weakSelf fireRemoteConfig:nil contextKey:contextKey loadingState:loadingState error:error completion:completion]; - return; } + } else { + [weakSelf fireRemoteConfig:remoteConfig contextKey:contextKey loadingState:loadingState error:nil completion:completion]; } - - [weakSelf fireRemoteConfig:remoteConfig contextKey:contextKey loadingState:loadingState error:nil completion:completion]; }]; }]; } @@ -238,7 +236,7 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe return ^(QONRemoteConfigList * _Nullable remoteConfigList, NSError * _Nullable error) { if (error) { - weakSelf.fallbackData = weakSelf.fallbackData ?: [weakSelf.fallbackService obtainFallbackData]; + weakSelf.fallbackData = [weakSelf getActualFallbackData]; if (weakSelf.fallbackData.remoteConfigList) { if (contextKeys) { NSArray *remoteConfigs = [weakSelf remoteConfigsForContextKeys:contextKeys remoteConfigList:remoteConfigList includeEmptyContextKey:includeEmptyContextKey]; @@ -281,4 +279,10 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe return [remoteConfigs copy]; } +- (QONFallbackObject *)getActualFallbackData { + self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; + + return self.fallbackData; +} + @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h index f749d796..4198e18c 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.h @@ -16,9 +16,9 @@ + (NSInteger)mapInteger:(NSObject * _Nullable)object orReturn:(NSInteger)defaultValue; -- (QONOfferings * _Nonnull)mapOfferings:(NSDictionary * _Nullable)data; +- (QONOfferings * _Nonnull)mapFallbackOfferings:(NSDictionary * _Nullable)data; -- (NSDictionary * _Nonnull)mapProducts:(NSDictionary * _Nullable)data; +- (NSDictionary * _Nonnull)mapFallbackProducts:(NSDictionary * _Nullable)data; - (NSDictionary * _Nullable)mapProductsEntitlementsRelations:(NSDictionary * _Nullable)dict; diff --git a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m index 322689db..9a8df70d 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QNMapper/QNMapper.m @@ -100,7 +100,7 @@ + (QONUser *)fillUser:(NSDictionary * _Nullable)dict { return [products copy]; } -- (NSDictionary * _Nonnull)mapProducts:(NSDictionary * _Nullable)data { +- (NSDictionary * _Nonnull)mapFallbackProducts:(NSDictionary * _Nullable)data { NSArray *rawProducts = data[@"products"]; return [QNMapper fillProducts:rawProducts]; } @@ -303,7 +303,7 @@ + (QONOfferings * _Nonnull)fillOfferingsObject:(NSArray *)data { return offerings; } -- (QONOfferings * _Nonnull)mapOfferings:(NSDictionary * _Nullable)data { +- (QONOfferings * _Nonnull)mapFallbackOfferings:(NSDictionary * _Nullable)data { NSArray *rawOfferings = data[@"offerings"]; return [QNMapper fillOfferingsObject:rawOfferings]; } diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h index f77f0df3..cdc0869d 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.h @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @interface QONFallbackMapper : NSObject -- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data; +- (QONFallbackObject * _Nullable)mapFallbackData:(NSDictionary *)data; @end diff --git a/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m index b06ffa25..409a1d81 100644 --- a/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m +++ b/Sources/Qonversion/Qonversion/Mappers/QONFallbackMapper/QONFallbackMapper.m @@ -30,15 +30,15 @@ - (instancetype)init return self; } -- (QONFallbackObject * _Nullable)mapFallback:(NSDictionary *)data { +- (QONFallbackObject * _Nullable)mapFallbackData:(NSDictionary *)data { if (![data isKindOfClass:[NSDictionary class]]) { return nil; } QONFallbackObject *fallback = [QONFallbackObject new]; - fallback.products = [self.mapper mapProducts:data]; - fallback.offerings = [self.mapper mapOfferings:data]; + fallback.products = [self.mapper mapFallbackProducts:data]; + fallback.offerings = [self.mapper mapFallbackOfferings:data]; fallback.productsEntitlementsRelation = [self.mapper mapProductsEntitlementsRelations:data]; NSArray *rawRemoteConfigList = data[@"remote_config_list"]; diff --git a/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m index 6bcb4745..dd3298fe 100644 --- a/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m +++ b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m @@ -39,7 +39,7 @@ - (QONFallbackObject * _Nullable)obtainFallbackData { NSDictionary *resultMap = [NSJSONSerialization JSONObjectWithData:fileData options:kNilOptions error:nil]; - QONFallbackObject *resultObject = [self.mapper mapFallback:resultMap]; + QONFallbackObject *resultObject = [self.mapper mapFallbackData:resultMap]; return resultObject; } From 31e792119529f3c6f2f72b262ee488ae8306949e Mon Sep 17 00:00:00 2001 From: Surik Date: Mon, 17 Jun 2024 14:39:54 +0400 Subject: [PATCH 16/25] Updated get actual fallback data function logic --- .../QNProductCenterManager/QNProductCenterManager.m | 10 ++++------ .../QONRemoteConfigManager/QONRemoteConfigManager.m | 8 +++----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m index 7b11fecf..1abffac7 100644 --- a/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m +++ b/Sources/Qonversion/Qonversion/Main/QNProductCenterManager/QNProductCenterManager.m @@ -159,7 +159,7 @@ - (NSTimeInterval)cachedLaunchResultTimeStamp { products = cachedResult ? cachedResult.products : products; if (products.allValues.count == 0) { - self.fallbackData = [self getActualFallbackData]; + [self actualizeFallbackData]; products = self.fallbackData.products; } } @@ -167,10 +167,8 @@ - (NSTimeInterval)cachedLaunchResultTimeStamp { return products; } -- (QONFallbackObject *)getActualFallbackData { +- (void)actualizeFallbackData { self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; - - return self.fallbackData; } - (QONOfferings * _Nullable)getActualOfferings { @@ -181,7 +179,7 @@ - (QONOfferings * _Nullable)getActualOfferings { offerings = cachedResult ? cachedResult.offerings : offerings; if (!offerings) { - self.fallbackData = [self getActualFallbackData]; + [self actualizeFallbackData]; offerings = self.fallbackData.offerings; } } @@ -1184,7 +1182,7 @@ - (void)handlePurchaseResult:(NSDictionary *)resul QONProduct *qonversionProduct = productsMap[transaction.payment.productIdentifier]; if (self.productsEntitlementsRelation.count == 0) { - self.fallbackData = [self getActualFallbackData]; + [self actualizeFallbackData]; self.productsEntitlementsRelation = self.fallbackData.productsEntitlementsRelation; } diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 2c017c0b..b49501a8 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -105,7 +105,7 @@ - (void)obtainRemoteConfigWithContextKey:(NSString * _Nullable)contextKey comple loadingState.isInProgress = NO; if (error) { if (error.shouldFireFallback) { - weakSelf.fallbackData = [weakSelf getActualFallbackData]; + [weakSelf actualizeFallbackData]; QONRemoteConfig *remoteConfig; if (contextKey.length == 0) { remoteConfig = [weakSelf.fallbackData.remoteConfigList remoteConfigForEmptyContextKey]; @@ -236,7 +236,7 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe return ^(QONRemoteConfigList * _Nullable remoteConfigList, NSError * _Nullable error) { if (error) { - weakSelf.fallbackData = [weakSelf getActualFallbackData]; + [weakSelf actualizeFallbackData]; if (weakSelf.fallbackData.remoteConfigList) { if (contextKeys) { NSArray *remoteConfigs = [weakSelf remoteConfigsForContextKeys:contextKeys remoteConfigList:remoteConfigList includeEmptyContextKey:includeEmptyContextKey]; @@ -279,10 +279,8 @@ - (QONRemoteConfigListCompletionHandler)remoteConfigListCompletionWrapper:(QONRe return [remoteConfigs copy]; } -- (QONFallbackObject *)getActualFallbackData { +- (void)actualizeFallbackData { self.fallbackData = self.fallbackData ?: [self.fallbackService obtainFallbackData]; - - return self.fallbackData; } @end From a94b744e6202e1ff50f0fda743087c7bee3465a6 Mon Sep 17 00:00:00 2001 From: Surik Date: Tue, 18 Jun 2024 15:55:02 +0400 Subject: [PATCH 17/25] Updated fallback file --- Sample/qonversion_fallbacks.json | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Sample/qonversion_fallbacks.json b/Sample/qonversion_fallbacks.json index 86c31bb4..d6f40bd6 100644 --- a/Sample/qonversion_fallbacks.json +++ b/Sample/qonversion_fallbacks.json @@ -1,5 +1,4 @@ { - "timestamp": 1586369519, "products": [ { "duration": 4, @@ -37,7 +36,7 @@ "type": 0 }, { - "duration": "", + "duration": null, "id": "consumable", "store_id": "io.qonversion.consumable", "type": 2 @@ -68,12 +67,12 @@ }, "remote_config_list": [ { - "experiment": "", + "experiment": null, "payload": { "CTA": "Start you trial", "CTA_color": "red", - "main_image": 111, - "product_id": 123123123123123, + "main_image": "111", + "product_id": "123123123123123", "show_close_button": 1 }, "source": { @@ -85,12 +84,12 @@ } }, { - "experiment": "", + "experiment": null, "payload": { "CTA": "New test", "CTA_color": "blue", - "main_image": 1111, - "product_id": 2332, + "main_image": "1111", + "product_id": "2332", "show_close_button": 1 }, "source": { @@ -102,12 +101,12 @@ } }, { - "experiment": "", + "experiment": null, "payload": { "CTA": "One more test", "CTA_color": "yellow", - "main_image": 1111, - "product_id": 2332, + "main_image": "1111", + "product_id": "2332", "show_close_button": 1 }, "source": { From 5c0cfd72f8ccfa18e86746029d4b961406af852f Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 27 Jun 2024 19:20:17 +0400 Subject: [PATCH 18/25] Fixed nil file handling --- Qonversion.xcodeproj/project.pbxproj | 8 +- Sample/qonversion_fallbacks.json | 272 ++++++++++-------- .../QONFallbackService/QONFallbackService.m | 4 + 3 files changed, 168 insertions(+), 116 deletions(-) diff --git a/Qonversion.xcodeproj/project.pbxproj b/Qonversion.xcodeproj/project.pbxproj index 2eb0d98c..a91bfd3a 100644 --- a/Qonversion.xcodeproj/project.pbxproj +++ b/Qonversion.xcodeproj/project.pbxproj @@ -68,7 +68,6 @@ 70283DF729F66FAC00D138BC /* PurchasesMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70283DF629F66FAC00D138BC /* PurchasesMapper.swift */; }; 702BF8B629531A68000B6C3E /* QONScreenCustomizationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 702BF8B529531A68000B6C3E /* QONScreenCustomizationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 702DBDEC2A3216C900D590D0 /* QONExperiment+Protected.h in Headers */ = {isa = PBXBuildFile; fileRef = 702DBDEB2A3216C900D590D0 /* QONExperiment+Protected.h */; }; - 703666202C17512200B0C503 /* qonversion_fallbacks.json in Resources */ = {isa = PBXBuildFile; fileRef = 7036661F2C17512200B0C503 /* qonversion_fallbacks.json */; }; 7042E7822C1C5DB700C5AECF /* QONFallbackService.h in Headers */ = {isa = PBXBuildFile; fileRef = 7042E77F2C1C5DB700C5AECF /* QONFallbackService.h */; }; 7042E7832C1C5DB700C5AECF /* QONFallbackService.m in Sources */ = {isa = PBXBuildFile; fileRef = 7042E7802C1C5DB700C5AECF /* QONFallbackService.m */; }; 7042E7872C1C5DDE00C5AECF /* QONFallbackMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 7042E7842C1C5DDE00C5AECF /* QONFallbackMapper.h */; }; @@ -92,6 +91,7 @@ 70B9A9F1297AB8A700BD30FD /* QONAutomationsNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 70B9A9EF297AB8A700BD30FD /* QONAutomationsNavigationController.h */; }; 70B9A9F2297AB8A700BD30FD /* QONAutomationsNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 70B9A9F0297AB8A700BD30FD /* QONAutomationsNavigationController.m */; }; 70BAB0642B58306E00D19A6A /* expected_entitlements.json in Resources */ = {isa = PBXBuildFile; fileRef = 70893C992B3EC136002C6B82 /* expected_entitlements.json */; }; + 70CB7CE42C2DB37A00241FF1 /* qonversion_fallbacks.json in Resources */ = {isa = PBXBuildFile; fileRef = 70CB7CE32C2DB37900241FF1 /* qonversion_fallbacks.json */; }; 70D05A8E29C9FC1600EA5DDF /* QONRemoteConfigManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 70D05A8C29C9FC1600EA5DDF /* QONRemoteConfigManager.h */; }; 70D05A8F29C9FC1600EA5DDF /* QONRemoteConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 70D05A8D29C9FC1600EA5DDF /* QONRemoteConfigManager.m */; }; 70D05A9329C9FF3C00EA5DDF /* QONRemoteConfigService.h in Headers */ = {isa = PBXBuildFile; fileRef = 70D05A9129C9FF3C00EA5DDF /* QONRemoteConfigService.h */; }; @@ -390,7 +390,6 @@ 70283DF629F66FAC00D138BC /* PurchasesMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PurchasesMapper.swift; sourceTree = ""; }; 702BF8B529531A68000B6C3E /* QONScreenCustomizationDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONScreenCustomizationDelegate.h; sourceTree = ""; }; 702DBDEB2A3216C900D590D0 /* QONExperiment+Protected.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QONExperiment+Protected.h"; sourceTree = ""; }; - 7036661F2C17512200B0C503 /* qonversion_fallbacks.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = qonversion_fallbacks.json; sourceTree = ""; }; 7042E77F2C1C5DB700C5AECF /* QONFallbackService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QONFallbackService.h; sourceTree = ""; }; 7042E7802C1C5DB700C5AECF /* QONFallbackService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QONFallbackService.m; sourceTree = ""; }; 7042E7842C1C5DDE00C5AECF /* QONFallbackMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QONFallbackMapper.h; sourceTree = ""; }; @@ -414,6 +413,7 @@ 70B917662B34284200BF0689 /* QONTransaction+Protected.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QONTransaction+Protected.h"; sourceTree = ""; }; 70B9A9EF297AB8A700BD30FD /* QONAutomationsNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONAutomationsNavigationController.h; sourceTree = ""; }; 70B9A9F0297AB8A700BD30FD /* QONAutomationsNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONAutomationsNavigationController.m; sourceTree = ""; }; + 70CB7CE32C2DB37900241FF1 /* qonversion_fallbacks.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = qonversion_fallbacks.json; sourceTree = ""; }; 70D05A8C29C9FC1600EA5DDF /* QONRemoteConfigManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigManager.h; sourceTree = ""; }; 70D05A8D29C9FC1600EA5DDF /* QONRemoteConfigManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRemoteConfigManager.m; sourceTree = ""; }; 70D05A9129C9FF3C00EA5DDF /* QONRemoteConfigService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigService.h; sourceTree = ""; }; @@ -641,7 +641,7 @@ 454EF63D24E5CC580070581E /* Sample */ = { isa = PBXGroup; children = ( - 7036661F2C17512200B0C503 /* qonversion_fallbacks.json */, + 70CB7CE32C2DB37900241FF1 /* qonversion_fallbacks.json */, 456215C8257D6AF800548A3D /* Sample.entitlements */, 454EF63E24E5CC580070581E /* AppDelegate.swift */, 454EF64224E5CC590070581E /* ViewController.swift */, @@ -1898,7 +1898,7 @@ 454EF64B24E5CC5A0070581E /* LaunchScreen.storyboard in Resources */, 894278822759334D00A8A6EC /* GoogleService-Info.plist in Resources */, 454EF64824E5CC5A0070581E /* Assets.xcassets in Resources */, - 703666202C17512200B0C503 /* qonversion_fallbacks.json in Resources */, + 70CB7CE42C2DB37A00241FF1 /* qonversion_fallbacks.json in Resources */, 454EF64624E5CC590070581E /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sample/qonversion_fallbacks.json b/Sample/qonversion_fallbacks.json index d6f40bd6..63c45e40 100644 --- a/Sample/qonversion_fallbacks.json +++ b/Sample/qonversion_fallbacks.json @@ -1,121 +1,169 @@ { - "products": [ + "products": [ + { + "id": "weekly", + "duration": 0, + "store_id": "io.qonversion.weekly", + "type": 1 + }, + { + "id": "consumable", + "duration": null, + "store_id": "io.qonversion.consumable", + "type": 2 + }, + { + "id": "subs_plus_trial", + "duration": 1, + "store_id": "io.qonversion.subs.monthly.plus.trial", + "type": 0 + }, + { + "id": "annual", + "duration": 4, + "store_id": "io.qonversion.subs.annual", + "type": 0 + }, + { + "id": "in_app", + "duration": null, + "store_id": "io.qonversion.nonconsumable", + "type": 2 + } + ], + "offerings": [ + { + "id": "main", + "tag": 1, + "products": [ { - "duration": 4, - "id": "annual", - "store_id": "io.qonversion.subs.annual", - "type": 0 + "id": "weekly", + "duration": 0, + "store_id": "io.qonversion.weekly", + "type": 1 }, { - "duration": 1, - "id": "subs_plus_trial", - "store_id": "io.qonversion.subs.monthly.plus.trial", - "type": 0 + "id": "annual", + "duration": 4, + "store_id": "io.qonversion.subs.annual", + "type": 0 }, { - "duration": 0, - "id": "weekly", - "store_id": "io.qonversion.weekly", - "type": 1 + "id": "consumable", + "duration": null, + "store_id": "io.qonversion.consumable", + "type": 2 } - ], - "offerings": [ - { - "id": "main", - "products": [ - { - "duration": 0, - "id": "weekly", - "store_id": "io.qonversion.weekly", - "type": 1 - }, - { - "duration": 4, - "id": "annual", - "store_id": "io.qonversion.subs.annual", - "type": 0 - }, - { - "duration": null, - "id": "consumable", - "store_id": "io.qonversion.consumable", - "type": 2 - } - ], - "tag": 1 - }, - { - "id": "discounted_offer", - "products": [], - "tag": 0 - } - ], - "products_permissions": { - "annual": [ - "standart", - "sample" - ], - "annual": [ - "standart" - ], - "subs_plus_trial": [ - "standart" - ], - "weekly": [ - "plus" - ] + ] }, - "remote_config_list": [ - { - "experiment": null, - "payload": { - "CTA": "Start you trial", - "CTA_color": "red", - "main_image": "111", - "product_id": "123123123123123", - "show_close_button": 1 - }, - "source": { - "assignment_type": "auto", - "context_key": "", - "name": "Default settings", - "type": "remote_configuration", - "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" - } - }, - { - "experiment": null, - "payload": { - "CTA": "New test", - "CTA_color": "blue", - "main_image": "1111", - "product_id": "2332", - "show_close_button": 1 - }, - "source": { - "assignment_type": "auto", - "context_key": "new_test", - "name": "Default settings", - "type": "remote_configuration", - "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" - } - }, - { - "experiment": null, - "payload": { - "CTA": "One more test", - "CTA_color": "yellow", - "main_image": "1111", - "product_id": "2332", - "show_close_button": 1 - }, - "source": { - "assignment_type": "auto", - "context_key": "one_more_test", - "name": "Default settings", - "type": "remote_configuration", - "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" - } + { + "id": "discounted_offer", + "tag": 0, + "products": [] + } + ], + "products_permissions": [ + { + "weekly": [ + "plus" + ] + }, + { + "consumable": [] + }, + { + "subs_plus_trial": [ + "standart" + ] + }, + { + "annual": [ + "standart", + "sample" + ] + }, + { + "in_app": [ + "Premium Movies" + ] + } + ], + "remote_config_list": [ + { + "experiment": null, + "payload": { + "CTA": "Start Trial", + "CTA_color": "#307BF6", + "main_image": "[IMAGE_URL]", + "product_id": "prod_7d_trial_5.99", + "show_close_button": true + }, + "source": { + "assignment_type": "auto", + "context_key": "main_paywall", + "name": "default paywall", + "type": "remote_configuration", + "uid": "0dcb1bd9-9bc3-4668-84aa-4540d1042c5d" + } + }, + { + "experiment": null, + "payload": { + "CTA": "Start you trial", + "CTA_color": "red", + "main_image": "111", + "product_id": "123123123123123", + "show_close_button": true + }, + "source": { + "assignment_type": "auto", + "context_key": "", + "name": "Default settings", + "type": "remote_configuration", + "uid": "12feb1dd-8096-47bc-a5a1-443fd2828ecc" + } + }, + { + "experiment": null, + "payload": { + "test_key": "test_value" + }, + "source": { + "assignment_type": "auto", + "context_key": "test_context_key", + "name": "Test with context key1", + "type": "remote_configuration", + "uid": "c5077ec4-acf4-41ea-8b43-05114be5d7ce" + } + }, + { + "experiment": null, + "payload": { + "test_key_2": "test_value_2" + }, + "source": { + "assignment_type": "auto", + "context_key": "test_context_key_2", + "name": "Test with context key2 - copy", + "type": "remote_configuration", + "uid": "1c000f2a-2f4b-4736-b5dd-75b13bf73deb" + } + }, + { + "experiment": null, + "payload": { + "bool": true, + "json": { + "key": "value" } - ] -} + }, + "source": { + "assignment_type": "auto", + "context_key": "swift_key ", + "name": "Swift", + "type": "remote_configuration", + "uid": "9f85d738-56d8-4f6c-b54a-c08658be2cb4" + } + } + ] +} \ No newline at end of file diff --git a/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m index dd3298fe..66c1f57a 100644 --- a/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m +++ b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m @@ -37,6 +37,10 @@ - (QONFallbackObject * _Nullable)obtainFallbackData { NSData *fileData = [NSData dataWithContentsOfFile:pathToFile]; + if (!fileData) { + return nil; + } + NSDictionary *resultMap = [NSJSONSerialization JSONObjectWithData:fileData options:kNilOptions error:nil]; QONFallbackObject *resultObject = [self.mapper mapFallbackData:resultMap]; From 40fe28a0ea93bcef80707eba6b6a0a67cd1a75a8 Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 27 Jun 2024 21:24:44 +0400 Subject: [PATCH 19/25] Fixed fallback file --- Sample/qonversion_fallbacks.json | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/Sample/qonversion_fallbacks.json b/Sample/qonversion_fallbacks.json index 63c45e40..736e4fef 100644 --- a/Sample/qonversion_fallbacks.json +++ b/Sample/qonversion_fallbacks.json @@ -62,32 +62,22 @@ "products": [] } ], - "products_permissions": [ - { + "products_permissions": { "weekly": [ "plus" - ] - }, - { - "consumable": [] - }, - { + ], + "consumable": [], "subs_plus_trial": [ "standart" - ] - }, - { + ], "annual": [ "standart", "sample" - ] - }, - { + ], "in_app": [ "Premium Movies" ] - } - ], + }, "remote_config_list": [ { "experiment": null, @@ -166,4 +156,4 @@ } } ] -} \ No newline at end of file +} From 25c7452cf4f74f2148edfc0d5ae5a2a32399e7f0 Mon Sep 17 00:00:00 2001 From: Surik Date: Fri, 28 Jun 2024 17:45:09 +0400 Subject: [PATCH 20/25] Fixed platform check for mac catalyst --- .../Qonversion/Utils/QNDevice/QNDevice.m | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Sources/Qonversion/Qonversion/Utils/QNDevice/QNDevice.m b/Sources/Qonversion/Qonversion/Utils/QNDevice/QNDevice.m index 15e0e9cf..3c098a13 100644 --- a/Sources/Qonversion/Qonversion/Utils/QNDevice/QNDevice.m +++ b/Sources/Qonversion/Qonversion/Utils/QNDevice/QNDevice.m @@ -323,6 +323,22 @@ + (NSString*)getVendorID:(int) maxAttempts { } + (NSString*)getPlatformString { +#if TARGET_OS_MACCATALYST + io_service_t service = IOServiceGetMatchingService(kIOMainPortDefault, + IOServiceMatching("IOPlatformExpertDevice")); + CFStringRef model = IORegistryEntryCreateCFProperty(service, + CFSTR("model"), + kCFAllocatorDefault, + 0); + + NSString *modelIdentifier = [[NSString alloc] initWithData:(__bridge NSData *)model + encoding:NSUTF8StringEncoding]; + + CFRelease(model); + IOObjectRelease(service); + + return modelIdentifier; +#else #if UI_DEVICE const char *sysctl_name = "hw.machine"; #else @@ -335,6 +351,7 @@ + (NSString*)getPlatformString { NSString *platform = [NSString stringWithUTF8String:machine]; free(machine); return platform; +#endif } + (NSString*)getDeviceModel { From a711e67cebcb1106ea2d23956d670c4881c38312 Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 4 Jul 2024 14:32:05 +0400 Subject: [PATCH 21/25] Added function to check if fallback file is accessible + renamed file and mapping --- ...sion_fallbacks.json => qonversion_ios_fallbacks.json} | 0 Sources/Qonversion/Public/Qonversion.h | 6 ++++++ Sources/Qonversion/Public/Qonversion.m | 9 ++++++++- .../Services/QONFallbackService/QONFallbackService.m | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) rename Sample/{qonversion_fallbacks.json => qonversion_ios_fallbacks.json} (100%) diff --git a/Sample/qonversion_fallbacks.json b/Sample/qonversion_ios_fallbacks.json similarity index 100% rename from Sample/qonversion_fallbacks.json rename to Sample/qonversion_ios_fallbacks.json diff --git a/Sources/Qonversion/Public/Qonversion.h b/Sources/Qonversion/Public/Qonversion.h index 4f41ba26..58981d40 100644 --- a/Sources/Qonversion/Public/Qonversion.h +++ b/Sources/Qonversion/Public/Qonversion.h @@ -291,6 +291,12 @@ NS_SWIFT_NAME(remoteConfigList(contextKeys:includeEmptyContextKey:completion:)); */ - (void)handlePurchases:(NSArray *)purchasesInfo completion:(nullable QONDefaultCompletionHandler)completion; +/** + Call this function to check if fallback file is accessible. + @return flag that indicates if fallbacke file is accessible or not. + */ +- (BOOL)isFallbackFileAccessible; + @end NS_ASSUME_NONNULL_END diff --git a/Sources/Qonversion/Public/Qonversion.m b/Sources/Qonversion/Public/Qonversion.m index 43056803..5c5137d8 100644 --- a/Sources/Qonversion/Public/Qonversion.m +++ b/Sources/Qonversion/Public/Qonversion.m @@ -27,7 +27,7 @@ @interface Qonversion() @property (nonatomic, strong) QONExceptionManager *exceptionManager; @property (nonatomic, strong) id userInfoService; @property (nonatomic, strong) id localStorage; - +@property (nonatomic, strong) QONFallbackService *fallbackService; @property (nonatomic, assign) BOOL debugMode; @property (nonatomic, assign) QONLaunchMode launchMode; @@ -240,6 +240,12 @@ - (void)handlePurchases:(NSArray *)purchasesInfo co [[self productCenterManager] handlePurchases:purchasesInfo completion:completion]; } +- (BOOL)isFallbackFileAccessible { + QONFallbackObject *fallbackData = [self.fallbackService obtainFallbackData]; + + return fallbackData != nil; +} + // MARK: - Private - (instancetype)initWithCustomUserDefaults:(NSUserDefaults *)userDefaults { @@ -252,6 +258,7 @@ - (instancetype)initWithCustomUserDefaults:(NSUserDefaults *)userDefaults { id identityManager = [servicesAssembly identityManager]; QONFallbackService *fallbackService = [QONFallbackService new]; _productCenterManager = [[QNProductCenterManager alloc] initWithUserInfoService:_userInfoService identityManager:identityManager localStorage:_localStorage fallbackService:fallbackService]; + _fallbackService = fallbackService; _propertiesManager = [QNUserPropertiesManager new]; _attributionManager = [QNAttributionManager new]; _remoteConfigManager = [QONRemoteConfigManager new]; diff --git a/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m index 66c1f57a..99efa822 100644 --- a/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m +++ b/Sources/Qonversion/Qonversion/Services/QONFallbackService/QONFallbackService.m @@ -10,7 +10,7 @@ #import "QONFallbackObject.h" #import "QONFallbackMapper.h" -NSString *const kFallbacksFileName = @"qonversion_fallbacks.json"; +NSString *const kFallbacksFileName = @"qonversion_ios_fallbacks.json"; @interface QONFallbackService () From 61a956bb16883ab468664340f796d01a0c9dbca2 Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 4 Jul 2024 14:37:04 +0400 Subject: [PATCH 22/25] Updated file name proj fix --- Qonversion.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Qonversion.xcodeproj/project.pbxproj b/Qonversion.xcodeproj/project.pbxproj index a91bfd3a..a44040d9 100644 --- a/Qonversion.xcodeproj/project.pbxproj +++ b/Qonversion.xcodeproj/project.pbxproj @@ -91,7 +91,7 @@ 70B9A9F1297AB8A700BD30FD /* QONAutomationsNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 70B9A9EF297AB8A700BD30FD /* QONAutomationsNavigationController.h */; }; 70B9A9F2297AB8A700BD30FD /* QONAutomationsNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 70B9A9F0297AB8A700BD30FD /* QONAutomationsNavigationController.m */; }; 70BAB0642B58306E00D19A6A /* expected_entitlements.json in Resources */ = {isa = PBXBuildFile; fileRef = 70893C992B3EC136002C6B82 /* expected_entitlements.json */; }; - 70CB7CE42C2DB37A00241FF1 /* qonversion_fallbacks.json in Resources */ = {isa = PBXBuildFile; fileRef = 70CB7CE32C2DB37900241FF1 /* qonversion_fallbacks.json */; }; + 70CB7CE42C2DB37A00241FF1 /* qonversion_ios_fallbacks.json in Resources */ = {isa = PBXBuildFile; fileRef = 70CB7CE32C2DB37900241FF1 /* qonversion_ios_fallbacks.json */; }; 70D05A8E29C9FC1600EA5DDF /* QONRemoteConfigManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 70D05A8C29C9FC1600EA5DDF /* QONRemoteConfigManager.h */; }; 70D05A8F29C9FC1600EA5DDF /* QONRemoteConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 70D05A8D29C9FC1600EA5DDF /* QONRemoteConfigManager.m */; }; 70D05A9329C9FF3C00EA5DDF /* QONRemoteConfigService.h in Headers */ = {isa = PBXBuildFile; fileRef = 70D05A9129C9FF3C00EA5DDF /* QONRemoteConfigService.h */; }; @@ -413,7 +413,7 @@ 70B917662B34284200BF0689 /* QONTransaction+Protected.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QONTransaction+Protected.h"; sourceTree = ""; }; 70B9A9EF297AB8A700BD30FD /* QONAutomationsNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONAutomationsNavigationController.h; sourceTree = ""; }; 70B9A9F0297AB8A700BD30FD /* QONAutomationsNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONAutomationsNavigationController.m; sourceTree = ""; }; - 70CB7CE32C2DB37900241FF1 /* qonversion_fallbacks.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = qonversion_fallbacks.json; sourceTree = ""; }; + 70CB7CE32C2DB37900241FF1 /* qonversion_ios_fallbacks.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = qonversion_ios_fallbacks.json; sourceTree = ""; }; 70D05A8C29C9FC1600EA5DDF /* QONRemoteConfigManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigManager.h; sourceTree = ""; }; 70D05A8D29C9FC1600EA5DDF /* QONRemoteConfigManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRemoteConfigManager.m; sourceTree = ""; }; 70D05A9129C9FF3C00EA5DDF /* QONRemoteConfigService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigService.h; sourceTree = ""; }; @@ -641,7 +641,7 @@ 454EF63D24E5CC580070581E /* Sample */ = { isa = PBXGroup; children = ( - 70CB7CE32C2DB37900241FF1 /* qonversion_fallbacks.json */, + 70CB7CE32C2DB37900241FF1 /* qonversion_ios_fallbacks.json */, 456215C8257D6AF800548A3D /* Sample.entitlements */, 454EF63E24E5CC580070581E /* AppDelegate.swift */, 454EF64224E5CC590070581E /* ViewController.swift */, @@ -1898,7 +1898,7 @@ 454EF64B24E5CC5A0070581E /* LaunchScreen.storyboard in Resources */, 894278822759334D00A8A6EC /* GoogleService-Info.plist in Resources */, 454EF64824E5CC5A0070581E /* Assets.xcassets in Resources */, - 70CB7CE42C2DB37A00241FF1 /* qonversion_fallbacks.json in Resources */, + 70CB7CE42C2DB37A00241FF1 /* qonversion_ios_fallbacks.json in Resources */, 454EF64624E5CC590070581E /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; From e765913066bb4fa16feaf16fbcd49b6af9bb1c2a Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 4 Jul 2024 14:44:05 +0400 Subject: [PATCH 23/25] Fixed typo --- Sources/Qonversion/Public/Qonversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Qonversion/Public/Qonversion.h b/Sources/Qonversion/Public/Qonversion.h index 58981d40..7a3c19cf 100644 --- a/Sources/Qonversion/Public/Qonversion.h +++ b/Sources/Qonversion/Public/Qonversion.h @@ -293,7 +293,7 @@ NS_SWIFT_NAME(remoteConfigList(contextKeys:includeEmptyContextKey:completion:)); /** Call this function to check if fallback file is accessible. - @return flag that indicates if fallbacke file is accessible or not. + @return flag that indicates if fallback file is accessible or not. */ - (BOOL)isFallbackFileAccessible; From 55442c4d9478c3a53594eaaf4d0c07e5e1aa375e Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 4 Jul 2024 14:46:49 +0400 Subject: [PATCH 24/25] Updated comment --- Sources/Qonversion/Public/Qonversion.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Qonversion/Public/Qonversion.h b/Sources/Qonversion/Public/Qonversion.h index 7a3c19cf..837e4abd 100644 --- a/Sources/Qonversion/Public/Qonversion.h +++ b/Sources/Qonversion/Public/Qonversion.h @@ -292,8 +292,8 @@ NS_SWIFT_NAME(remoteConfigList(contextKeys:includeEmptyContextKey:completion:)); - (void)handlePurchases:(NSArray *)purchasesInfo completion:(nullable QONDefaultCompletionHandler)completion; /** - Call this function to check if fallback file is accessible. - @return flag that indicates if fallback file is accessible or not. + Call this function to check if the fallback file is accessible. + @return flag that indicates whether Qonversion was able to read data from the fallback file or not. */ - (BOOL)isFallbackFileAccessible; From c6cd89caea70c549bce45ec686879fe8c5e11dee Mon Sep 17 00:00:00 2001 From: SpertsyanKM Date: Fri, 5 Jul 2024 09:27:03 +0000 Subject: [PATCH 25/25] [create-pull-request] automated change --- Framework/Info.plist | 2 +- Qonversion.podspec | 2 +- Sources/Qonversion/Public/QONConfiguration.m | 2 +- fastlane/report.xml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Framework/Info.plist b/Framework/Info.plist index 396a9669..3b73fb1b 100644 --- a/Framework/Info.plist +++ b/Framework/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 5.10.1 + 5.11.0 CFBundleSignature ???? CFBundleVersion diff --git a/Qonversion.podspec b/Qonversion.podspec index d8503b3d..9041f8b9 100644 --- a/Qonversion.podspec +++ b/Qonversion.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| idfa_exclude_files = ['Sources/Qonversion/IDFA'] s.name = 'Qonversion' s.swift_version = '5.5' - s.version = '5.10.1' + s.version = '5.11.0' s.summary = 'qonversion.io' s.description = <<-DESC Deep Analytics for iOS Subscriptions diff --git a/Sources/Qonversion/Public/QONConfiguration.m b/Sources/Qonversion/Public/QONConfiguration.m index 8d5841b9..c05046bd 100644 --- a/Sources/Qonversion/Public/QONConfiguration.m +++ b/Sources/Qonversion/Public/QONConfiguration.m @@ -9,7 +9,7 @@ #import "QONConfiguration.h" #import "QNAPIConstants.h" -static NSString *const kSDKVersion = @"5.10.1"; +static NSString *const kSDKVersion = @"5.11.0"; @interface QONConfiguration () diff --git a/fastlane/report.xml b/fastlane/report.xml index 51b2b863..58bcc58e 100644 --- a/fastlane/report.xml +++ b/fastlane/report.xml @@ -5,12 +5,12 @@ - + - +