---
metadata:
  - name: generator
    content: Diplodoc Platform v5.55.2
alternate:
  - https://ads.yandex.com/helpcenter/en/dev/ios/release/8-0-0-migration.md
  - https://ads.yandex.com/helpcenter/ru/dev/ios/release/8-0-0-migration.md
  - https://ads.yandex.com/helpcenter/zh/dev/ios/release/8-0-0-migration.md
  - href: zh/dev/ios/release/8-0-0-migration.md
    type: text/markdown
    title: Markdown version
  - href: ../llms.txt
    type: text/markdown
    title: llms.txt
---
> **Documentation Index:** Fetch the complete configuration index at https://ads.yandex.com/helpcenter/zh/llms.txt

# 迁移至版本 8 的指南

Yandex Mobile Ads SDK 8.0.0 引入了多项 API 变更，旨在提升开发者体验。

{% note info "" %}

对于 Objective-C 项目，请参阅[第 14 节](#main-actor) (MainActor)，以确保正确处理 MainActor 隔离类。 在主线程上执行与这些类相关的操作。

{% endnote %}

{% note tip "使用 AI 工具迁移" %}

为加快从 SDK 7.x 到 8.x 的迁移，可使用内置迁移技能的 AI 助手，详情参见[使用 AI 工具迁移](#ai)章节。

{% endnote %}

## 主要变更

### 1. AdRequest 变更

- 对所有广告格式使用 `AdRequest`。
- `AdRequestConfiguration` 和 `NativeAdRequestConfiguration` 类以及所有可变请求类均已被移除。
- 在 `AdRequest` 初始化期间，`adUnitID` 属性现在作为必需参数传递。

#|
|| **类** | **状态** ||
|| `AdRequestConfiguration` | 已移除。 使用 `AdRequest` ||
|| `NativeAdRequestConfiguration` | 已移除。 使用 `AdRequest` 和 `NativeAdOptions` ||
|| `MutableAdRequest` | 已移除 ||
|| `MutableAdRequestConfiguration` | 已移除 ||
|| `MutableNativeAdRequestConfiguration` | 已移除 ||
|#

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   let configuration = AdRequestConfiguration(adUnitID: "R-M-XXXXX-YY")
   loader.loadAd(with: configuration)
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   let request = AdRequest(adUnitID: "R-M-XXXXX-YY") loader.loadAd(with: request) { … }
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   YMAAdRequestConfiguration *configuration =
       [[YMAAdRequestConfiguration alloc] initWithAdUnitID:@"R-M-XXXXX-YY"];
   [loader loadAdWithConfiguration:configuration];
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   YMAAdRequest *request =
       [[YMAAdRequest alloc] initWithAdUnitID:@"R-M-XXXXX-YY"];
   [loader loadAdWithRequest:request
          completionHandler:^(YMAInterstitialAd * _Nullable ad,
                              NSError * _Nullable error) {
       if (ad) {
           // 广告已加载
       } else {
           // 加载错误
       }
   }];
   ```
   ||
   |#

{% endlist %}

### 2. 定位变更

- 字段 `age`、`gender`、`location`、`contextQuery` 和 `contextTags` 已从 `AdRequest` 中移除。
- 要管理定位参数，请使用新的 `AdTargeting` 类。

{% note info "" %}

`AdTargetInfo` 类已重命名为 `AdTargeting`，`AdRequestTokenConfiguration` 和 `BidderTokenRequestConfiguration` 中的 `targetInfo` 字段已重命名为 `targeting`。

{% endnote %}

#|
|| **类**  | **状态** ||
|| `AdTargetInfo` | 已重命名为 `AdTargeting` ||
|#

#|
|| **类** | **属性** | **状态** ||
|| `AdRequest` | `age` | 已移除。 使用 `AdTargeting.age` ||
|| ^ | `gender` | 已移除。 使用 `AdTargeting.gender` ||
|| ^ | `location` | 已移除。 使用 `AdTargeting.location` ||
|| ^ | `contextQuery` | 已移除。 使用 `AdTargeting.contextQuery` ||
|| ^ | `contextTags` | 已移除。 使用 `AdTargeting.contextTags` ||
|| ^ | `targeting` | 已添加 ||
|| `AdTargeting` |  `targetInfo` | 已重命名为 `targeting` ||
|#

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   let request = AdRequest(
       adUnitID: "R-M-XXXXX-YY",
       age: 25,
       gender: kYMAGenderMale,
       location: location
   )
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   let targeting = AdTargeting(
       age: 25,
       gender: .male,
       location: location
   )
   let request = AdRequest(adUnitID: "R-M-XXXXX-YY", targeting: targeting)
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   YMAAdRequest *request = [[YMAAdRequest alloc] initWithAdUnitID:@"R-M-XXXXX-YY"
                                                              age:@(25)
                                                           gender:kYMAGenderMale
                                                         location:location];
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   YMAAdTargeting *targeting = [[YMAAdTargeting alloc] initWithAge:@(25)
                                                            gender:YMAGender.male
                                                          location:location
                                                      contextQuery:nil
                                                       contextTags:nil];
   YMAAdRequest *request = [[YMAAdRequest alloc] initWithAdUnitID:@"R-M-XXXXX-YY"
                                                         targeting:targeting];
   ```
   ||
   |#

{% endlist %}

### 3. 广告加载器变更

- 加载委托已被移除。 加载结果现在通过 `completion` 处理程序传递。
- 通过 `AdRequest` 传递 `adUnitID` 参数。

#|
|| **类** | **加载器** | **状态** ||
|| `AppOpenAdLoader` | `loadAd(with:)` + 委托 | 已替换为 `loadAd(with:completion:)` ||
|| `InterstitialAdLoader` | `loadAd(with:)` + 委托 | 已替换为 `loadAd(with:completion:)` ||
|| `RewardedAdLoader` | `loadAd(with:)` + 委托 | 已替换为 `loadAd(with:completion:)` ||
|| `NativeAdLoader` | `loadAd(with:)` + 委托 | 已替换为 `loadAd(with:options:completion:)` ||
|| `NativeBulkAdLoader` | `loadAds(with:adsCount:)` + 委托 | 已替换为 `loadAds(with:adsCount:options:completion:)` ||
|| `SliderAdLoader` | `loadAd(with:)` + 委托 | 已替换为 `loadAd(with:options:completion:)`||
|#

#|
|| **类** | **状态** ||
|| `AppOpenAdLoaderDelegate` | 已移除 ||
|| `InterstitialAdLoaderDelegate`| ^ ||
|| `RewardedAdLoaderDelegate`| ^ ||
|| `NativeAdLoaderDelegate`| ^ ||
|| `NativeBulkAdLoaderDelegate` | ^ ||
|| `SliderAdLoaderDelegate` | ^ ||
|#

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   // 插屏广告
   let configuration = AdRequestConfiguration(adUnitID: "R-M-XXXXX-YY")
   interstitialAdLoader.delegate = self
   interstitialAdLoader.loadAd(with: configuration)

   // 原生广告
   let nativeConfiguration = NativeAdRequestConfiguration(adUnitID: "R-M-XXXXX-YY")
   nativeAdLoader.delegate = self
   nativeAdLoader.loadAd(with: nativeConfiguration)
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   // 插屏广告
   let request = AdRequest(adUnitID: "R-M-XXXXX-YY")
   interstitialAdLoader.loadAd(with: request) { result in
       switch result {
       case .success(let ad):
           // 广告已加载
       case .failure(let error):
           // 加载错误
       }
   }

   // 原生广告
   let options = NativeAdOptions()
   nativeAdLoader.loadAd(with: request, options: options) { result in
       switch result {
       case .success(let ad):
           // 广告已加载
       case .failure(let error):
           // 加载错误
       }
   }
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   // 插屏广告
   YMAAdRequestConfiguration *configuration =
       [[YMAAdRequestConfiguration alloc] initWithAdUnitID:@"R-M-XXXXX-YY"];
   interstitialAdLoader.delegate = self;
   [interstitialAdLoader loadAdWithConfiguration:configuration];

   // 原生广告
   YMANativeAdRequestConfiguration *nativeConfig =
       [[YMANativeAdRequestConfiguration alloc] initWithAdUnitID:@"R-M-XXXXX-YY"];
   nativeAdLoader.delegate = self;
   [nativeAdLoader loadAdWithConfiguration:nativeConfig];
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   // 插屏广告
   YMAAdRequest *request =
       [[YMAAdRequest alloc] initWithAdUnitID:@"R-M-XXXXX-YY"];
   [interstitialAdLoader loadAdWithRequest:request
                         completionHandler:^(YMAInterstitialAd * _Nullable ad,
                                             NSError * _Nullable error) {
       if (ad) {
           // 广告已加载
       } else {
           // 加载错误
       }
   }];

   // 原生广告
   YMANativeAdOptions *options = [[YMANativeAdOptions alloc] init];
   [nativeAdLoader loadAdWithRequest:request
                             options:options
                   completionHandler:^(id<YMANativeAd> _Nullable ad,
                                       NSError * _Nullable error) {
       if (ad) {
           // 广告已加载
       } else {
           // 加载错误
       }
   }];
   ```
   ||
   |#

{% endlist %}

### 3.1 Structured Concurrency 支持

所有广告加载器现在均支持 Swift Structured Concurrency (async/await)。

#|
|| **加载器** | **方法** | **状态** ||
|| `AppOpenAdLoader` | `loadAd(with:)` | 已添加 ||
|| `InterstitialAdLoader` | `loadAd(with:)` | ^ ||
|| `RewardedAdLoader` | `loadAd(with:)` | ^ ||
|| `NativeAdLoader` | `loadAd(with:options:)` | ^ ||
|| `NativeBulkAdLoader` | `loadAds(with:adsCount:options:)` | ^ ||
|| `SliderAdLoader` | `loadAd(with:options:)` | ^ ||
|#

#### 示例

{% list tabs %}

- Swift

   ```swift
   let request = AdRequest(adUnitID: "R-M-XXXXX-YY")

   // 插屏广告
   let interstitialAd = try await interstitialAdLoader.loadAd(with: request)

   // 激励广告
   let rewardedAd = try await rewardedAdLoader.loadAd(with: request)

   // 开屏广告
   let appOpenAd = try await appOpenAdLoader.loadAd(with: request)

   // 原生广告
   let options = NativeAdOptions()
   let nativeAd = try await nativeAdLoader.loadAd(with: request, options: options)

   // 滑动广告
   let sliderAd = try await sliderAdLoader.loadAd(with: request, options: options)

   // 原生批量广告
   let nativeAds = try await nativeBulkAdLoader.loadAds(with: request, adsCount: 3, options: options)
   ```

- Objective-C

  *Structured Concurrency 仅在 Swift 中可用。*

{% endlist %}

### 4. Banner API 的变更

- `AdView` 类已重命名为 `BannerAdView`，`AdViewDelegate` 协议已重命名为 `BannerAdViewDelegate`。
- `BannerAdView` 不再包含 `adUnitID` 属性。在每次加载广告前，请将 `adUnitID` 传递到 `AdRequest` 构建器。
- `BannerAdSize` 工厂方法已重命名。

#|
|| **类** | **状态** ||
|| `AdView` | 已重命名为 `BannerAdView` ||
|| `AdViewDelegate` | 已重命名为 `BannerAdViewDelegate` ||
|#

#|
|| **类** | **属性** | **状态** ||
|| `BannerAdView` | `adViewDidLoad` | 已重命名为 `bannerAdViewDidLoad`  ||
|| ^ | `adViewDidFailLoading` | 已重命名为 `bannerAdViewDidFailLoading`  ||
|| ^ | `adViewDidClick` | 已重命名为 `bannerAdViewDidClick` ||
|| ^ | `adView(_:didTrackImpression:)` | 已重命名为 `bannerAdView(_:didTrackImpression:)` ||
|| ^ | `AdView(adUnitID:adSize:)` | 已替换为 `BannerAdView(adSize:)` ||
|| ^ | `AdView.adUnitID` | 已替换为 `BannerAdView.adInfo?.adUnitID` ||
|| ^ | `AdView.loadAd()` |  已移除 ||
|| ^ | `AdView.loadAd(with: AdRequest?)` | 已替换为 `BannerAdView.loadAd(with: AdRequest)` ||
|| `BannerAdSize` | `fixedSize(withWidth:height:)` | 已重命名为 `fixed(width:height:)` ||
|| ^ | `inlineSize(withWidth:maxHeight:)` | 已重命名为 `inline(width:maxHeight:)` ||
|| ^ | `stickySize(withContainerWidth:)` | 已重命名为 `sticky(containerWidth:)` ||
|#

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   let adSize = BannerAdSize.stickySize(withContainerWidth: screenWidth)
   let adView = AdView(adUnitID: "R-M-XXXXX-YY", adSize: adSize)
   adView.delegate = self
   adView.loadAd()
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   let adSize = BannerAdSize.sticky(containerWidth: screenWidth)
   let bannerAdView = BannerAdView(adSize: adSize)
   bannerAdView.delegate = self
   let request = AdRequest(adUnitID: "R-M-XXXXX-YY")
   bannerAdView.loadAd(with: request)
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   YMABannerAdSize *adSize = [YMABannerAdSize stickySizeWithContainerWidth:screenWidth];
   YMAAdView *adView = [[YMAAdView alloc] initWithAdUnitID:@"R-M-XXXXX-YY"
                                                    adSize:adSize];
   adView.delegate = self;
   [adView loadAd];
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   YMABannerAdSize *adSize = [YMABannerAdSize stickyWithContainerWidth:screenWidth];
   YMABannerAdView *bannerAdView = [[YMABannerAdView alloc] initWithAdSize:adSize];
   bannerAdView.delegate = self;
   YMAAdRequest *request = [[YMAAdRequest alloc] initWithAdUnitID:@"R-M-XXXXX-YY"];
   [bannerAdView loadAdWithRequest:request];
   ```
   ||
   |#

{% endlist %}

### 5. AdInfo 变更

- 部分广告对象属性已被移除：`info`、`adAttributes`、`creativeID` 和 `campaignID`。
- 使用 `adInfo`。 部分 `adInfo` 属性已重命名。

#|
|| **类** | **属性** |  **状态** ||
|| `AdInfo` | `adUnitId` | 已重命名为 `adUnitID` ||
|| ^ | `data` | 已重命名为 `extraData` ||
|| ^ | `adSize` | 已移除 ||
|| ^ | `partnerText` | 已添加 ||
|| `BannerAdView`、<br>`NativeAd`、<br>`SliderAd`、<br>`AppOpenAd`、<br>`InterstitialAd`、<br>`RewardedAd` | `info` | 已重命名为 `adInfo.extraData` ||
|| ^ | `adAttributes` | 已替换为 `adInfo.creatives`  ||
|| ^ | `creativeID` | 已替换为 `adInfo.creatives[i].creativeID`  ||
|| ^ | `campaignID` | 已替换为 `adInfo.creatives[i].campaignID`  ||
|| `Creative` | `placeID` | 已添加   ||
|| ^ | `offerID` | 已添加  ||
|#

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   // adAttributes 和 info
   let attributes = nativeAd.adAttributes
   let info = nativeAd.info

   // creativeID 和 campaignID
   let creativeID = interstitialAd.creativeID
   let campaignID = interstitialAd.campaignID

   // adUnitId
   let adUnitId = interstitialAd.adInfo.adUnitId

   // adSize (available)
   let size = bannerAdView.adInfo.adSize
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   // adInfo.creatives 和 adInfo.extraData
   let creatives = nativeAd.adInfo.creatives
   let extraData = nativeAd.adInfo.extraData

   // 通过创意获得的 creativeID、campaignID、placeID、offerID
   if let creative = interstitialAd.adInfo.creatives.first {
       let creativeID = creative.creativeID
       let campaignID = creative.campaignID
       let placeID = creative.placeID
       let offerID = creative.offerID
   }

   // adUnitID（已重命名）
   let adUnitID = interstitialAd.adInfo.adUnitID

   // partnerText（新建）
   let partnerText = interstitialAd.adInfo.partnerText

   // adSize 已删除 — 横幅尺寸在 BannerAdView.adSize 中可用
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   // adAttributes 和 info
   NSArray *attributes = nativeAd.adAttributes;
   NSDictionary *info = nativeAd.info;

   // creativeID 和 campaignID
   NSString *creativeID = interstitialAd.creativeID;
   NSString *campaignID = interstitialAd.campaignID;

   // adUnitId
   NSString *adUnitId = interstitialAd.adInfo.adUnitId;

   // adSize（可用）
   YMAAdSize *size = bannerAdView.adInfo.adSize;
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   // adInfo.creatives 和 adInfo.extraData
   NSArray<YMACreative *> *creatives = nativeAd.adInfo.creatives;
   NSDictionary *extraData = nativeAd.adInfo.extraData;

   // 通过创意获得的 creativeID、campaignID、placeID、offerID
   YMACreative *creative = interstitialAd.adInfo.creatives.firstObject;
   if (creative != nil) {
       NSString *creativeID = creative.creativeID;
       NSString *campaignID = creative.campaignID;
       NSString *placeID = creative.placeID;
       NSString *offerID = creative.offerID;
   }

   // adUnitID（已重命名）
   NSString *adUnitID = interstitialAd.adInfo.adUnitID;

   // partnerText（新建）
   NSString *partnerText = interstitialAd.adInfo.partnerText;

   // adSize 已删除 — 横幅尺寸在 YMABannerAdView.adSize 中可用
   ```
   ||
   |#

{% endlist %}

### 6. 主 SDK 类变更

- `MobileAds` 类已重命名为 `YandexAds`。
- 隐私方法和属性已重命名并移至新类。

#|
|| **类** | **状态** ||
|| `MobileAds` | 已重命名为 `YandexAds` ||
|| `MobileAds.sdkVersion` | 已替换为 `YandexAds.sdkVersion.stringValue` ||
|| `MobileAds.setLocationTrackingEnabled(_:)` | 已重命名为 `YandexAds.setLocationTracking(_:)` ||
|| `MobileAds.setAgeRestrictedUser(_:)` | 已重命名为 `YandexAds.setAgeRestricted(_:)` ||
|| `MobileAds.setUserConsent(_:)` | 已移至 `YandexAds.setUserConsent(_:)` ||
|| `YMANativeAdView` | 已重命名为 `NativeAdView` ||
|| `YMANativeMediaView` | 已重命名为 `NativeMediaView` ||
|#

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   import YandexMobileAds
   MobileAds.setLocationTrackingEnabled(true)
   MobileAds.setAgeRestrictedUser(false)
   MobileAds.setUserConsent(true)
   let version = MobileAds.sdkVersion
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   import YandexMobileAds
   YandexAds.setLocationTracking(true)
   YandexAds.setAgeRestricted(false)
   YandexAds.setUserConsent(true)
   let version = YandexAds.sdkVersion.stringValue
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   [YMAMobileAds setLocationTrackingEnabled:YES];
   [YMAMobileAds setAgeRestrictedUser:NO];
   [YMAMobileAds setUserConsent:YES];
   NSString *version = YMAMobileAds.sdkVersion;
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   [YMAYandexAds setLocationTracking:YES];
   [YMAYandexAds setAgeRestricted:NO];
   [YMAYandexAds setUserConsent:YES];
   NSString *version = YMAYandexAds.sdkVersion.stringValue;
   ```
   ||
   |#

{% endlist %}

### 7. 广告对象委托变更

委托方法 `AppOpenAdDelegate`、`InterstitialAdDelegate`、`RewardedAdDelegate`、`NativeAdDelegate` 和 `SliderAdDelegate` 不再可选，必须全部实施。

#### 展示相关方法

#|
|| **类** | **方法** | **状态** ||
|| `RewardedAdDelegate` |
```
rewardedAdDelegate(
  _:didFailToShowWithError:)
```
| 已重命名为
```
rewardedAdDelegate(
  _:didFailToShow:)
```
||
|| `InterstitialAdDelegate` |
```
interstitialAdDelegate(
  _:didFailToShowWithError:)
```
| 已重命名为
```
interstitialAdDelegate(
  _:didFailToShow:)
```
||
|| `AppOpenAdDelegate` |
```
appOpenAdDelegate(
  _:didFailToShowWithError:)
```
| 已重命名为

```
appOpenAdDelegate(
  _:didFailToShow:)
``` ||
|#

#### 展示跟踪方法

#|
|| **类** | **方法** |  **状态** ||
|| `NativeAdDelegate` |
```
nativeAd(
_:didTrackImpressionWith:)
```
| 已重命名为
```
nativeAd(
_:didTrackImpression:)
```
||
|| `RewardedAdDelegate` |
```
rewardedAdDelegate(
_:didTrackImpressionWith:)
```
| 已重命名为
```
rewardedAdDelegate(
_:didTrackImpression:)
```
||
|| `InterstitialAdDelegate` |
```
interstitialAdDelegate(
_:didTrackImpressionWith:)
```
| 已重命名为
```
interstitialAdDelegate(
_:didTrackImpression:)
```
||
|| `AppOpenAdDelegate` |
```
appOpenAdDelegate(
_:didTrackImpressionWith:)
```
| 已重命名为
```
appOpenAdDelegate(
_:didTrackImpression:)
```
||
|| `SliderAdDelegate` |
```
sliderAdDelegate(
_:didTrackImpressionWith:)
```
| 已重命名为
```
sliderAdDelegate(
_:didTrackImpression:)
```
||
|#

#### 已移除委托方法

#|
|| **委托** | **方法** | **状态** ||
|| `AdViewDelegate` | `close(_:)` | 已移除 ||
|| ^ | `viewControllerForPresentingModalView()` | ^ ||
|| ^ | `adViewWillLeaveApplication` | ^ ||
|| ^ | `adView(_:willPresentScreen:)` | ^ ||
|| ^ | `adView(_:didDismissScreen:)` | ^ ||
|| `NativeAdDelegate` | `close(_:)` | ^ ||
|| ^ | `viewControllerForPresentingModalView()` | ^ ||
|| ^ | `nativeAdWillLeaveApplication` | ^ ||
|| ^ | `nativeAd(_:willPresentScreen:)` | ^ ||
|| ^ | `nativeAd(_:didDismissScreen:)` | ^ ||
|| `SliderAdDelegate` | `sliderAdDidClose(_:)` | ^ ||
|| ^ | `sliderAdWillLeaveApplication` | ^ ||
|| ^ | `sliderAd(_:willPresentScreen:)` | ^ ||
|| ^ | `sliderAd(_:didDismissScreen:)` | ^ ||
|#

### 8. 原生广告变更：警告

- `NativeAdAssets` 中的 `warning` 字段类型已从 `String?` 更改为 `NativeAdWarning?`。
- `NativeAdWarning` 现包含一个新字段：`minimumRequiredArea`。 此字段指定必须分配给 `warning` 素材的广告的最小面积。

#|
|| **类** | **字段** | **状态** ||
|| `NativeAdAssets` | `warning: String?` | 字段类型已更改为 `warning: NativeAdWarning?` ||
|| `NativeAdWarning` | `value: String` | 已添加  ||
|| ^ | `minimumRequiredArea: Double` | 已添加  ||
|#

#### 示例

{% list tabs %}

- Swift

  #|
  || **SDK 7** ||
  ||
  ```swift
  let warningText: String? = nativeAd.adAssets.warning
  label.text = warningText
  ```
  ||

  || **SDK 8** ||
  ||
  ```swift
  let warning: NativeAdWarning? = nativeAd.adAssets.warning
  label.text = warning?.value
  ```
  ||
  |#

- Objective-C

  #|
  || **SDK 7** ||
  ||
  ```objc
  NSString *warningText = nativeAd.adAssets.warning;
  label.text = warningText;
  ```
  ||

  || **SDK 8** ||
  ||
  ```objc
  YMANativeAdWarning *warning = nativeAd.adAssets.warning;
  label.text = warning.value;
  ```
  ||
  |#

{% endlist %}

### 9. 原生广告变更：媒体

`NativeAdMedia` 现提供一个新属性：`hasVideo`。

#|
|| **类** | **属性** | **状态** ||
|| `NativeAdMedia` | `hasVideo: Bool` | 已添加 ||
|#

#### 示例

{% list tabs %}

- Swift

   ```swift
   // SDK 8
   if let media = nativeAd.adAssets.media, media.hasVideo {
       // 考虑广告中的视频内容
   }
   ```

- Objective-C

   ```objc
   // SDK 8
   if (nativeAd.adAssets.media != nil && nativeAd.adAssets.media.hasVideo) {
       // 考虑广告中的视频内容
   }
   ```

{% endlist %}

### 10. NativeAd 和 SliderAd 变更：loadImages

- `loadImages()` 方法已重命名为 `loadImages(completionHandler:)`。
- `NativeAdImageLoadingObserver` 协议已替换为 `completionHandler` 参数。
- 我们添加了 `loadImages()` 的异步版本。

#|
|| **类** | **状态** ||
|| `NativeAdImageLoadingObserver` |  已移除 ||
|#

#|
|| **类** | **方法** | **状态** ||
|| `NativeAd` | `loadImages()` + `NativeAdImageLoadingObserver` | 已替换为 `loadImages(completionHandler:)` / `loadImages()` (async)  ||
|| `SliderAd` | `loadImages()` + `NativeAdImageLoadingObserver` | 已替换为 `loadImages(completionHandler:)` / `loadImages()` (async)  ||
|#

**适用于:** `NativeAd` 和 `SliderAd`。

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   // NativeAd
   nativeAd.addImageLoadingObserver(self)
   nativeAd.loadImages()

   // SliderAd
   sliderAd.addImageLoadingObserver(self)
   sliderAd.loadImages()
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   // NativeAd（完成处理程序）
   nativeAd.loadImages { [weak self] in
       // 资源已加载
   }

   // NativeAd (async/await)
   await nativeAd.loadImages()

   // SliderAd（完成处理程序）
   sliderAd.loadImages { [weak self] in
       // 资源已加载
   }

   // SliderAd (async/await)
   await sliderAd.loadImages()
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   // NativeAd
   [nativeAd addImageLoadingObserver:self];
   [nativeAd loadImages];

   // SliderAd
   [sliderAd addImageLoadingObserver:self];
   [sliderAd loadImages];
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   // NativeAd
   [nativeAd loadImagesWithCompletionHandler:^{
       // 资源已加载
   }];

   // SliderAd
   [sliderAd loadImagesWithCompletionHandler:^{
       // 资源已加载
   }]
   ```
   ||
   |#

{% endlist %}

### 11. 移除 VideoController

`videoController` 属性和相关类（`VideoController` 和 `VideoDelegate`）已被移除。

#|
|| **属性** | **状态** ||
|| `AdView.videoController`  | 已移除 ||
|| `BannerAdView.videoController`  | ^ ||
|| `VideoController` | ^ ||
|| `VideoDelegate` | ^ ||
|#

### 12. 移除原生模板

原生模板已被完全移除。 所有相关类均不再可用。

#|
|| **模板**| **状态** ||
|| `NativeTemplateAppearance` | 已移除 ||
|| `MutableNativeTemplateAppearance` | ^ ||
|| `NativeTemplateHorizontalOffset`  | ^ ||
|| `NativeBannerView`  | ^ ||
|| `ButtonAppearance` | ^ ||
|| `MutableButtonAppearance`  | ^ ||
|| `ImageAppearance`  | ^ ||
|| `MutableImageAppearance` | ^ ||
|| `LabelAppearance`  | ^ ||
|| `MutableLabelAppearance` | ^ ||
|| `RatingAppearance`  | ^ ||
|| `MutableRatingAppearance`  | ^ ||
|| `SizeConstraint` | ^ ||
|| `MutableSizeConstraint`  | ^ ||
|| `SizeConstraintType` | ^ ||
|| `YMAHorizontalOffset`  | ^ ||
|#

### 13. 已移除常量和错误类型

#|
|| **常量和错误类型**| **状态** ||
|| `kYMAAdsErrorDomain` | 已移除 ||
|| `kYMANativeAdErrorDomain`  | 已移除 ||
|| `kYMAGenderFemale`, `kYMAGenderMale` | 已替换为 `Gender` 类 ||
|| `YMAVersion` 中的常量 | 已替换为 `YandexAds.sdkVersion.stringValue` ||
|| `MobileAds.sdkVersion` | 已替换为 `YandexAds.sdkVersion.stringValue`  ||
|| `AdErrorCode` | 已移除 ||
|| `NativeErrorCode` | 已移除 ||
|| `Version.prereleaseIdentifiers`  | 已移除 ||
|| `Version.buildMetadataIdentifiers` | 已移除 ||
|| `isYandexMobileAdsError` (在 `Error`/`NSError`) | 已移除 ||
|| `isYandexMobileNativeAdsError` (在 `Error`/`NSError`)| 已移除 ||
|#

### 14. Swift 6、MainActor 和 Sendable {#main-actor}

- SDK 是使用 Swift 6 构建的。
- 部分类和协议现在是 `MainActor` 隔离类和协议，其中一个协议要求 `Sendable`。

#### MainActor 隔离类

#|
|| **类** ||
|| `AppOpenAd` ||
|| `InterstitialAd` ||
|| `RewardedAd` ||
|| `AudioSessionManager` ||
|| `NativeVideoPlaybackControls` ||
|#

#### MainActor 隔离协议

#|
|| **协议** ||
|| `AppOpenAdDelegate` ||
|| `InterstitialAdDelegate` ||
|| `RewardedAdDelegate` ||
|| `NativeAd` ||
|| `NativeAdDelegate` ||
|| `SliderAd` ||
|| `SliderAdDelegate` ||
|| `BannerAdViewDelegate` ||
|#

`NativeAdImageLoadingObserver` 协议已被移除。 图片加载现在通过完成处理程序或 async/await 处理。

### 15. 其他变更

#|
|| **类** | **对象** | **状态** ||
|| `Rating` | `setRating(_:)` / `rating()` | 已替换为 `Rating.rating` 属性 ||
|| `NativeAd` | `bind(toSliderView:)` | 已移至 `SliderAd.bind(with:)` ||
|| `NativeVideoPlaybackProgressControl` | `reset` | 已移除 ||
|| `MobileAds` | `audioSessionManager()` | 已替换为 `YandexAds.audioSessionManager` 属性 ||
|#

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   rating.setRating(4.5)
   let value = rating.rating()

   let audioManager = MobileAds.audioSessionManager()
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   rating.rating = 4.5

   let audioManager = YandexAds.audioSessionManager
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   [rating setRating:4.5];
   CGFloat value = [rating rating];

   YMAAudioSessionManager *audioManager = [YMAMobileAds audioSessionManager];
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   rating.rating = 4.5;

   YMAAudioSessionManager *audioManager = YMAYandexAds.audioSessionManager;
   ```
   ||
   |#

{% endlist %}

## 聚合网络 API 变更

### 1. 聚合适配器的 AdapterIdentity 变更

- 现在，您可以通过 `AdapterIdentity` 设置聚合适配器的身份。
- 不再使用 `mediationNetworkName` 参数。
- 在 SDK 初始化之前，通过 `YandexAds.setAdapterIdentity(_:)` 全局设置适配器身份。

#|
|| **类** | **参数** | **状态** ||
|| `BidderTokenLoader` | `BidderTokenLoader(mediationNetworkName:)` | 已替换为 `BidderTokenLoader()` ||
|| `YandexAds` | `MobileAds.initialize()` | 已替换为 `YandexAds.setAdapterIdentity(_:)` + `YandexAds.initializeSDK()` ||
|| `AdapterIdentity` |
```
AdapterIdentity(
  adapterNetworkName:adapterVersion:adapterNetworkVersion:)
```
| 已添加 ||
|#

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   let tokenLoader = BidderTokenLoader(mediationNetworkName: "AdMob")
   let config = BidderTokenRequestConfiguration(adType: .interstitial)
   tokenLoader.loadBidderToken(requestConfiguration: config) { ... }

   MobileAds.initialize()
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   let tokenLoader = BidderTokenLoader()
   let request = BidderTokenRequest.interstitial()
   tokenLoader.loadBidderToken(request: request) { ... }

   let adapterIdentity = AdapterIdentity(
       adapterNetworkName: "AdMob",
       adapterVersion: "1.0.0",
       adapterNetworkVersion: "23.5.0"
   )
   YandexAds.setAdapterIdentity(adapterIdentity)
   YandexAds.initializeSDK()
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   YMABidderTokenLoader *tokenLoader =
       [[YMABidderTokenLoader alloc] initWithMediationNetworkName:@"AdMob"];
   YMABidderTokenRequestConfiguration *config =
       [[YMABidderTokenRequestConfiguration alloc] initWithAdType:YMAAdTypeInterstitial];
   [tokenLoader loadBidderTokenWithRequestConfiguration:config
                                    completionHandler:^(NSString *token) { ... }];

   [YMAMobileAds initialize];
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   YMABidderTokenLoader *tokenLoader = [[YMABidderTokenLoader alloc] init];
   YMABidderTokenRequest *request = [YMABidderTokenRequest interstitial];
   [tokenLoader loadBidderTokenWithRequest:request
                         completionHandler:^(NSString *token) { ... }];

   YMAAdapterIdentity *identity =
       [[YMAAdapterIdentity alloc] initWithAdapterNetworkName:@"AdMob"
                                              adapterVersion:@"1.0.0"
                                       adapterNetworkVersion:@"23.5.0"];
   [YMAYandexAds setAdapterIdentity:identity];
   [YMAYandexAds initializeSDK];
   ```
   ||
   |#

{% endlist %}

### 2. BidderTokenRequest 变更

- `BidderTokenRequestConfiguration` 类已重命名为 `BidderTokenRequest`。
- 初始化器和公共属性（`targetInfo`、`bannerAdSize` 和 `parameters`）已移至工厂方法参数。

#|
|| **类** | **状态** ||
|| `BidderTokenRequestConfiguration` | 已重命名为 `BidderTokenRequest` ||
|#

#|
|| **类** | **属性** | **状态** ||
|| `BidderTokenRequestConfiguration` | `init(adType: .banner)` + `.bannerAdSize` | 已替换为
```
BidderTokenRequest.banner(
  size:targeting:parameters:)
```
||
|| `BidderTokenRequestConfiguration` | `init(adType: .interstitial)` + `.targetInfo` | 已替换为
```
BidderTokenRequest.interstitial(
  targeting:parameters:)
```
||
|| `BidderTokenRequestConfiguration` | `init(adType: .rewarded)` + `.targetInfo` | 已替换为
```
BidderTokenRequest.rewarded(
  targeting:parameters:)
```
||
|| `BidderTokenRequestConfiguration` | `init(adType: .native)` + `.targetInfo` | 已替换为
```
BidderTokenRequest.native(
  targeting:parameters:)
```
||
|| `BidderTokenRequestConfiguration` | `init(adType: .appOpenAd)` + `.targetInfo` | 已替换为
```
BidderTokenRequest.appOpenAd(
  targeting:parameters:)
```
||
|| `BidderTokenLoader` |
```
loadBidderToken(
  requestConfiguration:completionHandler:)
```
| 已重命名为
```
loadBidderToken(
  request:completionHandler:)
```
||
|#

**适用于**使用 `BidderTokenLoader` 的聚合适配器。

#### 示例

{% list tabs %}

- Swift

   #|
   || **SDK 7** ||
   ||
   ```swift
   let config = BidderTokenRequestConfiguration(adType: .banner)
   config.bannerAdSize = adSize
   config.targetInfo = adTargetInfo
   tokenLoader.loadBidderToken(requestConfiguration: config) { ... }
   ```
   ||

   || **SDK 8** ||
   ||
   ```swift
   let targeting = AdTargeting()
   let request = BidderTokenRequest.banner(
       size: adSize,
       targeting: targeting,
       parameters: ["key": "value"]
   )
   tokenLoader.loadBidderToken(request: request) { ... }

   // 其他广告格式：
   let interstitialRequest = BidderTokenRequest.interstitial()
   let rewardedRequest = BidderTokenRequest.rewarded()
   let nativeRequest = BidderTokenRequest.native()
   let appOpenRequest = BidderTokenRequest.appOpenAd()
   ```
   ||
   |#

- Objective-C

   #|
   || **SDK 7** ||
   ||
   ```objc
   YMABidderTokenRequestConfiguration *config =
       [[YMABidderTokenRequestConfiguration alloc] initWithAdType:YMAAdTypeBanner];
   config.bannerAdSize = adSize;
   config.targetInfo = adTargetInfo;
   [tokenLoader loadBidderTokenWithRequestConfiguration:config
                                    completionHandler:^(NSString *token) { ... }];
   ```
   ||

   || **SDK 8** ||
   ||
   ```objc
   YMAAdTargeting *targeting = [[YMAAdTargeting alloc] initWithAge:nil
                                                            gender:nil
                                                          location:nil
                                                      contextQuery:nil
                                                       contextTags:nil];
   YMABidderTokenRequest *request = [YMABidderTokenRequest bannerWithSize:adSize
                                                                  targeting:targeting
                                                                parameters:@{@"key": @"value"}];
   [tokenLoader loadBidderTokenWithRequest:request
                         completionHandler:^(NSString *token) { ... }];

   // 其他广告格式：
   YMABidderTokenRequest *interstitialRequest = [YMABidderTokenRequest interstitial];
   YMABidderTokenRequest *rewardedRequest = [YMABidderTokenRequest rewarded];
   YMABidderTokenRequest *nativeRequest = [YMABidderTokenRequest native];
   YMABidderTokenRequest *appOpenRequest = [YMABidderTokenRequest appOpenAd];
   ```
   ||
   |#

{% endlist %}

## SwiftUI 集成

API 现支持 SwiftUI 集成。 查看 iOS 文档菜单末尾的 SwiftUI 部分：

- [自适应内联横幅](https://ads.yandex.com/helpcenter/zh/dev/ios/swiftui/adaptive-inline-banner.md)
- [自适应粘性横幅](https://ads.yandex.com/helpcenter/zh/dev/ios/swiftui/adaptive-sticky-banner.md)
- [插屏广告](https://ads.yandex.com/helpcenter/zh/dev/ios/swiftui/interstitial.md)
- [激励广告](https://ads.yandex.com/helpcenter/zh/dev/ios/swiftui/rewarded.md)
- [开屏广告](https://ads.yandex.com/helpcenter/zh/dev/ios/swiftui/app-open-ad.md)

## AI 辅助迁移 (beta) {#ai}

为了简化从 SDK 7.x 到 8.x 的迁移，您可以使用具有预配置迁移技能的 AI 助手。

### 工作原理

1. **下载技能**

    迁移技能可在 [GitHub Yandex Ads SDK iOS](https://github.com/yandexmobile/yandex-ads-sdk-ios/tree/master/Skills/migrate-yandex-ads-sdk-from-7-to-8) 中获取。

    - 对于 Claude Desktop

        将技能文件夹复制到代理的技能目录中，例如：

        ```bash
        cp -r Skills/migrate-yandex-ads-sdk-from-7-to-8 .claude/skills/
        ```

    - 对于 Cursor IDE

        将技能文件夹复制到您的项目中，并使用 `@` 引用 `SKILL.md` 文件，例如：

        ```
        @migrate-yandex-ads-sdk-from-7-to-8/SKILL.md
        ```

    - 另一种方法
    
        将 `SKILL.md` 和所有相关文件的内容复制到与 AI 助手的聊天中。 请注意，这可能会超出消息限制。

2. **使用提示**

    技能加载完成后，在与 AI 助手的聊天中使用以下提示：

    ```
    将我的项目从 Yandex Mobile Ads SDK 7.x 迁移至 8.x
    ```

{% note warning %}

始终仔细审查 AI 生成的更改。

技能有助于 AI 助手更高效地处理任务，但您仍需审查代理做出的所有更改。 AI 助手可能会出错，因此您需要手动审查代码。

{% endnote %}

## SKAdNetwork

SKAdNetwork ID 列表已更新，并新增了用于自动更新的工具。 关于实施方法和使用场景的更多信息，请参阅 [SKAdNetwork](https://ads.yandex.com/helpcenter/zh/dev/ios/skadnetwork.md)。

## 要求

- **Xcode**：16.4 或更高版本
- **AppMetricaCore**：6.0.0 或更高版本
- **AppMetricaLibraryAdapter**：6.0.0 或更高版本
- **AppMetricaAdSupport**：6.0.0 或更高版本
- **AppMetricaIDSync**：6.0.0 或更高版本


