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.
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:
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.
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
}
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.”
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
}
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
}
}
#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
}
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
}
}