Skip to content

Commit 8313273

Browse files
feat: iOS 25.4.0
1 parent fe8741d commit 8313273

13 files changed

+326
-216
lines changed

ios/Classes/CountlyiOS/CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
## XX.XX.XX
2-
* Deprecated the experimental configuration function enableServerConfiguration and it will do nothing. It is now enabled by default and can be controlled directly from the server.
1+
## 25.4.0
2+
* ! Minor breaking change ! Removed UIDevice.currentDevice.identifierForVendor usage in device id generation. The SDK now exclusively uses random UUIDs for device id generation.
33

4+
* Added a Content feature method "refreshContentZone" that does a manual refresh.
45
* Extended server configuration capabilities of the SDK.
6+
* Added a config parameter to provide server config in the initialization "sdkBehaviorSettings: NSString".
7+
8+
* Deprecated the experimental configuration function enableServerConfiguration and it will do nothing. It is now enabled by default and can be controlled directly from the server.
59

610
## 25.1.2
711
* Mitigated an issue where the safe area resolution was not correctly calculated for the content zone on certain iOS devices.

ios/Classes/CountlyiOS/Countly.m

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ - (void)startWithConfig:(CountlyConfig *)config
9292

9393
config = [self checkAndFixInternalLimitsConfig:config];
9494

95-
[CountlyServerConfig.sharedInstance retrieveServerConfigFromStorage: config.serverConfiguration];
96-
95+
[CountlyServerConfig.sharedInstance retrieveServerConfigFromStorage:config.sdkBehaviorSettings];
96+
9797
CountlyCommon.sharedInstance.maxKeyLength = config.sdkInternalLimits.getMaxKeyLength;
9898
CountlyCommon.sharedInstance.maxValueLength = config.sdkInternalLimits.getMaxValueSize;
9999
CountlyCommon.sharedInstance.maxSegmentationValues = config.sdkInternalLimits.getMaxSegmentationValues;
@@ -167,8 +167,8 @@ - (void)startWithConfig:(CountlyConfig *)config
167167
CountlyDeviceInfo.sharedInstance.customMetrics = [customMetricsTruncated cly_limited:@"Custom metric"];
168168

169169
[Countly.user save];
170-
// If something added related to server config, make sure to check CountlyServerConfig.notifySdkConfigChange
171-
[CountlyServerConfig.sharedInstance fetchServerConfig: config];
170+
// If something added related to server config, make sure to check CountlyServerConfig.notifySdkConfigChange
171+
[CountlyServerConfig.sharedInstance fetchServerConfig:config];
172172

173173
#if (TARGET_OS_IOS)
174174
CountlyFeedbacksInternal.sharedInstance.message = config.starRatingMessage;
@@ -227,9 +227,9 @@ - (void)startWithConfig:(CountlyConfig *)config
227227
if ([config.features containsObject:CLYCrashReporting])
228228
{
229229
CountlyCrashReporter.sharedInstance.isEnabledOnInitialConfig = YES;
230-
231-
if (CountlyServerConfig.sharedInstance.crashReportingEnabled) {
232-
[CountlyCrashReporter.sharedInstance startCrashReporting];
230+
if (CountlyServerConfig.sharedInstance.crashReportingEnabled)
231+
{
232+
[CountlyCrashReporter.sharedInstance startCrashReporting];
233233
}
234234
}
235235

@@ -238,10 +238,10 @@ - (void)startWithConfig:(CountlyConfig *)config
238238
{
239239
// Print deprecation flag for feature
240240
CountlyViewTrackingInternal.sharedInstance.isEnabledOnInitialConfig = YES;
241-
if (CountlyServerConfig.sharedInstance.viewTrackingEnabled) {
241+
if (CountlyServerConfig.sharedInstance.viewTrackingEnabled)
242+
{
242243
[CountlyViewTrackingInternal.sharedInstance startAutoViewTracking];
243244
}
244-
[CountlyViewTrackingInternal.sharedInstance startAutoViewTracking];
245245
}
246246
if (config.automaticViewTrackingExclusionList) {
247247
[CountlyViewTrackingInternal.sharedInstance addAutoViewTrackingExclutionList:config.automaticViewTrackingExclusionList];
@@ -257,7 +257,6 @@ - (void)startWithConfig:(CountlyConfig *)config
257257
if (config.globalViewSegmentation) {
258258
[CountlyViewTrackingInternal.sharedInstance setGlobalViewSegmentation:config.globalViewSegmentation];
259259
}
260-
261260
timer = [NSTimer timerWithTimeInterval:config.updateSessionPeriod target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
262261
[NSRunLoop.mainRunLoop addTimer:timer forMode:NSRunLoopCommonModes];
263262

@@ -447,7 +446,7 @@ - (void)resume
447446
- (void)applicationDidBecomeActive:(NSNotification *)notification
448447
{
449448
CLY_LOG_D(@"App enters foreground");
450-
[CountlyServerConfig.sharedInstance fetchServerConfigIfTimeIsUp];
449+
[CountlyServerConfig.sharedInstance fetchServerConfigIfTimeIsUp];
451450
[self resume];
452451
}
453452

@@ -861,13 +860,12 @@ - (void)recordEvent:(NSString *)key segmentation:(NSDictionary *)segmentation co
861860
CLY_LOG_W(@"A reserved event detected for key: '%@', event will not be recorded.", key);
862861
return;
863862
}
864-
865863
if (!CountlyServerConfig.sharedInstance.customEventTrackingEnabled)
866864
{
867865
CLY_LOG_D(@"'recordEvent' is aborted: Custom Event Tracking is disabled from server config!");
868866
return;
869867
}
870-
868+
871869
NSDictionary* truncated = [segmentation cly_truncated:@"Event segmentation"];
872870
segmentation = [truncated cly_limited:@"Event segmentation"];
873871

ios/Classes/CountlyiOS/CountlyCommon.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ @interface CountlyCommon ()
2929
#endif
3030
@end
3131

32-
NSString* const kCountlySDKVersion = @"25.1.1";
32+
NSString* const kCountlySDKVersion = @"25.4.0";
3333
NSString* const kCountlySDKName = @"objc-native-ios";
3434

3535
NSString* const kCountlyErrorDomain = @"ly.count.ErrorDomain";

ios/Classes/CountlyiOS/CountlyConfig.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -662,20 +662,18 @@ typedef enum : NSUInteger
662662
*/
663663
@property (nonatomic) BOOL enableOrientationTracking;
664664

665-
#pragma mark -
666-
667665
/**
668666
* This is an experimental feature and it can have breaking changes
669667
* For enabling fetching and application of server config values.
670668
* @discussion If set, Server Config values from Countly Server will be fetched at the beginning of a session.
671-
* @deprecated and will do nothing
672669
*/
673-
@property (nonatomic) BOOL enableServerConfiguration;
670+
@property(nonatomic) BOOL enableServerConfiguration DEPRECATED_MSG_ATTRIBUTE("Will do nothing");
671+
;
674672

675673
/**
676674
* Set the server configuration to be set while initializing the SDK
677675
*/
678-
@property (nonatomic, copy) NSString* serverConfiguration;
676+
@property(nonatomic, copy) NSString *sdkBehaviorSettings;
679677

680678
#if (TARGET_OS_IOS)
681679
/**

ios/Classes/CountlyiOS/CountlyContentBuilder.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,26 @@ NS_ASSUME_NONNULL_BEGIN
1515
+ (instancetype)sharedInstance;
1616

1717
/**
18-
* This is an experimental feature and it can have breaking changes
19-
* Opt in user for the content fetching and updates
18+
* Enables content fetching and updates for the user.
19+
* This method opts the user into receiving content updates
20+
* and ensures that relevant data is fetched accordingly.
2021
*/
2122
- (void)enterContentZone;
2223

2324
/**
24-
* This is an experimental feature and it can have breaking changes
25-
* Opt out user for the content fetching and updates
25+
* Disables content fetching and updates for the user.
26+
* This method opts the user out of receiving content updates
27+
* and stops any ongoing content retrieval processes.
2628
*/
2729
- (void)exitContentZone;
2830

31+
/**
32+
* Triggers a manual refresh of the content zone.
33+
* This method forces an update by fetching the latest content,
34+
* ensuring the user receives the most up-to-date information.
35+
*/
36+
- (void)refreshContentZone;
37+
2938
#endif
3039
NS_ASSUME_NONNULL_END
3140
@end

ios/Classes/CountlyiOS/CountlyContentBuilder.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ - (void)exitContentZone
4141
{
4242
[CountlyContentBuilderInternal.sharedInstance exitContentZone];
4343
}
44+
- (void)refreshContentZone
45+
{
46+
[CountlyContentBuilderInternal.sharedInstance refreshContentZone];
47+
48+
}
4449
- (void)changeContent:(NSArray<NSString *> *)tags
4550
{
4651
[CountlyContentBuilder.sharedInstance changeContent:tags];

ios/Classes/CountlyiOS/CountlyContentBuilderInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
2121
- (void)enterContentZone:(NSArray<NSString *> *)tags;
2222
- (void)exitContentZone;
2323
- (void)changeContent:(NSArray<NSString *> *)tags;
24+
- (void)refreshContentZone;
2425

2526
#endif
2627
NS_ASSUME_NONNULL_END

ios/Classes/CountlyiOS/CountlyContentBuilderInternal.m

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@
1212

1313
@implementation CountlyContentBuilderInternal {
1414
BOOL _isRequestQueueLocked;
15+
BOOL _isCurrentlyContentShown;
1516
NSTimer *_requestTimer;
1617
NSTimer *_minuteTimer;
1718
}
19+
20+
NSInteger const contentInitialDelay = 4;
21+
1822
#if (TARGET_OS_IOS)
1923
+ (instancetype)sharedInstance {
2024
static CountlyContentBuilderInternal *instance = nil;
@@ -31,12 +35,18 @@ - (instancetype)init
3135
{
3236
self.zoneTimerInterval = 30.0;
3337
_requestTimer = nil;
38+
_isCurrentlyContentShown = NO;
3439
}
3540

3641
return self;
3742
}
3843

3944
- (void)enterContentZone {
45+
46+
if(_isCurrentlyContentShown){
47+
CLY_LOG_I(@"%s, a content is already shown, skipping" ,__FUNCTION__);
48+
}
49+
4050
[self enterContentZone:@[]];
4151
}
4252

@@ -53,13 +63,21 @@ - (void)enterContentZone:(NSArray<NSString *> *)tags {
5363
}
5464

5565
self.currentTags = tags;
66+
int contentDelay = 0;
5667

57-
[self fetchContents];;
58-
_requestTimer = [NSTimer scheduledTimerWithTimeInterval:self.zoneTimerInterval
59-
target:self
60-
selector:@selector(fetchContents)
61-
userInfo:nil
62-
repeats:YES];
68+
if (CountlyCommon.sharedInstance.timeSinceLaunch < contentInitialDelay) {
69+
contentDelay = contentInitialDelay;
70+
}
71+
72+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(contentDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
73+
{
74+
[self fetchContents];;
75+
self->_requestTimer = [NSTimer scheduledTimerWithTimeInterval:self->_zoneTimerInterval
76+
target:self
77+
selector:@selector(fetchContents)
78+
userInfo:nil
79+
repeats:YES];
80+
});
6381
}
6482

6583
- (void)exitContentZone {
@@ -73,6 +91,25 @@ - (void)changeContent:(NSArray<NSString *> *)tags {
7391
}
7492
}
7593

94+
- (void)refreshContentZone {
95+
if (![CountlyServerConfig.sharedInstance refreshContentZoneEnabled])
96+
{
97+
return;
98+
}
99+
if(_isCurrentlyContentShown){
100+
CLY_LOG_I(@"%s, a content is already shown, skipping" ,__FUNCTION__);
101+
}
102+
103+
[self exitContentZone];
104+
[CountlyConnectionManager.sharedInstance attemptToSendStoredRequests];
105+
106+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
107+
{
108+
[self enterContentZone];
109+
});
110+
111+
}
112+
76113
#pragma mark - Private Methods
77114

78115
- (void)clearContentState {
@@ -88,7 +125,9 @@ - (void)clearContentState {
88125
- (void)fetchContents {
89126
if (!CountlyConsentManager.sharedInstance.consentForContent)
90127
return;
91-
128+
129+
if (!CountlyServerConfig.sharedInstance.networkingEnabled)
130+
return;
92131
if (_isRequestQueueLocked) {
93132
return;
94133
}
@@ -130,24 +169,25 @@ - (void)fetchContents {
130169

131170
- (NSURLRequest *)fetchContentsRequest
132171
{
133-
NSString* queryString = [CountlyConnectionManager.sharedInstance queryEssentials];
172+
NSString *queryString = [CountlyConnectionManager.sharedInstance queryEssentials];
134173
NSString *resolutionJson = [self resolutionJson];
135-
queryString = [queryString stringByAppendingFormat:@"&%@=%@",
136-
@"resolution", resolutionJson.cly_URLEscaped];
137-
138-
queryString = [CountlyConnectionManager.sharedInstance appendChecksum:queryString];
139-
174+
queryString = [queryString stringByAppendingFormat:@"&%@=%@", @"method", kCountlyCBFetchContent];
175+
queryString = [queryString stringByAppendingFormat:@"&%@=%@", @"resolution", resolutionJson.cly_URLEscaped];
176+
140177
NSArray *components = [CountlyDeviceInfo.locale componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"_-"]];
178+
queryString = [queryString stringByAppendingFormat:@"&%@=%@", @"la", components.firstObject];
141179

142-
queryString = [queryString stringByAppendingFormat:@"&%@=%@",
143-
@"la", components.firstObject];
144-
145-
NSString* URLString = [NSString stringWithFormat:@"%@%@?%@",
146-
CountlyConnectionManager.sharedInstance.host,
147-
kCountlyEndpointContent,
148-
queryString];
149-
150-
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString]];
180+
NSString *deviceType = CountlyDeviceInfo.deviceType;
181+
if (deviceType)
182+
{
183+
queryString = [queryString stringByAppendingFormat:@"&%@=%@", @"dt", deviceType];
184+
}
185+
186+
queryString = [CountlyConnectionManager.sharedInstance appendChecksum:queryString];
187+
188+
NSString *URLString = [NSString stringWithFormat:@"%@%@?%@", CountlyConnectionManager.sharedInstance.host, kCountlyEndpointContent, queryString];
189+
190+
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString]];
151191
return request;
152192
}
153193

@@ -244,11 +284,13 @@ - (void)showContentWithHtmlPath:(NSString *)urlString placementCoordinates:(NSDi
244284
[webViewManager createWebViewWithURL:url frame:frame appearBlock:^
245285
{
246286
CLY_LOG_I(@"%s, Webview appeared", __FUNCTION__);
287+
self->_isCurrentlyContentShown = YES;
247288
[self clearContentState];
248289
} dismissBlock:^
249290
{
250291
CLY_LOG_I(@"%s, Webview dismissed", __FUNCTION__);
251-
self->_minuteTimer = [NSTimer scheduledTimerWithTimeInterval:60.0
292+
self->_isCurrentlyContentShown = NO;
293+
self->_minuteTimer = [NSTimer scheduledTimerWithTimeInterval:self->_zoneTimerInterval
252294
target:self
253295
selector:@selector(enterContentZone)
254296
userInfo:nil
@@ -260,4 +302,4 @@ - (void)showContentWithHtmlPath:(NSString *)urlString placementCoordinates:(NSDi
260302
});
261303
}
262304
#endif
263-
@end
305+
@end

ios/Classes/CountlyiOS/CountlyDeviceInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ typedef enum : NSUInteger
2727
- (CLYDeviceIDTypeValue)deviceIDTypeValue;
2828

2929
+ (NSString *)device;
30+
+ (NSString *)deviceType;
3031
+ (NSString *)architecture;
3132
+ (NSString *)osName;
3233
+ (NSString *)osVersion;

ios/Classes/CountlyiOS/CountlyDeviceInfo.m

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,6 @@ - (NSString *)ensafeDeviceID:(NSString *)deviceID
107107
if (deviceID.length)
108108
return deviceID;
109109

110-
#if (TARGET_OS_IOS || TARGET_OS_VISION || TARGET_OS_TV)
111-
return UIDevice.currentDevice.identifierForVendor.UUIDString;
112-
#else
113110
NSString* UUID = [CountlyPersistency.sharedInstance retrieveNSUUID];
114111
if (!UUID)
115112
{
@@ -118,7 +115,6 @@ - (NSString *)ensafeDeviceID:(NSString *)deviceID
118115
}
119116

120117
return UUID;
121-
#endif
122118
}
123119

124120
- (BOOL)isDeviceIDTemporary

0 commit comments

Comments
 (0)