segmentio / analytics-ios

The hassle-free way to integrate analytics into any iOS application.
https://segment.com/libraries/ios
MIT License
399 stars 334 forks source link

How to set advertisingId after User set promission #971

Closed sanhue0302 closed 3 years ago

sanhue0302 commented 3 years ago

In iOS 14, We need permission to use adTracking. As document said, I setup SEGAnalytics in delegate application:didFinishLaunchingWithOptions as below

    SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:{SEGMENT_KEY}];

    configuration.enableAdvertisingTracking = YES;

    configuration.adSupportBlock = ^NSString * _Nonnull{

        NSString *uuidString = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
        return uuidString;
    };
    [SEGAnalytics setupWithConfiguration:configuration];

however, when we got user's permission using requestTrackingAuthorizationWithCompletionHandler: we can't do the configuration again. The only way to apply the configuration is removing the app from background, and launch again

Is there another way to set advertisingId after "[SEGAnalytics setupWithConfiguration:configuration];"?

migs647 commented 3 years ago

Hello @sanhue0302... thanks for reaching out

We suggest expanding your adSupportBlock to contain the ATTrackingManager logic. Please let us know if this does not work for you and re-open the issue.

if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusNotDetermined) {

    [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {

        NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
        NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
        if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
            [SEGAnalytics.sharedAnalytics track:@"iOS14 Tracking enabled" properties:@{@"IDFA": idfa, @"IDFV": idfv}];
        } else {
            [SEGAnalytics.sharedAnalytics track:@"iOS14 Tracking disabled" properties:@{@"IDFA": idfa, @"IDFV": idfv}];
        }
    }];
} else {
    NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; // Will be 0000-0000-0000-0000 if denied
    NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    [SEGAnalytics.sharedAnalytics track:@"iOS14 Tracking after being asked" properties:@{@"IDFA": idfa, @"IDFV": idfv}];
}
bsneed commented 3 years ago

One other alternative is to capture it and store it somewhere. And your adSupportBlock just returns whatever the value that's stored (initially nil I suppose).

sanhue0302 commented 3 years ago

One other alternative is to capture it and store it somewhere. And your adSupportBlock just returns whatever the value that's stored (initially nil I suppose).

Since I Setup SEGAnalytics when didFinishLaunchingWithOptions, the adSupportBlock will only run one time So, if I store it after user confirm it, We still need to restart app to let didFinishLaunchingWithOptions run again to setup SEGAnalytics

sanhue0302 commented 3 years ago

Hello @sanhue0302... thanks for reaching out

We suggest expanding your adSupportBlock to contain the ATTrackingManager logic. Please let us know if this does not work for you and re-open the issue.

if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusNotDetermined) {

    [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {

        NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
        NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
        if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
            [SEGAnalytics.sharedAnalytics track:@"iOS14 Tracking enabled" properties:@{@"IDFA": idfa, @"IDFV": idfv}];
        } else {
            [SEGAnalytics.sharedAnalytics track:@"iOS14 Tracking disabled" properties:@{@"IDFA": idfa, @"IDFV": idfv}];
        }
    }];
} else {
    NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; // Will be 0000-0000-0000-0000 if denied
    NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    [SEGAnalytics.sharedAnalytics track:@"iOS14 Tracking after being asked" properties:@{@"IDFA": idfa, @"IDFV": idfv}];
}

Yes, I am using code like you said. and it work. But I am thinking that is there a way to set the IDFA after SEGAnalytics setup.

bsneed commented 3 years ago

One other alternative is to capture it and store it somewhere. And your adSupportBlock just returns whatever the value that's stored (initially nil I suppose).

Since I Setup SEGAnalytics when didFinishLaunchingWithOptions, the adSupportBlock will only run one time So, if I store it after user confirm it, We still need to restart app to let didFinishLaunchingWithOptions run again to setup SEGAnalytics

That’s not how it works. The adsupportblock is called multiple times. You’re giving us a block we’ll call anytime we need the idfa value, which is likely every event that goes thru the system.

sanhue0302 commented 3 years ago

One other alternative is to capture it and store it somewhere. And your adSupportBlock just returns whatever the value that's stored (initially nil I suppose).

Since I Setup SEGAnalytics when didFinishLaunchingWithOptions, the adSupportBlock will only run one time So, if I store it after user confirm it, We still need to restart app to let didFinishLaunchingWithOptions run again to setup SEGAnalytics

That’s not how it works. The adsupportblock is called multiple times. You’re giving us a block we’ll call anytime we need the idfa value, which is likely every event that goes thru the system.

Ok, I did trace into the code. The adsupportblock is called in the method updateStaticContext. It will be called on each time applicationWillEnterForeground be called.

The only problem is when the user first time set the permission, it will apply on next time app enter foreground.