From 0146dc890284e6f1dd78c7315bd26fa5b51151a9 Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Tue, 2 Apr 2024 18:13:53 +0300 Subject: [PATCH 1/2] Added user stability check for remote config list requests. (#483) * Added user stability check for remote config list requests. * CR fixes --- Podfile.lock | 2 +- Qonversion.xcodeproj/project.pbxproj | 8 +++++ .../QONRemoteConfigListRequestData.h | 26 +++++++++++++++ .../QONRemoteConfigListRequestData.m | 31 ++++++++++++++++++ .../QONRemoteConfigLoadingState.h | 5 ++- .../QONRemoteConfigManager.m | 32 ++++++++++++++++++- 6 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigListRequestData.h create mode 100644 Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigListRequestData.m diff --git a/Podfile.lock b/Podfile.lock index f9c97b09..2bacb10b 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -97,4 +97,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 578415250db59f137d92c9b1ce32646ae18974ba -COCOAPODS: 1.11.3 +COCOAPODS: 1.13.0 diff --git a/Qonversion.xcodeproj/project.pbxproj b/Qonversion.xcodeproj/project.pbxproj index 55a11dc1..54a34c22 100644 --- a/Qonversion.xcodeproj/project.pbxproj +++ b/Qonversion.xcodeproj/project.pbxproj @@ -40,6 +40,8 @@ 4CADC5602759181A004FDC10 /* AuthViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CADC55F2759181A004FDC10 /* AuthViewController.swift */; }; 6A121DAC2BB445AE0073B330 /* QONRemoteConfigList.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A121DAB2BB445AE0073B330 /* QONRemoteConfigList.m */; }; 6A121DAE2BB446740073B330 /* QONRemoteConfigList.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A121DAD2BB446740073B330 /* QONRemoteConfigList.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6A121DB12BBB10370073B330 /* QONRemoteConfigListRequestData.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A121DB02BBB10370073B330 /* QONRemoteConfigListRequestData.h */; }; + 6A121DB32BBB10AA0073B330 /* QONRemoteConfigListRequestData.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A121DB22BBB10AA0073B330 /* QONRemoteConfigListRequestData.m */; }; 6A21BF4C2AB201A7005BDA7C /* QONRateLimiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A21BF4B2AB201A7005BDA7C /* QONRateLimiter.h */; }; 6A21BF4E2AB20483005BDA7C /* QONRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A21BF4D2AB20483005BDA7C /* QONRateLimiter.m */; }; 6A21BF532AB2059F005BDA7C /* QONRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A21BF522AB2059F005BDA7C /* QONRequest.h */; }; @@ -348,6 +350,8 @@ 6A121DAB2BB445AE0073B330 /* QONRemoteConfigList.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRemoteConfigList.m; sourceTree = ""; }; 6A121DAD2BB446740073B330 /* QONRemoteConfigList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigList.h; sourceTree = ""; }; 6A121DAF2BB44D7B0073B330 /* QONRemoteConfigList+protected.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QONRemoteConfigList+protected.h"; sourceTree = ""; }; + 6A121DB02BBB10370073B330 /* QONRemoteConfigListRequestData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRemoteConfigListRequestData.h; sourceTree = ""; }; + 6A121DB22BBB10AA0073B330 /* QONRemoteConfigListRequestData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRemoteConfigListRequestData.m; sourceTree = ""; }; 6A21BF4B2AB201A7005BDA7C /* QONRateLimiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRateLimiter.h; sourceTree = ""; }; 6A21BF4D2AB20483005BDA7C /* QONRateLimiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QONRateLimiter.m; sourceTree = ""; }; 6A21BF522AB2059F005BDA7C /* QONRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QONRequest.h; sourceTree = ""; }; @@ -907,6 +911,8 @@ 70D05A8D29C9FC1600EA5DDF /* QONRemoteConfigManager.m */, 6ABCBE162B99A79E003DB107 /* QONRemoteConfigLoadingState.h */, 6ABCBE172B99A79E003DB107 /* QONRemoteConfigLoadingState.m */, + 6A121DB02BBB10370073B330 /* QONRemoteConfigListRequestData.h */, + 6A121DB22BBB10AA0073B330 /* QONRemoteConfigListRequestData.m */, ); path = QONRemoteConfigManager; sourceTree = ""; @@ -1639,6 +1645,7 @@ 8957329326DD03A3009507A6 /* QONExperimentGroup.h in Headers */, 895732A126DD03A3009507A6 /* QONMacrosProcess.h in Headers */, 7098564D2A370F270023DFAB /* QONRemoteConfigMapper.h in Headers */, + 6A121DB12BBB10370073B330 /* QONRemoteConfigListRequestData.h in Headers */, 7094501A29CD994200F55E68 /* QONRemoteConfig.h in Headers */, 8957327B26DD03A3009507A6 /* QONUser.h in Headers */, 8957327926DD03A3009507A6 /* QNDevice+Advertising.h in Headers */, @@ -2027,6 +2034,7 @@ 895732BD26DD03A3009507A6 /* QNRequestSerializer.m in Sources */, 895732F526DD03A3009507A6 /* QNAttributionManager.m in Sources */, 895732EF26DD03A3009507A6 /* QNErrorsMapper.m in Sources */, + 6A121DB32BBB10AA0073B330 /* QONRemoteConfigListRequestData.m in Sources */, 895732A426DD03A3009507A6 /* QONUserActionPoint.m in Sources */, 8957330A26DE5532009507A6 /* QNKeyedArchiver.m in Sources */, 895732FC26DD03A3009507A6 /* QNStoreKitService.m in Sources */, diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigListRequestData.h b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigListRequestData.h new file mode 100644 index 00000000..8a802032 --- /dev/null +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigListRequestData.h @@ -0,0 +1,26 @@ +// +// QONRemoteConfigListRequestData.h +// Qonversion +// +// Created by Kamo Spertsyan on 01.04.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import +#import "QONLaunchResult.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface QONRemoteConfigListRequestData : NSObject + +@property (nonatomic, copy, nullable) NSArray *contextKeys; +@property (nonatomic, assign) BOOL includeEmptyContextKey; +@property (nonatomic, copy, nonnull) QONRemoteConfigListCompletionHandler completion; + +- (instancetype)initWithCompletion:(QONRemoteConfigListCompletionHandler)completion; + +- (instancetype)initWithContextKeys:(NSArray *)contextKeys includeEmptyContextKey:(BOOL)includeEmptyContextKey completion:(QONRemoteConfigListCompletionHandler)completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigListRequestData.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigListRequestData.m new file mode 100644 index 00000000..72c2cc0e --- /dev/null +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigListRequestData.m @@ -0,0 +1,31 @@ +// +// QONRemoteConfigListRequestData.m +// Qonversion +// +// Created by Kamo Spertsyan on 01.04.2024. +// Copyright © 2024 Qonversion Inc. All rights reserved. +// + +#import "QONRemoteConfigListRequestData.h" + +@implementation QONRemoteConfigListRequestData + +- (instancetype)initWithCompletion:(QONRemoteConfigListCompletionHandler)completion { + self = [super init]; + if (self) { + _completion = completion; + } + return self; +} + +- (instancetype)initWithContextKeys:(NSArray *)contextKeys includeEmptyContextKey:(BOOL)includeEmptyContextKey completion:(QONRemoteConfigListCompletionHandler)completion { + self = [super init]; + if (self) { + _contextKeys = [contextKeys copy]; + _includeEmptyContextKey = includeEmptyContextKey; + _completion = completion; + } + return self; +} + +@end diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigLoadingState.h b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigLoadingState.h index 812abc8c..9a92747b 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigLoadingState.h +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigLoadingState.h @@ -8,12 +8,11 @@ #import #import "QONLaunchResult.h" -#import "QONExperiment.h" @interface QONRemoteConfigLoadingState : NSObject -@property (nonatomic, strong, nullable) QONRemoteConfig * loadedConfig; -@property (nonatomic, strong, nonnull) NSMutableArray * completions; +@property (nonatomic, strong, nullable) QONRemoteConfig *loadedConfig; +@property (nonatomic, strong, nonnull) NSMutableArray *completions; @property (nonatomic, assign) BOOL isInProgress; @end diff --git a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m index 7d2cb0ef..f8daaba4 100644 --- a/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m +++ b/Sources/Qonversion/Qonversion/Main/QONRemoteConfigManager/QONRemoteConfigManager.m @@ -13,12 +13,14 @@ #import "QONExperiment.h" #import "QNProductCenterManager.h" #import "QONRemoteConfigLoadingState.h" +#import "QONRemoteConfigListRequestData.h" static NSString *const kEmptyContextKey = @""; @interface QONRemoteConfigManager () @property (nonatomic, strong) NSMutableDictionary *loadingStates; +@property (nonatomic, strong) NSMutableArray *listRequests; @end @@ -30,6 +32,7 @@ - (instancetype)init { if (self) { _remoteConfigService = [QONRemoteConfigService new]; _loadingStates = [NSMutableDictionary new]; + _listRequests = [NSMutableArray new]; } return self; @@ -43,6 +46,17 @@ - (void)handlePendingRequests { completion:^(QONRemoteConfig * _Nullable remoteConfig, NSError * _Nullable error) {}]; } } + + NSArray *requestsToSend = [self.listRequests copy]; + [self.listRequests removeAllObjects]; + + for (QONRemoteConfigListRequestData *listRequest in requestsToSend) { + if (listRequest.contextKeys) { + [self obtainRemoteConfigListWithContextKeys:listRequest.contextKeys includeEmptyContextKey:listRequest.includeEmptyContextKey completion:listRequest.completion]; + } else { + [self obtainRemoteConfigList:listRequest.completion]; + } + } } - (void)userChangingRequestFailedWithError:(NSError *)error { @@ -59,13 +73,13 @@ - (void)userHasBeenChanged { } - (void)obtainRemoteConfigWithContextKey:(NSString * _Nullable)contextKey completion:(QONRemoteConfigCompletionHandler)completion { - BOOL isUserStable = [self.productCenterManager isUserStable]; QONRemoteConfigLoadingState *loadingState = [self loadingStateForContextKey:contextKey]; if (loadingState == nil) { loadingState = [QONRemoteConfigLoadingState new]; self.loadingStates[contextKey ?: kEmptyContextKey] = loadingState; } + BOOL isUserStable = [self.productCenterManager isUserStable]; if (!isUserStable || loadingState.isInProgress) { [loadingState.completions addObject:completion]; @@ -112,11 +126,27 @@ - (void)obtainRemoteConfigListWithContextKeys:(NSArray *)contextKeys return completion(remoteConfigList, nil); } + BOOL isUserStable = [self.productCenterManager isUserStable]; + if (!isUserStable) { + QONRemoteConfigListRequestData *requestData = [[QONRemoteConfigListRequestData alloc] initWithContextKeys:contextKeys includeEmptyContextKey:includeEmptyContextKey completion:completion]; + [self.listRequests addObject:requestData]; + + return; + } + QONRemoteConfigListCompletionHandler completionWrapper = [self remoteConfigListCompletionWrapper:completion]; [self.remoteConfigService loadRemoteConfigList:contextKeys includeEmptyContextKey:includeEmptyContextKey completion:completionWrapper]; } - (void)obtainRemoteConfigList:(QONRemoteConfigListCompletionHandler)completion { + BOOL isUserStable = [self.productCenterManager isUserStable]; + if (!isUserStable) { + QONRemoteConfigListRequestData *requestData = [[QONRemoteConfigListRequestData alloc] initWithCompletion:completion]; + [self.listRequests addObject:requestData]; + + return; + } + QONRemoteConfigListCompletionHandler completionWrapper = [self remoteConfigListCompletionWrapper:completion]; [self.remoteConfigService loadRemoteConfigList:completionWrapper]; } From f915d6caaa3ad45111faedca130581e1070451de Mon Sep 17 00:00:00 2001 From: SpertsyanKM Date: Tue, 2 Apr 2024 15:15:06 +0000 Subject: [PATCH 2/2] [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 fe8f3706..6951a462 100644 --- a/Framework/Info.plist +++ b/Framework/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 5.8.2 + 5.8.3 CFBundleSignature ???? CFBundleVersion diff --git a/Qonversion.podspec b/Qonversion.podspec index 877c7b86..af6d8632 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.8.2' + s.version = '5.8.3' 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 0b58aba9..83e1fba4 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.8.2"; +static NSString *const kSDKVersion = @"5.8.3"; @interface QONConfiguration () diff --git a/fastlane/report.xml b/fastlane/report.xml index 241e4cca..489040b0 100644 --- a/fastlane/report.xml +++ b/fastlane/report.xml @@ -5,12 +5,12 @@ - + - +