How to retrieve iPhone IDFA from API?

IosIphoneTvosIdfa

Ios Problem Overview


I would like to get the device IDFA. How to get this info from iOS official API ?

Ios Solutions


Solution 1 - Ios

First, you have to ask permission from the user to use their IDFA:

#import <AppTrackingTransparency/AppTrackingTransparency.h> 

[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
 // Tracking authorization completed. Start loading ads here. 
 }];

This permission flow will only run once, the first time it is called, even if you re-start the app and/or call it again. If you want to answer differently, you'll have to delete the app off the device or simulator completely and reinstall it. Note that iOS simulators return blanked IDFAs (all zeroes) no matter what the answer to the permission flow. See https://developer.apple.com/documentation/apptrackingtransparency for details, including how to customize the message shown to users when asking to track them. Note that many advertising SDKs have their own consent flow calls that you can use.

To actually get the IDFA once you have permission:

#import <AdSupport/ASIdentifierManager.h> 

If you would like to get it as an NSString, use:

[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]

So your code might look like this:

NSString *idfaString = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSLog (@"IDFA: %@", idfaString);

Solution 2 - Ios

You first have to check if user user has decided to opt out from ad tracking. Only if he allowed it you can use the IDFA.

You can check it by calling isAdvertisingTrackingEnabled method of ASIdentifierManager.

> isAdvertisingTrackingEnabled > > Check the value of this property before performing any advertising > tracking. If the value is NO, use the advertising identifier only for > the following purposes: frequency capping, conversion events, > estimating the number of unique users, security and fraud detection, > and debugging.

The following code snippet shows how to obtain a string value of IDFA.

ObjC
@import AdSupport;

- (NSString *)identifierForAdvertising {
    // Check whether advertising tracking is enabled
    if([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
        NSUUID *identifier = [[ASIdentifierManager sharedManager] advertisingIdentifier];
        return [identifier UUIDString];
    }

    // Get and return IDFA
    return nil;
}
Swift
import AdSupport

func identifierForAdvertising() -> String? {
    // Check whether advertising tracking is enabled
    guard ASIdentifierManager.shared().isAdvertisingTrackingEnabled else {
        return nil
    }

    // Get and return IDFA
    return ASIdentifierManager.shared().advertisingIdentifier.uuidString
}

Solution 3 - Ios

IDFA - Identifier for Advertising

isAdvertisingTrackingEnabled -> trackingAuthorizationStatus

From iOS v14 Apple deprecated isAdvertisingTrackingEnabled and moved the logic into AppTrackingTransparency Framework. Now user has to grand a permission to read idfa(in the same way as Location permission)

User can control it via:

#iOS 13
#AdSupport
#ASIdentifierManager.shared().isAdvertisingTrackingEnabled
Settings -> Privacy -> Advertising -> Limit Ad Tracking
#iOS 14
#AppTrackingTransparency
#ATTrackingManager.trackingAuthorizationStatus

#a global flag
Settings -> Privacy -> Tracking -> `Allow Apps to Request to Track` 
#or select an app from list to control every app separately 

#a local flag
Settings -> <app_name> -> Allow Tracking 

Implementation

import AppTrackingTransparency
import AdSupport
func getIDFA() -> String? {
    // Check whether advertising tracking is enabled
    if #available(iOS 14, *) {
        if ATTrackingManager.trackingAuthorizationStatus != ATTrackingManager.AuthorizationStatus.authorized  {
            return nil
        }
    } else {
        if ASIdentifierManager.shared().isAdvertisingTrackingEnabled == false {
            return nil
        }
    }

    return ASIdentifierManager.shared().advertisingIdentifier.uuidString
}

Solution 4 - Ios

ASIdentifierManager is the official way to garner the Advertising Identification Number from a device running iOS 6+. You can use -[[ASIdentifierManager sharedManager] advertisingIdentifier]; to get it.

Solution 5 - Ios

Get IDFA in Swift:

    import AdSupport

    ...
    
    let myIDFA: String?
    // Check if Advertising Tracking is Enabled
    if ASIdentifierManager.sharedManager().advertisingTrackingEnabled {
        // Set the IDFA
        myIDFA = ASIdentifierManager.sharedManager().advertisingIdentifier.UUIDString
    } else {
        myIDFA = nil
    }

Solution 6 - Ios

Beginning in iOS 10, when a user enables “Limit Ad Tracking,” the OS will send along the advertising identifier with a new value of “00000000-0000-0000-0000-000000000000.”

As per this article: https://fpf.org/2016/08/02/ios-10-feature-stronger-limit-ad-tracking/

Solution 7 - Ios

Here's a commented helper class in Swift that will give you a nil object for the identifier if the user has turned advertisement tracking off:

import AdSupport

class IDFA {
    // MARK: - Stored Type Properties
    static let shared = IDFA()

    // MARK: - Computed Instance Properties
    /// Returns `true` if the user has turned off advertisement tracking, else `false`.
    var limited: Bool {
        return !ASIdentifierManager.shared().isAdvertisingTrackingEnabled
    }

    /// Returns the identifier if the user has turned advertisement tracking on, else `nil`.
    var identifier: String? {
        guard !limited else { return nil }
        return ASIdentifierManager.shared().advertisingIdentifier.uuidString
    }
}

Just add it to your project (for example in a file named IDFA.swift) and link the AdSupport.framework in your target via the "Linked Frameworks and Libraries" section in the General settings tab.

Then you can use it like this:

if let identifier = IDFA.shared.identifier {
    // use the identifier
} else {
    // put any fallback logic in here
}

Solution 8 - Ios

Swift 3 & 4

var IDFA = String()
if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
            IDFA = ASIdentifierManager.shared().advertisingIdentifier
}

Solution 9 - Ios

Please pay attention that in iOS 14, ASIdentifierManager.shared().isAdvertisingTrackingEnabled is deprecated. please use ATTrackingManager.trackingAuthorizationStatus == .authorized instead.

import AdSupport
import AppTrackingTransparency

extension ASIdentifierManager {
    //NOTE: if the user has enabled Limit Ad Tracking, this IDFA will be all zeros on a physical device
    static var identifierForAdvertising: String {

        // Check whether advertising tracking is enabled
        if #available(iOS 14, *) {
            guard ATTrackingManager.trackingAuthorizationStatus == .authorized else {
                return ""
            }
        } else {
            guard ASIdentifierManager.shared().isAdvertisingTrackingEnabled else {
                return ""
            }
        }
            
        // Get and return IDFA
        return ASIdentifierManager.shared().advertisingIdentifier.uuidString
    }
}

Solution 10 - Ios

A nicer approach to get the IDFA or nil if tracking is disabled via iOS Setting is using a (private) extension:

import AdSupport

class YourClass {

    func printIDFA() {
        print(ASIdentifierManager.shared().advertisingIdentifierIfPresent)
    }
}

private extension ASIdentifierManager {

    /// IDFA or nil if ad tracking is disabled via iOS system settings
    var advertisingIdentifierIfPresent: String? {
        if isAdvertisingTrackingEnabled {
            return advertisingIdentifier.uuidString
        }

        return nil 
    }        
}

Solution 11 - Ios

Just to extend Amro's Swift answer, here's similar code wrapped in a method:

import AdSupport

...

func provideIdentifierForAdvertisingIfAvailable() -> String? {
    if ASIdentifierManager.sharedManager().advertisingTrackingEnabled {
      return ASIdentifierManager.sharedManager().advertisingIdentifier?.UUIDString ?? nil
    } else {
      return nil
    }
  }

Solution 12 - Ios

Swift 5 with encapsulation:

import AdSupport

struct ID{
    static var advertising: String? {
         // Firstly, Check whether advertising tracking is enabled
         guard ASIdentifierManager.shared().isAdvertisingTrackingEnabled else {
              return nil
         }
         // Then, Get and return IDFA
         return ASIdentifierManager.shared().advertisingIdentifier.uuidString
     }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionfvisticotView Question on Stackoverflow
Solution 1 - IosZachary DrakeView Answer on Stackoverflow
Solution 2 - IosRafa de KingView Answer on Stackoverflow
Solution 3 - IosyoAlex5View Answer on Stackoverflow
Solution 4 - IosCodaFiView Answer on Stackoverflow
Solution 5 - IosAmr HossamView Answer on Stackoverflow
Solution 6 - IosVladView Answer on Stackoverflow
Solution 7 - IosJeehutView Answer on Stackoverflow
Solution 8 - IosOscar FalmerView Answer on Stackoverflow
Solution 9 - IosyonivavView Answer on Stackoverflow
Solution 10 - IosJochen HolzerView Answer on Stackoverflow
Solution 11 - IosworthbakView Answer on Stackoverflow
Solution 12 - Iosblack_pearlView Answer on Stackoverflow