<br />

When an impression occurs, Google Mobile Ads SDK provides ad revenue data
associated with that impression. You can use the data to calculate a user's
lifetime value, or forward the data downstream to other relevant systems.

This guide is intended to help you implement LTV data capture in your iOS app.

## Prerequisites

- Make sure you have [turned on the impression-level ad revenue
  feature](https://support.google.com/admanager/answer/13404416) in the Ad Manager UI.

<!-- -->

- Import Google Mobile Ads SDK 9.10.0 or higher.
- [Set up Google Mobile Ads SDK](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/quick-start.md.txt).
- Before you can receive any impression-level ad revenue, you need to implement
  at least one ad format:

  - [Banner](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/banner.md.txt)
  - [Interstitial](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/interstitial.md.txt)
  - [Rewarded](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/rewarded.md.txt)
  - [Rewarded Interstitial](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/rewarded-interstitial.md.txt)
  - [Native](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/native.md.txt)

## Handle paid events

Each ad format's delegate protocol includes a `didRecordPaidEventWithAdValue:`
method. During an ad lifecycle, Google Mobile Ads SDK monitors impression
events and calls this delegate method with an earned
[`GADAdValue`](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GADAdValue.md.txt) object.

The following example handles paid events for a rewarded ad:

### Swift

```swift
func ad(_ ad: FullScreenPresentingAd, didRecordPaidEventWith adValue: AdValue) {
  // TODO: Send the impression-level ad revenue information to your preferred
  // analytics server directly within this callback.

  // Extract the impression-level ad revenue data.
  let value = adValue.value
  let currencyCode = adValue.currencyCode
  let precision = adValue.precision

  print(
    "Ad paid event. Value: \(value) \(currencyCode), with precision: \(precision)."
  )
}
```

### Objective-C

```objective-c
- (void)ad:(id<GADFullScreenPresentingAd>)ad didRecordPaidEventWithAdValue:(GADAdValue *)adValue {
  // TODO: Send the impression-level ad revenue information to your preferred
  // analytics server directly within this callback.

  // Extract the impression-level ad revenue data.
  NSDecimalNumber *value = adValue.value;
  NSString *currencyCode = adValue.currencyCode;
  GADAdValuePrecision precision = adValue.precision;

  NSLog(@"Ad paid event. Value: %@ %@, with precision: %ld.", value, currencyCode, (long)precision);
}
```

### Identify a custom event ad source name

For custom event ad sources, [`adSourceName`](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GADAdNetworkResponseInfo.md.txt#adsourcename)
property gives you the ad source name `Custom event`. If you use multiple custom
events, the ad source name isn't granular enough to distinguish between multiple
custom events. To locate a specific custom event, do the following steps:

1. Get the [`adNetworkClassName`](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GADAdNetworkResponseInfo.md.txt#adnetworkclassname) property.
2. Set a unique ad source name.

The following example sets a unique ad source name for a custom event:

### Swift

```swift
func uniqueAdSourceName(for loadedAdNetworkResponseInfo: AdNetworkResponseInfo) -> String {
  var adSourceName: String = loadedAdNetworkResponseInfo.adSourceName ?? ""
  if adSourceName == "Custom Event" {
    if loadedAdNetworkResponseInfo.adNetworkClassName
      == "MediationExample.SampleCustomEventSwift"
    {
      adSourceName = "Sample Ad Network (Custom Event)"
    }
  }
  return adSourceName
}
```

### Objective-C

```objective-c
- (NSString *)uniqueAdSourceNameForAdNetworkResponseInfo:
    (GADAdNetworkResponseInfo *)loadedAdNetworkResponseInfo {
  NSString *adSourceName = loadedAdNetworkResponseInfo.adSourceName;
  if ([adSourceName isEqualToString:@"Custom Event"]) {
    if ([loadedAdNetworkResponseInfo.adNetworkClassName isEqualToString:@"SampleCustomEvent"]) {
      adSourceName = @"Sample Ad Network (Custom Event)";
    }
  }
  return adSourceName;
}
```

For more information on the winning ad source, see [Retrieve information about
the ad response](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/response-info).

### Implementation best practices

- Set the delegate immediately once you create or get access to the ad object, and definitely before showing the ad. This makes sure that you don't miss any paid event callbacks.
- Send the paid event information to your preferred analytics server immediately at the time the `didRecordPaidEventWithAdValue:` delegate method is called. This makes sure that you don't accidentally drop any callbacks and avoids data discrepancies.

## GADAdValue

`GADAdValue` is a class that represents the monetary value earned for an ad,
including the value's currency code and its precision type encoded as following.

> [!IMPORTANT]
> **Key Point:** The value of [`GADAdValue.value`](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GADAdValue.md.txt#value) is a decimal number that represents each ad's worth. For example, a value of 0.005 means this ad is estimated to be worth $0.005.

| GADAdValuePrecision | Description |
|---|---|
| `GADAdValuePrecisionUnknown` | An ad value that's unknown. This gets returned when LTV pingback is enabled but there isn't enough data available. |
| `GADAdValuePrecisionEstimated` | An ad value estimated from aggregated data. |
| `GADAdValuePrecisionPublisherProvided` | A publisher provided ad value, such as manual CPMs in a mediation group. |
| `GADAdValuePrecisionPrecise` | The precise value paid for this ad. |

> [!IMPORTANT]
> **Key Point:** In the case of mediation, Ad Manager tries to provide a `GADAdValuePrecisionEstimated` first and falls back to `GADAdValuePrecisionPublisherProvided` if there isn't enough aggregated data to report a meaningful value.

### Test impressions from Open Bidding

After an impression-level ad revenue event occurs for
an Open Bidding
ad source through a test request, you receive only the following
values:

- `GADAdValuePrecisionUnknown`: indicates the precision type.

<!-- -->

- `0`: indicates the ad value.

Previously, you might have seen the precision type as a value other than `GADAdValuePrecisionUnknown` and an ad value more than `0`.

For details on sending a test ad request, see
[Enable test devices](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/test-ads.md.txt#enable-test-devices).