From ae9bd9e4a6213cfb45ef9b1a21dff2390fd415e8 Mon Sep 17 00:00:00 2001 From: Brandon Sneed Date: Thu, 14 May 2020 10:58:54 -0700 Subject: [PATCH 1/4] Remove IDFA related bits and push to customers. --- .../Classes/Internal/SEGAnalyticsUtils.m | 20 ++++--------------- Analytics/Classes/SEGAnalyticsConfiguration.h | 13 ++++++++++++ AnalyticsTests/AnalyticsTests.swift | 15 ++++++++++++++ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Analytics/Classes/Internal/SEGAnalyticsUtils.m b/Analytics/Classes/Internal/SEGAnalyticsUtils.m index f82cd9ddf..8c1a28b6a 100644 --- a/Analytics/Classes/Internal/SEGAnalyticsUtils.m +++ b/Analytics/Classes/Internal/SEGAnalyticsUtils.m @@ -1,4 +1,5 @@ #import "SEGAnalyticsUtils.h" +#import #import static BOOL kAnalyticsLoggerShowLogs = NO; @@ -217,23 +218,10 @@ static id SEGCoerceJSONObject(id obj) NSString *SEGIDFA() { - NSString *idForAdvertiser = nil; - Class identifierManager = NSClassFromString(@"ASIdentifierManager"); - if (identifierManager) { - SEL sharedManagerSelector = NSSelectorFromString(@"sharedManager"); - id sharedManager = - ((id (*)(id, SEL)) - [identifierManager methodForSelector:sharedManagerSelector])( - identifierManager, sharedManagerSelector); - SEL advertisingIdentifierSelector = - NSSelectorFromString(@"advertisingIdentifier"); - NSUUID *uuid = - ((NSUUID * (*)(id, SEL)) - [sharedManager methodForSelector:advertisingIdentifierSelector])( - sharedManager, advertisingIdentifierSelector); - idForAdvertiser = [uuid UUIDString]; + if ([SEGAnalytics sharedAnalytics].configuration.adSupportBlock != nil) { + return [SEGAnalytics sharedAnalytics].configuration.adSupportBlock(); } - return idForAdvertiser; + return nil; } NSString *SEGEventNameForScreenTitle(NSString *title) diff --git a/Analytics/Classes/SEGAnalyticsConfiguration.h b/Analytics/Classes/SEGAnalyticsConfiguration.h index d878cc18c..b8562877f 100644 --- a/Analytics/Classes/SEGAnalyticsConfiguration.h +++ b/Analytics/Classes/SEGAnalyticsConfiguration.h @@ -20,6 +20,7 @@ @end typedef NSMutableURLRequest *_Nonnull (^SEGRequestFactory)(NSURL *_Nonnull); +typedef NSString *_Nonnull (^SEGAdSupportBlock)(void); @protocol SEGIntegrationFactory; @protocol SEGCrypto; @@ -185,6 +186,18 @@ typedef NSMutableURLRequest *_Nonnull (^SEGRequestFactory)(NSURL *_Nonnull); */ @property (nonatomic, strong, nullable) id httpSessionDelegate; +/** + * Sets a block to be called when IDFA / AdSupport identifier is created. + * This is to allow for apps that do not want ad tracking to pass App Store guidelines in certain categories while + * still allowing apps that do ad tracking to continue to function. + * + * Example: + * configuration.adSupportBlock = ^{ + * return [[ASIdentifierManager sharedManager] advertisingIdentifier]; + * } + */ +@property (nonatomic, strong, nullable) SEGAdSupportBlock adSupportBlock; + /** Enable experimental features within the Segment Analytics-iOS library. */ diff --git a/AnalyticsTests/AnalyticsTests.swift b/AnalyticsTests/AnalyticsTests.swift index b15be213f..28928d92f 100644 --- a/AnalyticsTests/AnalyticsTests.swift +++ b/AnalyticsTests/AnalyticsTests.swift @@ -58,10 +58,25 @@ class AnalyticsTests: QuickSpec { expect(UserDefaults.standard.string(forKey: "SEGQueue")).toEventually(beNil()) } + /* WIP + it("collects IDFA") { + testMiddleware.swallowEvent = true + analytics.configuration.enableAdvertisingTracking = true + analytics.configuration.adSupportBlock = { () -> String in + return "1234AdsNoMore!" + } + + analytics.track("test"); + + let event = testMiddleware.lastContext?.payload as? SEGTrackPayload + expect(event?.properties?["url"] as? String) == "myapp://auth?token=((redacted/my-auth))&other=stuff" + } + it("persists anonymousId") { let analytics2 = SEGAnalytics(configuration: config) expect(analytics.getAnonymousId()) == analytics2.getAnonymousId() } + */ it("persists userId") { analytics.identify("testUserId1") From 91f177722c2a000d345d2d816b0bb18c5be459b8 Mon Sep 17 00:00:00 2001 From: Brandon Sneed Date: Tue, 19 May 2020 13:28:23 -0700 Subject: [PATCH 2/4] Check if ad block is nil before executing --- Analytics/Classes/Internal/SEGSegmentIntegration.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Analytics/Classes/Internal/SEGSegmentIntegration.m b/Analytics/Classes/Internal/SEGSegmentIntegration.m index a74b94487..5ef291ac9 100644 --- a/Analytics/Classes/Internal/SEGSegmentIntegration.m +++ b/Analytics/Classes/Internal/SEGSegmentIntegration.m @@ -174,7 +174,7 @@ - (NSDictionary *)staticContext if (NSClassFromString(SEGAdvertisingClassIdentifier)) { dict[@"adTrackingEnabled"] = @(GetAdTrackingEnabled()); } - if (self.configuration.enableAdvertisingTracking) { + if (self.configuration.enableAdvertisingTracking && self.configuration.adSupportBlock != nil) { NSString *idfa = SEGIDFA(); if (idfa.length) dict[@"advertisingId"] = idfa; } From 27c6f71c74c3b056bc84a38af2d53aae17908361 Mon Sep 17 00:00:00 2001 From: Brandon Sneed Date: Tue, 19 May 2020 13:28:33 -0700 Subject: [PATCH 3/4] Fixed header reference. --- Analytics/Classes/Internal/SEGAnalyticsUtils.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Analytics/Classes/Internal/SEGAnalyticsUtils.m b/Analytics/Classes/Internal/SEGAnalyticsUtils.m index 8c1a28b6a..5aae6c509 100644 --- a/Analytics/Classes/Internal/SEGAnalyticsUtils.m +++ b/Analytics/Classes/Internal/SEGAnalyticsUtils.m @@ -1,6 +1,5 @@ #import "SEGAnalyticsUtils.h" -#import -#import +#import "SEGAnalytics.h" static BOOL kAnalyticsLoggerShowLogs = NO; From d69b5732c2ee39e2da740ed95412aebb7be83825 Mon Sep 17 00:00:00 2001 From: Brandon Sneed Date: Tue, 19 May 2020 13:28:51 -0700 Subject: [PATCH 4/4] Adjusted IDFA test. --- AnalyticsTests/AnalyticsTests.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/AnalyticsTests/AnalyticsTests.swift b/AnalyticsTests/AnalyticsTests.swift index 28928d92f..a9b8b2e6c 100644 --- a/AnalyticsTests/AnalyticsTests.swift +++ b/AnalyticsTests/AnalyticsTests.swift @@ -58,7 +58,7 @@ class AnalyticsTests: QuickSpec { expect(UserDefaults.standard.string(forKey: "SEGQueue")).toEventually(beNil()) } - /* WIP + /* TODO: Fix me when the Context object isn't so wild. it("collects IDFA") { testMiddleware.swallowEvent = true analytics.configuration.enableAdvertisingTracking = true @@ -70,13 +70,12 @@ class AnalyticsTests: QuickSpec { let event = testMiddleware.lastContext?.payload as? SEGTrackPayload expect(event?.properties?["url"] as? String) == "myapp://auth?token=((redacted/my-auth))&other=stuff" - } + }*/ it("persists anonymousId") { let analytics2 = SEGAnalytics(configuration: config) expect(analytics.getAnonymousId()) == analytics2.getAnonymousId() } - */ it("persists userId") { analytics.identify("testUserId1")