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

- 39,540
- 23
- 113
- 143

- 7,936
- 14
- 49
- 79
-
3Note that Apple is now advising against accessing IDFA in apps that don't have ads: https://github.com/mixpanel/mixpanel-iphone/issues/109 – Louis St-Amour Feb 02 '14 at 06:05
12 Answers
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);

- 1,356
- 1
- 8
- 12
-
13
-
@parsley72 you can use "@import AdSupport;" instead so you don't have the additional step of adding the framework. Edited the answer to include this. – vinnybad Oct 12 '15 at 04:38
-
3Using Swift: `import AdSupport`, then `ASIdentifierManager.sharedManager().advertisingIdentifier` to get the IDFA! – nodebase Sep 13 '16 at 19:57
-
1Note that on iOS 10, if the user has enabled Limit Ad Tracking, this IDFA will be all zeros on a physical device. (In the simulator as of Xcode 8 GM seed, it still seems to return an arbitrary IDFA.) – Zachary Drake Sep 14 '16 at 03:16
-
Note that soon (as of September 2020) you'll have to ask user permission to use IDFA. You have to use App Tracking Transparency to do this: https://developer.apple.com/documentation/apptrackingtransparency – Zachary Drake Sep 14 '20 at 16:28
-
To ask permission to get the user's IDFA, you have to launch the ATT permission flow: #import
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { // Tracking authorization completed. Start loading ads here. }]; – Zachary Drake Feb 17 '22 at 21:39
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
}

- 39,540
- 23
- 113
- 143
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
}

- 29,217
- 8
- 193
- 205
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.

- 43,043
- 8
- 107
- 153
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
}

- 2,313
- 1
- 22
- 23
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/

- 5,727
- 3
- 38
- 59
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
}

- 20,202
- 8
- 59
- 80
-
cool, but you don't need to use IDFA as a singleton, ASIdentifierManager is already a singleton, so, just make the var as class var to use them directly – busta117 Nov 21 '18 at 01:30
Swift 3 & 4
var IDFA = String()
if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
IDFA = ASIdentifierManager.shared().advertisingIdentifier
}

- 1,771
- 1
- 24
- 38
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
}
}

- 994
- 11
- 18
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
}
}

- 1,448
- 16
- 23

- 1,598
- 19
- 25
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
}
}

- 335
- 3
- 8
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
}
}

- 2,549
- 1
- 23
- 36