From 2518804dde8fb34ae9d1a6fa256b80fc6a9b093c Mon Sep 17 00:00:00 2001 From: YoloMao Date: Thu, 13 Feb 2025 14:19:56 +0800 Subject: [PATCH] feat(ABTesting): ANLSPI-23827 new device (#340) * fix(autotrack): growingNodeChilds of collectionView not contain header as expected * fix: add double-checked lock to deviceId getter * feat: new device tag * feat: first session tag * feat(ABTesting): add newDevice to request parameters * style: code format * ci: update ci * ci: update ci * ci: update ci --------- Co-authored-by: GIOSDK --- .github/workflows/spm.yml | 27 ++-- Example/Podfile.lock | 120 +++++++++--------- .../Category/UICollectionView+GrowingNode.m | 17 ++- GrowingTrackerCore/Manager/GrowingSession.h | 1 + GrowingTrackerCore/Manager/GrowingSession.m | 2 + GrowingTrackerCore/Utils/GrowingDeviceInfo.h | 1 + GrowingTrackerCore/Utils/GrowingDeviceInfo.m | 8 +- Modules/ABTesting/Request/GrowingABTRequest.m | 14 +- 8 files changed, 102 insertions(+), 88 deletions(-) diff --git a/.github/workflows/spm.yml b/.github/workflows/spm.yml index 416cc1f87..3a91b6755 100644 --- a/.github/workflows/spm.yml +++ b/.github/workflows/spm.yml @@ -19,16 +19,16 @@ jobs: macOS, macCatalyst, tvOS, - watchOS + watchOS, ] - os: [macos-13, macos-14] + os: [macos-14, macos-15] include: - - os: macos-13 - xcode: Xcode_15.2 - os: macos-14 - xcode: Xcode_15.4 + xcode: Xcode_16.0 + - os: macos-15 + xcode: Xcode_16.2 - target: iOS - platform: iOS Simulator,name=iPhone 14 Pro Max + platform: iOS Simulator,name=iPhone 16 Pro Max - target: macOS platform: macOS - target: macCatalyst @@ -36,7 +36,7 @@ jobs: - target: tvOS platform: tvOS Simulator,name=Apple TV - target: watchOS - platform: watchOS Simulator,name=Apple Watch Ultra (49mm) + platform: watchOS Simulator,name=Apple Watch Ultra 2 (49mm) - scheme: GrowingAnalytics-Package target: iOS - scheme: GrowingAutotracker @@ -48,21 +48,12 @@ jobs: - scheme: GrowingTracker target: watchOS - target: visionOS - os: macos-14 - xcode: Xcode_15.4 + os: macos-15 + xcode: Xcode_16.2 platform: visionOS Simulator,name=Apple Vision Pro scheme: GrowingTracker runs-on: ${{ matrix.os }} steps: - # https://github.com/actions/runner-images/issues/10559 - - name: Download visionOS SDK - if: ${{ matrix.target == 'visionOS' }} - run: | - sudo xcodebuild -runFirstLaunch - sudo xcrun simctl list - sudo xcodebuild -downloadPlatform visionOS - sudo xcodebuild -runFirstLaunch - - name: Checkout Repo uses: actions/checkout@v4 - name: Xcode diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 7e8a6270c..f37e40785 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,66 +1,66 @@ PODS: - - GrowingAnalytics/ABTesting (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/Ads (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/APM (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) + - GrowingAnalytics/ABTesting (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/Ads (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/APM (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) - GrowingAPM/Core (~> 1.0.1) - - GrowingAnalytics/Autotracker (4.4.0): - - GrowingAnalytics/AutotrackerCore (= 4.4.0) - - GrowingAnalytics/DefaultServices (= 4.4.0) - - GrowingAnalytics/Hybrid (= 4.4.0) - - GrowingAnalytics/MobileDebugger (= 4.4.0) - - GrowingAnalytics/WebCircle (= 4.4.0) - - GrowingAnalytics/AutotrackerCore (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) + - GrowingAnalytics/Autotracker (4.5.0): + - GrowingAnalytics/AutotrackerCore (= 4.5.0) + - GrowingAnalytics/DefaultServices (= 4.5.0) + - GrowingAnalytics/Hybrid (= 4.5.0) + - GrowingAnalytics/MobileDebugger (= 4.5.0) + - GrowingAnalytics/WebCircle (= 4.5.0) + - GrowingAnalytics/AutotrackerCore (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) - GrowingUtils/AutotrackerCore (~> 1.2.3) - - GrowingAnalytics/Compression (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/Database (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/DefaultServices (4.4.0): - - GrowingAnalytics/Compression (= 4.4.0) - - GrowingAnalytics/Encryption (= 4.4.0) - - GrowingAnalytics/JSON (= 4.4.0) - - GrowingAnalytics/Network (= 4.4.0) - - GrowingAnalytics/Protobuf (= 4.4.0) - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/Encryption (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/Hybrid (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/ImpressionTrack (4.4.0): - - GrowingAnalytics/AutotrackerCore (= 4.4.0) - - GrowingAnalytics/JSON (4.4.0): - - GrowingAnalytics/Database (= 4.4.0) - - GrowingAnalytics/MobileDebugger (4.4.0): - - GrowingAnalytics/Screenshot (= 4.4.0) - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/WebSocket (= 4.4.0) - - GrowingAnalytics/Network (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/Protobuf (4.4.0): - - GrowingAnalytics/Database (= 4.4.0) - - GrowingAnalytics/Protobuf/Proto (= 4.4.0) - - GrowingAnalytics/Protobuf/Proto (4.4.0): - - GrowingAnalytics/Database (= 4.4.0) + - GrowingAnalytics/Compression (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/Database (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/DefaultServices (4.5.0): + - GrowingAnalytics/Compression (= 4.5.0) + - GrowingAnalytics/Encryption (= 4.5.0) + - GrowingAnalytics/JSON (= 4.5.0) + - GrowingAnalytics/Network (= 4.5.0) + - GrowingAnalytics/Protobuf (= 4.5.0) + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/Encryption (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/Hybrid (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/ImpressionTrack (4.5.0): + - GrowingAnalytics/AutotrackerCore (= 4.5.0) + - GrowingAnalytics/JSON (4.5.0): + - GrowingAnalytics/Database (= 4.5.0) + - GrowingAnalytics/MobileDebugger (4.5.0): + - GrowingAnalytics/Screenshot (= 4.5.0) + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/WebSocket (= 4.5.0) + - GrowingAnalytics/Network (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/Protobuf (4.5.0): + - GrowingAnalytics/Database (= 4.5.0) + - GrowingAnalytics/Protobuf/Proto (= 4.5.0) + - GrowingAnalytics/Protobuf/Proto (4.5.0): + - GrowingAnalytics/Database (= 4.5.0) - Protobuf (~> 3.27) - - GrowingAnalytics/Screenshot (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/Tracker (4.4.0): - - GrowingAnalytics/DefaultServices (= 4.4.0) - - GrowingAnalytics/MobileDebugger (= 4.4.0) - - GrowingAnalytics/TrackerCore (= 4.4.0) - - GrowingAnalytics/TrackerCore (4.4.0): + - GrowingAnalytics/Screenshot (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/Tracker (4.5.0): + - GrowingAnalytics/DefaultServices (= 4.5.0) + - GrowingAnalytics/MobileDebugger (= 4.5.0) + - GrowingAnalytics/TrackerCore (= 4.5.0) + - GrowingAnalytics/TrackerCore (4.5.0): - GrowingUtils/TrackerCore (~> 1.2.3) - - GrowingAnalytics/WebCircle (4.4.0): - - GrowingAnalytics/AutotrackerCore (= 4.4.0) - - GrowingAnalytics/Hybrid (= 4.4.0) - - GrowingAnalytics/Screenshot (= 4.4.0) - - GrowingAnalytics/WebSocket (= 4.4.0) - - GrowingAnalytics/WebSocket (4.4.0): - - GrowingAnalytics/TrackerCore (= 4.4.0) + - GrowingAnalytics/WebCircle (4.5.0): + - GrowingAnalytics/AutotrackerCore (= 4.5.0) + - GrowingAnalytics/Hybrid (= 4.5.0) + - GrowingAnalytics/Screenshot (= 4.5.0) + - GrowingAnalytics/WebSocket (= 4.5.0) + - GrowingAnalytics/WebSocket (4.5.0): + - GrowingAnalytics/TrackerCore (= 4.5.0) - GrowingAPM (1.0.1): - GrowingAPM/Core (= 1.0.1) - GrowingAPM/CrashMonitor (= 1.0.1) @@ -160,7 +160,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - GrowingAnalytics: d50200337f7dbad6d087705119c6f0605cdc91a2 + GrowingAnalytics: dd1b26e83f30a322f5c5c2dd7a4b8da65c0c0b3e GrowingAPM: 3c4de0384935b654e6798b95606f47883a99418b GrowingToolsKit: 53160d19690da0b78e04a9242abde7af86442922 GrowingUtils: 68aee2c96849bf9b674740503da30c2da468e79d @@ -172,4 +172,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 8ef4d85701caba0f5df403432dc182d34412ab4a -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.1 diff --git a/GrowingAutotrackerCore/GrowingNode/Category/UICollectionView+GrowingNode.m b/GrowingAutotrackerCore/GrowingNode/Category/UICollectionView+GrowingNode.m index 12d0b0581..c7cb7d365 100644 --- a/GrowingAutotrackerCore/GrowingNode/Category/UICollectionView+GrowingNode.m +++ b/GrowingAutotrackerCore/GrowingNode/Category/UICollectionView+GrowingNode.m @@ -25,15 +25,18 @@ @implementation UICollectionView (GrowingNode) - (NSArray> *)growingNodeChilds { - // 对于collectionView我们仅需要返回可见cell + // 对于CollectionViewCell仅需要返回可见的cell NSMutableArray *children = [NSMutableArray array]; - if (@available(iOS 9.0, *)) { - NSArray *headers = [self visibleSupplementaryViewsOfKind:UICollectionElementKindSectionHeader]; - NSArray *footers = [self visibleSupplementaryViewsOfKind:UICollectionElementKindSectionFooter]; - [children addObjectsFromArray:headers]; - [children addObjectsFromArray:footers]; - } [children addObjectsFromArray:self.visibleCells]; + + // header/footer使用subviews获取 + NSArray *subviews = self.subviews; + for (UIView *view in subviews) { + if (![view isKindOfClass:UICollectionViewCell.class]) { + [children addObject:view]; + } + } + return children; } diff --git a/GrowingTrackerCore/Manager/GrowingSession.h b/GrowingTrackerCore/Manager/GrowingSession.h index 4bed6b298..6edfb97dc 100644 --- a/GrowingTrackerCore/Manager/GrowingSession.h +++ b/GrowingTrackerCore/Manager/GrowingSession.h @@ -42,6 +42,7 @@ typedef NS_ENUM(NSInteger, GrowingSessionState) { @property (nonatomic, assign, readonly) double latitude; @property (nonatomic, assign, readonly) double longitude; @property (nonatomic, assign, readonly) GrowingSessionState state; +@property (nonatomic, assign, readonly) BOOL firstSession; + (void)startSession; diff --git a/GrowingTrackerCore/Manager/GrowingSession.m b/GrowingTrackerCore/Manager/GrowingSession.m index a86f361a5..9b5ad9597 100644 --- a/GrowingTrackerCore/Manager/GrowingSession.m +++ b/GrowingTrackerCore/Manager/GrowingSession.m @@ -42,6 +42,7 @@ @interface GrowingSession () @property (nonatomic, assign) long long latestDidEnterBackgroundTime; @property (nonatomic, strong, readonly) NSHashTable *userIdChangedDelegates; @property (nonatomic, assign, readwrite) GrowingSessionState state; +@property (nonatomic, assign, readwrite) BOOL firstSession; @end @@ -93,6 +94,7 @@ - (void)generateVisit { } - (void)refreshSessionId { + _firstSession = !(_sessionId && _sessionId.length > 0); _sessionId = NSUUID.UUID.UUIDString; _sentVisitAfterRefreshSessionId = NO; } diff --git a/GrowingTrackerCore/Utils/GrowingDeviceInfo.h b/GrowingTrackerCore/Utils/GrowingDeviceInfo.h index 32164c292..7247ce20e 100644 --- a/GrowingTrackerCore/Utils/GrowingDeviceInfo.h +++ b/GrowingTrackerCore/Utils/GrowingDeviceInfo.h @@ -40,6 +40,7 @@ @property (nonatomic, readonly, assign) CGFloat screenWidth; @property (nonatomic, readonly, assign) CGFloat screenHeight; @property (nonatomic, readonly, assign) NSInteger timezoneOffset; +@property (nonatomic, readonly, assign) BOOL isNewDevice; + (instancetype)currentDeviceInfo; + (void)setup; diff --git a/GrowingTrackerCore/Utils/GrowingDeviceInfo.m b/GrowingTrackerCore/Utils/GrowingDeviceInfo.m index c0383138c..e2423d9ae 100644 --- a/GrowingTrackerCore/Utils/GrowingDeviceInfo.m +++ b/GrowingTrackerCore/Utils/GrowingDeviceInfo.m @@ -58,6 +58,7 @@ @interface GrowingDeviceInfo () @property (nonatomic, readwrite, assign) CGFloat screenWidth; @property (nonatomic, readwrite, assign) CGFloat screenHeight; @property (nonatomic, readwrite, assign) NSInteger timezoneOffset; +@property (nonatomic, readwrite, assign) BOOL isNewDevice; @end @@ -74,6 +75,7 @@ - (instancetype)init { _deviceBrand = @"Apple"; _appState = 0; _timezoneOffset = -([[NSTimeZone defaultTimeZone] secondsFromGMT] / 60); + _isNewDevice = NO; #if Growing_USE_APPKIT _screenWidth = NSScreen.mainScreen.frame.size.width; @@ -155,6 +157,7 @@ - (NSString *)getDeviceIdString { #if Growing_OS_PURE_IOS || Growing_OS_WATCH || Growing_OS_VISION || Growing_OS_TV [GrowingKeyChainWrapper setKeychainObject:uuid forKey:kGrowingKeychainUserIdKey]; #endif + _isNewDevice = YES; return uuid; } @@ -229,7 +232,10 @@ - (void)applicationWillResignActive { - (NSString *)deviceIDString { if (!_deviceIDString) { GROWING_LOCK(lock); - _deviceIDString = [self getDeviceIdString]; + // double checked locking + if (!_deviceIDString) { + _deviceIDString = [self getDeviceIdString]; + } GROWING_UNLOCK(lock); } return _deviceIDString; diff --git a/Modules/ABTesting/Request/GrowingABTRequest.m b/Modules/ABTesting/Request/GrowingABTRequest.m index 04ebdcd3a..e73e63651 100644 --- a/Modules/ABTesting/Request/GrowingABTRequest.m +++ b/Modules/ABTesting/Request/GrowingABTRequest.m @@ -22,6 +22,7 @@ #import "Modules/ABTesting/Request/GrowingABTRequestAdapter.h" #import "GrowingTrackerCore/Manager/GrowingConfigurationManager.h" +#import "GrowingTrackerCore/Manager/GrowingSession.h" #import "GrowingTrackerCore/Network/Request/Adapter/GrowingRequestAdapter.h" #import "GrowingTrackerCore/Utils/GrowingDeviceInfo.h" @@ -47,13 +48,22 @@ - (NSString *)path { NSString *accountId = config.accountId; NSString *datasourceId = config.dataSourceId; NSString *distinctId = [GrowingDeviceInfo currentDeviceInfo].deviceIDString; - bodyAdapter.parameters = @{ + + NSMutableDictionary *parameters = @{ @"accountId": accountId, @"datasourceId": datasourceId, @"distinctId": distinctId, @"layerId": self.layerId.copy - }; + } + .mutableCopy; + + BOOL newDevice = + [GrowingDeviceInfo currentDeviceInfo].isNewDevice && [[GrowingSession currentSession] firstSession]; + if (newDevice) { + parameters[@"newDevice"] = @(newDevice); + } + bodyAdapter.parameters = parameters.copy; GrowingRequestMethodAdapter *methodAdapter = [GrowingRequestMethodAdapter adapterWithRequest:self]; NSMutableArray *adapters = [NSMutableArray arrayWithObjects:bodyAdapter, methodAdapter, nil]; return adapters;