> For the complete documentation index, see [llms.txt](https://adpopcornssp.gitbook.io/ssp-sdk/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://adpopcornssp.gitbook.io/ssp-sdk/sdk/ios/ios-3.1.0+/_.md).

# 마이그레이션\_가이드

기존 ObjC SDK(`AdPopcornSSP`)에서 Swift SDK(`APSSPSDK`)로 전환하기 위한 가이드입니다.

***

## 마이그레이션 체크리스트

* [ ] `pod 'AdPopcornSSP'` → `pod 'APSSPSDK'` + 미디에이션 adapter Pod 추가
* [ ] `use_frameworks! :linkage => :static` 추가
* [ ] `#import <AdPopcornSSP/...>` → `@import APSSPSDK;`
* [ ] 초기화 코드 변경 (`APSSPInitializationSettings` + `APSSPAds.initializeSDK`)
* [ ] 광고 클래스명 변경 (`AdPopcornSSP...` → `APSSP...`)
* [ ] 생성자 파라미터명 변경 (`Key:` → `AppKey:`, `viewController:` → `rootViewController:`)
* [ ] 로드 메서드 변경 (`loadRequest` → `load` 또는 `loadAd`)
* [ ] 노출 메서드 변경 (`presentFromViewController:` → `presentFrom:`)
* [ ] Delegate 프로토콜명 변경
* [ ] Delegate 메서드명 변경 (대문자 시작 → 소문자 시작, `With` 파라미터 추가)
* [ ] 에러 타입 변경 (`AdPopcornSSPError *` → `APSSPNetworkError` enum)
* [ ] 배너 사이즈 enum 변경
* [ ] 네이티브 Renderer 바인딩 메서드 변경
* [ ] 하이브리드 브릿지 JS handler 이름 변경 (해당 시)
* [ ] 수동 adapter 파일 제거 (Pod으로 대체)
* [ ] 빌드 & 테스트

## 개요

| 항목            | 기존 (ObjC SDK)                           | 신규 (Swift SDK)                                         |
| ------------- | --------------------------------------- | ------------------------------------------------------ |
| Pod 이름        | `AdPopcornSSP`                          | `APSSPSDK`                                             |
| import        | `#import <AdPopcornSSP/AdPopcornSSP.h>` | `@import APSSPSDK;` (ObjC) / `import APSSPSDK` (Swift) |
| 최소 지원         | iOS 12.0                                | iOS 13.0                                               |
| 언어            | Objective-C                             | Swift (ObjC 호환)                                        |
| 미디에이션 Adapter | 별도 수동 설치                                | CocoaPods / SPM 자동 설치                                  |

***

## 1. SDK 설치 변경

### 기존 (ObjC)

```ruby
pod 'AdPopcornSSP'
```

### 신규 (Swift)

```ruby
use_frameworks! :linkage => :static

pod 'APSSPSDK', '3.1.0'
pod 'APSSPMediationAdMob'       # 사용할 업체만 추가
pod 'APSSPMediationVungle'
# ...
```

{% hint style="warning" %}
`use_frameworks! :linkage => :static` 필수 추가
{% endhint %}

***

## 2. import 변경

| 기존                                                    | 신규                       |
| ----------------------------------------------------- | ------------------------ |
| `#import <AdPopcornSSP/AdPopcornSSP.h>`               | `@import APSSPSDK;`      |
| `#import <AdPopcornSSP/AdPopcornSSPBannerView.h>`     | `@import APSSPSDK;` (통합) |
| `#import <AdPopcornSSP/AdPopcornSSPInterstitialAd.h>` | `@import APSSPSDK;` (통합) |

Swift SDK는 모든 public API가 하나의 모듈(`APSSPSDK`)에 포함되어 있으므로 `@import APSSPSDK;` 하나로 충분합니다.

***

## 3. 초기화 변경

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
#import <AdPopcornSSP/AdPopcornSSP.h>

[AdPopcornSSP initializeSDK:@"YOUR_APP_KEY"];
[AdPopcornSSP setLogLevel:AdPopcornSSPLogAll];
[AdPopcornSSP setUserId:@"TEST_USN"];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
@import APSSPSDK;

APSSPInitializationSettings *settings = [[APSSPInitializationSettings alloc] initWithAppKey:@"YOUR_APP_KEY"];
settings.logType = APSSPLogTypeAll;

[APSSPAds initializeSDKWith:settings completion:^{
    // 초기화 완료
}];

[APSSPAds setUSerIDWithUsn:@"TEST_USN"];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
import APSSPSDK

let settings = APSSPInitializationSettings(appKey: "YOUR_APP_KEY")
settings.logType = .all

APSSPAds.initializeSDK(with: settings) {
    // 초기화 완료
}

APSSPAds.setUSerID(usn: "TEST_USN")
```

{% endtab %}
{% endtabs %}

**주요 차이:**

* `AdPopcornSSP` 클래스 → `APSSPAds` 클래스
* 개별 설정 메서드 → `APSSPInitializationSettings` 객체로 통합
* 초기화 완료 콜백 추가 (미디에이션 SDK 자동 초기화 포함)

### 추가 설정 (COPPA, UID 2.0, 유저 식별값 등)

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
[AdPopcornSSP setUserId:@"TEST_USN"];
[AdPopcornSSP tagForChildDirectedTreatment:YES];
[AdPopcornSSP setUIDIdentifier:0 identifier:@"test@adpopcorn.com"];
[AdPopcornSSP gdprConsentAvailable:YES];
[AdPopcornSSP setAdInspectorEnabled:YES];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
// 유저 식별값 (리워드 비디오/비디오 믹스 시청 완료 시 유저 식별용)
[APSSPAds setUSerIDWithUsn:@"TEST_USN"];

// COPPA (아동 대상 앱인 경우 YES)
[APSSPAds tagForChildDirectedTreatment:YES];

// UID 2.0 (쿠팡 DSP 고단가 광고 수신용, 선택)
// identityType: 0 = Email, 1 = PhoneNumber
[APSSPAds setUIDIdentifierWithIdentityType:0 identifier:@"test@adpopcorn.com"];

// GDPR (3.1.1에서 추가 예정)
// [APSSPAds gdprConsentAvailable:YES];

// Ad Inspector (개발/QA 단계에서만 사용, 릴리즈 시 비활성화)
[APSSPAds setAdInspectorEnabled:YES];

// 사용자 정보 (선택)
[APSSPAds setAge:25];
[APSSPAds setGender:APSSPGenderMale];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
// 유저 식별값 (리워드 비디오/비디오 믹스 시청 완료 시 유저 식별용)
APSSPAds.setUSerID(usn: "TEST_USN")

// COPPA (아동 대상 앱인 경우 true)
APSSPAds.tagForChildDirectedTreatment(true)

// UID 2.0 (쿠팡 DSP 고단가 광고 수신용, 선택)
// identityType: 0 = Email, 1 = PhoneNumber
APSSPAds.setUIDIdentifier(identityType: 0, identifier: "test@adpopcorn.com")

// GDPR (3.1.1에서 추가 예정)
// APSSPAds.gdprConsentAvailable(true)

// Ad Inspector (개발/QA 단계에서만 사용, 릴리즈 시 비활성화)
APSSPAds.setAdInspectorEnabled(true)

// 사용자 정보 (선택)
APSSPAds.setAge(25)
APSSPAds.setGender(.male)
```

{% endtab %}
{% endtabs %}

***

## 4. 클래스명 변경

| 기존 (ObjC SDK)                        | 신규 (Swift SDK)                |
| ------------------------------------ | ----------------------------- |
| `AdPopcornSSP`                       | `APSSPAds`                    |
| `AdPopcornSSPBannerView`             | `APSSPBannerView`             |
| `AdPopcornSSPInterstitialAd`         | `APSSPInterstitialAd`         |
| `AdPopcornSSPInterstitialVideoAd`    | `APSSPInterstitialVideoAd`    |
| `AdPopcornSSPRewardVideoAd`          | `APSSPRewardVideoAd`          |
| `AdPopcornSSPVideoMixAd`             | `APSSPVideoMixAd`             |
| `AdPopcornSSPNativeAd`               | `APSSPNativeAd`               |
| `AdPopcornSSPReactNativeAd`          | `APSSPReactNativeAd`          |
| `AdPopcornSSPModalAd`                | `APSSPModalAd`                |
| `AdPopcornSSPSplashAd`               | `APSSPSplashAd`               |
| `AdPopcornSSPContentsAd`             | `APSSPContentsAd`             |
| `AdPopcornSSPPopContentsAd`          | `APSSPPopContentsAd`          |
| `AdPopcornSSPRewardAdPlus`           | `APSSPRewardAdPlus`           |
| `AdPopcornSSPError`                  | `APSSPNetworkError` (enum)    |
| `AdPopcornSSPWKScriptMessageHandler` | `APSSPWKScriptMessageHandler` |

***

## 5. 광고 포맷별 API 변경

### 5-1. 배너 광고

| 항목       | 기존                                                   | 신규                                       |
| -------- | ---------------------------------------------------- | ---------------------------------------- |
| 생성       | `initWithFrame:Key:placementId:size:viewController:` | `initWithAppKey:placementId:bannerSize:` |
| 로드       | `loadRequest`                                        | `loadAd`                                 |
| 중단       | `stopAd`                                             | `stopAd`                                 |
| 사이즈      | `SSPBannerSize320x50` (int)                          | `APSSPBannerSizeBanner320x50` (enum)     |
| delegate | `AdPopcornSSPBannerViewDelegate`                     | `APSSPBannerViewDelegate`                |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
#import <AdPopcornSSP/AdPopcornSSPBannerView.h>

AdPopcornSSPBannerView *banner = [[AdPopcornSSPBannerView alloc] initWithFrame:frame
                                                                           Key:@"APP_KEY"
                                                                   placementId:@"PLACEMENT_ID"
                                                                          size:SSPBannerSize320x50
                                                                viewController:self];
banner.delegate = self;
[banner loadRequest];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
@import APSSPSDK;

APSSPBannerView *banner = [[APSSPBannerView alloc] initWithAppKey:@"APP_KEY"
                                                      placementId:@"PLACEMENT_ID"
                                                       bannerSize:APSSPBannerSizeBanner320x50];
banner.delegate = self;
banner.rootViewController = self;
[self.view addSubview:banner];
[banner loadAd];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
import APSSPSDK

let banner = APSSPBannerView(appKey: "APP_KEY", placementId: "PLACEMENT_ID", bannerSize: .banner320x50)
banner.delegate = self
banner.rootViewController = self
view.addSubview(banner)
banner.loadAd()
```

{% endtab %}
{% endtabs %}

### 5-2. 전면 광고

| 항목       | 기존                                        | 신규                                               |
| -------- | ----------------------------------------- | ------------------------------------------------ |
| 생성       | `initWithKey:placementId:viewController:` | `initWithAppKey:placementId:rootViewController:` |
| 로드       | `loadRequest`                             | `load`                                           |
| 노출       | `presentFromViewController:`              | `presentFrom:`                                   |
| delegate | `AdPopcornSSPInterstitialAdDelegate`      | `APSSPInterstitialAdDelegate`                    |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
#import <AdPopcornSSP/AdPopcornSSPInterstitialAd.h>

AdPopcornSSPInterstitialAd *ad = [[AdPopcornSSPInterstitialAd alloc] initWithKey:@"APP_KEY"
                                                                     placementId:@"PLACEMENT_ID"
                                                                  viewController:self];
ad.delegate = self;
[ad loadRequest];
// 로드 성공 후
[ad presentFromViewController:self];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
@import APSSPSDK;

APSSPInterstitialAd *ad = [[APSSPInterstitialAd alloc] initWithAppKey:@"APP_KEY"
                                                          placementId:@"PLACEMENT_ID"
                                                   rootViewController:self];
ad.delegate = self;
[ad load];
// 로드 성공 후
[ad presentFrom:self];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
import APSSPSDK

let ad = APSSPInterstitialAd(appKey: "APP_KEY", placementId: "PLACEMENT_ID", rootViewController: self)
ad.delegate = self
ad.load()
// 로드 성공 후
ad.present(from: self)
```

{% endtab %}
{% endtabs %}

### 5-3. 전면 비디오 광고

| 항목       | 기존                                        | 신규                                               |
| -------- | ----------------------------------------- | ------------------------------------------------ |
| 생성       | `initWithKey:placementId:viewController:` | `initWithAppKey:placementId:rootViewController:` |
| 로드       | `loadRequest`                             | `load`                                           |
| 노출       | `presentFromViewController:`              | `presentFrom:`                                   |
| 중단       | `stopAd`                                  | `stopAd`                                         |
| delegate | `AdPopcornSSPInterstitialVideoAdDelegate` | `APSSPInterstitialVideoAdDelegate`               |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
#import <AdPopcornSSP/AdPopcornSSPInterstitialVideoAd.h>

AdPopcornSSPInterstitialVideoAd *iv = [[AdPopcornSSPInterstitialVideoAd alloc] initWithKey:@"APP_KEY"
                                                                               placementId:@"PLACEMENT_ID"
                                                                            viewController:self];
iv.delegate = self;
[iv loadRequest];
// 로드 성공 후
[iv presentFromViewController:self];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
@import APSSPSDK;

APSSPInterstitialVideoAd *iv = [[APSSPInterstitialVideoAd alloc] initWithAppKey:@"APP_KEY"
                                                                    placementId:@"PLACEMENT_ID"
                                                             rootViewController:self];
iv.delegate = self;
[iv load];
// 로드 성공 후
[iv presentFrom:self];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
import APSSPSDK

let iv = APSSPInterstitialVideoAd(appKey: "APP_KEY", placementId: "PLACEMENT_ID", rootViewController: self)
iv.delegate = self
iv.load()
// 로드 성공 후
iv.present(from: self)
```

{% endtab %}
{% endtabs %}

### 5-4. 리워드 비디오 광고

| 항목       | 기존                                        | 신규                                               |
| -------- | ----------------------------------------- | ------------------------------------------------ |
| 생성       | `initWithKey:placementId:viewController:` | `initWithAppKey:placementId:rootViewController:` |
| 로드       | `loadRequest`                             | `load`                                           |
| 노출       | `presentFromViewController:`              | `presentFrom:`                                   |
| 중단       | `stopAd`                                  | `stopAd`                                         |
| delegate | `AdPopcornSSPRewardVideoAdDelegate`       | `APSSPRewardVideoAdDelegate`                     |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
#import <AdPopcornSSP/AdPopcornSSPRewardVideoAd.h>

[AdPopcornSSP setUserId:@"TEST_USN"];  // 유저 식별값 설정 (load 전 필수)

AdPopcornSSPRewardVideoAd *rv = [[AdPopcornSSPRewardVideoAd alloc] initWithKey:@"APP_KEY"
                                                                   placementId:@"PLACEMENT_ID"
                                                                viewController:self];
rv.delegate = self;
[rv loadRequest];
// 로드 성공 후
[rv presentFromViewController:self];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
@import APSSPSDK;

[APSSPAds setUSerIDWithUsn:@"TEST_USN"];  // 유저 식별값 설정 (load 전 필수)

APSSPRewardVideoAd *rv = [[APSSPRewardVideoAd alloc] initWithAppKey:@"APP_KEY"
                                                         placementId:@"PLACEMENT_ID"
                                                  rootViewController:self];
rv.delegate = self;
[rv load];
// 로드 성공 후
[rv presentFrom:self];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
import APSSPSDK

APSSPAds.setUSerID(usn: "TEST_USN")  // 유저 식별값 설정 (load 전 필수)

let rv = APSSPRewardVideoAd(appKey: "APP_KEY", placementId: "PLACEMENT_ID", rootViewController: self)
rv.delegate = self
rv.load()
// 로드 성공 후
rv.present(from: self)
```

{% endtab %}
{% endtabs %}

### 5-5. 비디오 믹스 광고

| 항목       | 기존                                        | 신규                                               |
| -------- | ----------------------------------------- | ------------------------------------------------ |
| 생성       | `initWithKey:placementId:viewController:` | `initWithAppKey:placementId:rootViewController:` |
| 로드       | `loadRequest`                             | `load`                                           |
| 노출       | `presentFromViewController:`              | `presentFrom:`                                   |
| 중단       | `stopAd`                                  | `stopAd`                                         |
| delegate | `AdPopcornSSPVideoMixAdDelegate`          | `APSSPVideoMixAdDelegate`                        |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
#import <AdPopcornSSP/AdPopcornSSPVideoMixAd.h>

[AdPopcornSSP setUserId:@"TEST_USN"];  // 유저 식별값 설정 (load 전 필수)

AdPopcornSSPVideoMixAd *vm = [[AdPopcornSSPVideoMixAd alloc] initWithKey:@"APP_KEY"
                                                             placementId:@"PLACEMENT_ID"
                                                          viewController:self];
vm.delegate = self;
[vm loadRequest];
// 로드 성공 후
[vm presentFromViewController:self];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
@import APSSPSDK;

[APSSPAds setUSerIDWithUsn:@"TEST_USN"];  // 유저 식별값 설정 (load 전 필수)

APSSPVideoMixAd *vm = [[APSSPVideoMixAd alloc] initWithAppKey:@"APP_KEY"
                                                  placementId:@"PLACEMENT_ID"
                                           rootViewController:self];
vm.delegate = self;
[vm load];
// 로드 성공 후
[vm presentFrom:self];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
import APSSPSDK

APSSPAds.setUSerID(usn: "TEST_USN")  // 유저 식별값 설정 (load 전 필수)

let vm = APSSPVideoMixAd(appKey: "APP_KEY", placementId: "PLACEMENT_ID", rootViewController: self)
vm.delegate = self
vm.load()
// 로드 성공 후
vm.present(from: self)
```

{% endtab %}
{% endtabs %}

### 5-6. 네이티브 광고

| 항목             | 기존                                              | 신규                                               |
| -------------- | ----------------------------------------------- | ------------------------------------------------ |
| 생성             | `initWithFrame:Key:placementId:viewController:` | `initWithAppKey:placementId:rootViewController:` |
| 로드             | `loadRequest`                                   | `load`                                           |
| 중단             | `stopAd`                                        | `stop`                                           |
| Renderer 설정    | `setApSSPRenderer:superView:`                   | `bindAdPopcornRenderer(adPopcornRender:)`        |
| AdMob Renderer | `setAdMobRenderer:superView:`                   | `bindAdMobRenderer(renderer:)`                   |
| NAM Renderer   | `setNAMRenderer:superView:`                     | `bindNamRenderer(renderer:)`                     |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
#import <AdPopcornSSP/AdPopcornSSPNativeAd.h>

AdPopcornSSPNativeAd *nativeAd = [[AdPopcornSSPNativeAd alloc] initWithFrame:frame
                                                                         Key:@"APP_KEY"
                                                                 placementId:@"PLACEMENT_ID"
                                                              viewController:self];
nativeAd.delegate = self;

APSSPNativeAdRenderer *renderer = [[APSSPNativeAdRenderer alloc] init];
renderer.titleLabel = _titleLabel;
renderer.descLabel = _descLabel;
renderer.mainImageView = _mainImageView;
[nativeAd setApSSPRenderer:renderer superView:_nativeAdView];

[nativeAd loadRequest];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
@import APSSPSDK;

APSSPNativeAd *nativeAd = [[APSSPNativeAd alloc] initWithAppKey:@"APP_KEY"
                                                    placementId:@"PLACEMENT_ID"
                                             rootViewController:nil];
nativeAd.delegate = self;
[self.view addSubview:nativeAd];

APSSPNativeAdRenderer *renderer = [[APSSPNativeAdRenderer alloc] init];
renderer.titleLabel = _titleLabel;
renderer.descLabel = _descLabel;
renderer.mainImageView = _mainImageView;
[nativeAd bindAdPopcornRendererWithAdPopcornRender:renderer];

[nativeAd load];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
import APSSPSDK

let nativeAd = APSSPNativeAd(appKey: "APP_KEY", placementId: "PLACEMENT_ID")
nativeAd.delegate = self
view.addSubview(nativeAd)

let renderer = APSSPNativeAdRenderer()
renderer.titleLabel = titleLabel
renderer.descLabel = descLabel
renderer.mainImageView = mainImageView
nativeAd.bindAdPopcornRenderer(adPopcornRender: renderer)

nativeAd.load()
```

{% endtab %}
{% endtabs %}

#### 네이티브 미디에이션 Renderer 설정

네이티브 광고에서 미디에이션을 사용하는 경우, 각 업체별 Renderer를 설정해야 합니다.

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
// AdMob
GADNativeAdView *admobView = [[NSBundle mainBundle] loadNibNamed:@"GADNativeAdView" owner:nil options:nil].firstObject;
APAdMobNativeAdRenderer *admobRenderer = [[APAdMobNativeAdRenderer alloc] init];
admobRenderer.gadNativeAdView = admobView;
[nativeAd setAdMobRenderer:admobRenderer superView:_nativeAdView];

// NAM
GFPNativeAdView *namView = [[NSBundle mainBundle] loadNibNamed:@"GFPNativeAdView" owner:nil options:nil].firstObject;
APNAMNativeAdRenderer *namRenderer = [[APNAMNativeAdRenderer alloc] init];
namRenderer.gfpNativeAdView = namView;
[nativeAd setNAMRenderer:namRenderer superView:_nativeAdView];

// AdFit
APAdFitNativeAdRenderer *adfitRenderer = [[APAdFitNativeAdRenderer alloc] init];
[nativeAd setAdFitRenderer:adfitRenderer superView:_nativeAdView];

// AppLovin MAX
MANativeAdView *maxView = [[NSBundle mainBundle] loadNibNamed:@"NativeManualAdView" owner:nil options:nil].firstObject;
APAppLovinMaxNativeAdRenderer *maxRenderer = [[APAppLovinMaxNativeAdRenderer alloc] init];
maxRenderer.maNativeAdView = maxView;
[nativeAd setAppLovinMaxRenderer:maxRenderer superView:_nativeAdView];

// Vungle
APVungleNativeAdRenderer *vungleRenderer = [[APVungleNativeAdRenderer alloc] init];
[nativeAd setVungleRenderer:vungleRenderer superView:_nativeAdView];

// FAN
APFANNativeAdRenderer *fanRenderer = [[APFANNativeAdRenderer alloc] init];
[nativeAd setFANNativeRenderer:fanRenderer superView:_nativeAdView];

// Mintegral
APMintegralNativeAdRenderer *mintegralRenderer = [[APMintegralNativeAdRenderer alloc] init];
[nativeAd setMintegralNativeRenderer:mintegralRenderer superView:_nativeAdView];

// InMobi
APInMobiNativeAdRenderer *inMobiRenderer = [[APInMobiNativeAdRenderer alloc] init];
[nativeAd setInMobiRenderer:inMobiRenderer superView:_nativeAdView];

// Fyber
APFyberAdapterNativeAdRenderer *fyberRenderer = [[APFyberAdapterNativeAdRenderer alloc] init];
[nativeAd setFyberRenderer:fyberRenderer superView:_nativeAdView];

// ADOP
APADOPNativeAdRenderer *adopRenderer = [[APADOPNativeAdRenderer alloc] init];
adopRenderer.gadNativeAdView = adopView;
[nativeAd setADOPRenderer:adopRenderer superView:_nativeAdView];

// GAM
APGAMNativeAdRenderer *gamRenderer = [[APGAMNativeAdRenderer alloc] init];
gamRenderer.gadNativeAdView = gamView;
[nativeAd setGAMRenderer:gamRenderer superView:_nativeAdView];

// AdForus
APAdforusNativeAdRenderer *adforusRenderer = [[APAdforusNativeAdRenderer alloc] init];
adforusRenderer.gadNativeAdView = adforusView;
[nativeAd setAdForusRenderer:adforusRenderer superView:_nativeAdView];
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
// AdMob
GADNativeAdView *admobView = [[NSBundle mainBundle] loadNibNamed:@"GADNativeAdView" owner:nil options:nil].firstObject;
APAdMobNativeAdRenderer *admobRenderer = [[APAdMobNativeAdRenderer alloc] init];
admobRenderer.gadNativeAdView = admobView;
[nativeAd bindAdMobRendererWithRenderer:admobRenderer];

// NAM
GFPNativeAdView *namView = [[NSBundle mainBundle] loadNibNamed:@"GFPNativeAdView" owner:nil options:nil].firstObject;
APNAMNativeAdRenderer *namRenderer = [[APNAMNativeAdRenderer alloc] init];
namRenderer.gfpNativeAdView = namView;
[nativeAd bindNamRendererWithRenderer:namRenderer];

// AdFit
APAdFitNativeAdRenderer *adfitRenderer = [[APAdFitNativeAdRenderer alloc] init];
[nativeAd bindAdfitRendererWithRenderer:adfitRenderer];

// AppLovin MAX
MANativeAdView *maxView = [[NSBundle mainBundle] loadNibNamed:@"NativeManualAdView" owner:nil options:nil].firstObject;
APAppLovinMaxNativeAdRenderer *maxRenderer = [[APAppLovinMaxNativeAdRenderer alloc] init];
maxRenderer.maNativeAdView = maxView;
[nativeAd bindApplovinMaxRendererWithRenderer:maxRenderer];

// Vungle
APVungleNativeAdRenderer *vungleRenderer = [[APVungleNativeAdRenderer alloc] init];
[nativeAd bindVungleRendererWithRenderer:vungleRenderer];

// FAN
APFANNativeAdRenderer *fanRenderer = [[APFANNativeAdRenderer alloc] init];
[nativeAd bindFBANNativeRendererWithRenderer:fanRenderer];

// Mintegral
APMintegralNativeAdRenderer *mintegralRenderer = [[APMintegralNativeAdRenderer alloc] init];
[nativeAd bindMintegralRendererWithRenderer:mintegralRenderer];

// InMobi
APInMobiNativeAdRenderer *inMobiRenderer = [[APInMobiNativeAdRenderer alloc] init];
[nativeAd bindInMobiRendererWithRenderer:inMobiRenderer];

// Fyber
APFyberAdapterNativeAdRenderer *fyberRenderer = [[APFyberAdapterNativeAdRenderer alloc] init];
[nativeAd bindFyberRendererWithRenderer:fyberRenderer];

// ADOP
APADOPNativeAdRenderer *adopRenderer = [[APADOPNativeAdRenderer alloc] init];
adopRenderer.gadNativeAdView = adopView;
[nativeAd bindAdopRendererWithRenderer:adopRenderer];

// GAM
APGAMNativeAdRenderer *gamRenderer = [[APGAMNativeAdRenderer alloc] init];
gamRenderer.gadNativeAdView = gamView;
[nativeAd bindGamRendererWithRenderer:gamRenderer];

// AdForus
APAdforusNativeAdRenderer *adforusRenderer = [[APAdforusNativeAdRenderer alloc] init];
adforusRenderer.gadNativeAdView = adforusView;
[nativeAd bindAdForusRendererWithRenderer:adforusRenderer];
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
// AdMob
let admobView = Bundle.main.loadNibNamed("GADNativeAdView", owner: nil)?.first as! GADNativeAdView
let admobRenderer = APAdMobNativeAdRenderer()
admobRenderer.gadNativeAdView = admobView
nativeAd.bindAdMobRenderer(renderer: admobRenderer)

// NAM
let namView = Bundle.main.loadNibNamed("GFPNativeAdView", owner: nil)?.first as! GFPNativeAdView
let namRenderer = APNAMNativeAdRenderer()
namRenderer.gfpNativeAdView = namView
nativeAd.bindNamRenderer(renderer: namRenderer)

// AdFit
let adfitRenderer = APAdFitNativeAdRenderer()
nativeAd.bindAdfitRenderer(renderer: adfitRenderer)

// AppLovin MAX
let maxView = Bundle.main.loadNibNamed("NativeManualAdView", owner: nil)?.first as! MANativeAdView
let maxRenderer = APAppLovinMaxNativeAdRenderer()
maxRenderer.maNativeAdView = maxView
nativeAd.bindApplovinMaxRenderer(renderer: maxRenderer)

// Vungle
let vungleRenderer = APVungleNativeAdRenderer()
nativeAd.bindVungleRenderer(renderer: vungleRenderer)

// FAN
let fanRenderer = APFANNativeAdRenderer()
nativeAd.bindFBANNativeRenderer(renderer: fanRenderer)

// Mintegral
let mintegralRenderer = APMintegralNativeAdRenderer()
nativeAd.bindMintegralRenderer(renderer: mintegralRenderer)

// InMobi
let inMobiRenderer = APInMobiNativeAdRenderer()
nativeAd.bindInMobiRenderer(renderer: inMobiRenderer)

// Fyber
let fyberRenderer = APFyberAdapterNativeAdRenderer()
nativeAd.bindFyberRenderer(renderer: fyberRenderer)

// ADOP
let adopRenderer = APADOPNativeAdRenderer()
adopRenderer.gadNativeAdView = adopView
nativeAd.bindAdopRenderer(renderer: adopRenderer)

// GAM
let gamRenderer = APGAMNativeAdRenderer()
gamRenderer.gadNativeAdView = gamView
nativeAd.bindGamRenderer(renderer: gamRenderer)

// AdForus
let adforusRenderer = APAdforusNativeAdRenderer()
adforusRenderer.gadNativeAdView = adforusView
nativeAd.bindAdForusRenderer(renderer: adforusRenderer)
```

{% endtab %}
{% endtabs %}

### 5-7. 모달 광고

| 항목 | 기존                                        | 신규                                           |
| -- | ----------------------------------------- | -------------------------------------------- |
| 생성 | `initWithKey:placementId:viewController:` | `initWithAppKey:placementId:viewController:` |
| 로드 | `loadRequest`                             | `loadRequest`                                |
| 노출 | `presentFromViewController:`              | `presentFrom:`                               |

### 5-8. 스플래시 광고

| 항목 | 기존                                              | 신규                                                 |
| -- | ----------------------------------------------- | -------------------------------------------------- |
| 생성 | `initWithFrame:Key:placementId:viewController:` | `initWithFrame:appKey:placementId:viewController:` |
| 로드 | `loadRequest`                                   | `loadRequest`                                      |
| 중단 | `stopAd`                                        | `stopAd`                                           |

### 5-9. 보상형 광고 플러스

| 항목 | 기존                                                                          | 신규                                                                             |
| -- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| 열기 | `[AdPopcornSSP openRewardPlusSettingViewController:appKey viewController:]` | `[APSSPRewardAdPlus openRewardAdPlusViewControllerWithAppKey:viewController:]` |

***

## 6. Delegate 메서드명 변경

> Swift SDK는 Swift 스타일 네이밍을 사용하므로, ObjC에서 호출 시 자동 변환된 이름을 사용합니다.

### 배너

| 기존                               | 신규 (ObjC에서 사용 시)                               |
| -------------------------------- | ---------------------------------------------- |
| `APSSPBannerViewLoadSuccess:`    | `apsspBannerViewLoadSuccessWithBannerView:`    |
| `APSSPBannerViewLoadFail:error:` | `apsspBannerViewLoadFailWithBannerView:error:` |
| `APSSPBannerViewClicked:`        | `apsspBannerViewClickedWithBannerView:`        |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
- (void)APSSPBannerViewLoadSuccess:(AdPopcornSSPBannerView *)bannerView {
}
- (void)APSSPBannerViewLoadFail:(AdPopcornSSPBannerView *)bannerView error:(AdPopcornSSPError *)error {
}
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
- (void)apsspBannerViewLoadSuccessWithBannerView:(APSSPBannerView *)bannerView {
}
- (void)apsspBannerViewLoadFailWithBannerView:(APSSPBannerView *)bannerView error:(enum APSSPNetworkError)error {
}
- (void)apsspBannerViewClickedWithBannerView:(APSSPBannerView *)bannerView {
}
- (void)apsspBannerViewImpressionWithBannerView:(APSSPBannerView *)bannerView {
}
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
func apsspBannerViewLoadSuccess(bannerView: APSSPBannerView) {
}
func apsspBannerViewLoadFail(bannerView: APSSPBannerView, error: APSSPNetworkError) {
}
func apsspBannerViewClicked(bannerView: APSSPBannerView) {
}
func apsspBannerViewImpression(bannerView: APSSPBannerView) {
}
```

{% endtab %}
{% endtabs %}

### 전면

| 기존                                   | 신규 (ObjC에서 사용 시)                                       |
| ------------------------------------ | ------------------------------------------------------ |
| `APSSPInterstitialAdLoadSuccess:`    | `apsspInterstitialAdLoadSuccessWithInterstitialAd:`    |
| `APSSPInterstitialAdLoadFail:error:` | `apsspInterstitialAdLoadFailWithInterstitialAd:error:` |
| `APSSPInterstitialAdShowSuccess:`    | `apsspInterstitialAdShowSuccessWithInterstitialAd:`    |
| `APSSPInterstitialAdShowFail:`       | `apsspInterstitialAdShowFailWithInterstitialAd:error:` |
| `APSSPInterstitialAdClicked:`        | `apsspInterstitialAdClickedWithInterstitialAd:`        |
| `APSSPInterstitialAdClosed:`         | `apsspInterstitialAdClosedWithInterstitialAd:`         |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
- (void)APSSPInterstitialAdLoadSuccess:(AdPopcornSSPInterstitialAd *)interstitialAd {
    [interstitialAd presentFromViewController:self];
}
- (void)APSSPInterstitialAdLoadFail:(AdPopcornSSPInterstitialAd *)interstitialAd error:(AdPopcornSSPError *)error {
}
- (void)APSSPInterstitialAdClosed:(AdPopcornSSPInterstitialAd *)interstitialAd {
}
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
- (void)apsspInterstitialAdLoadSuccessWithInterstitialAd:(APSSPInterstitialAd *)interstitialAd {
    [interstitialAd presentFrom:self];
}
- (void)apsspInterstitialAdLoadFailWithInterstitialAd:(APSSPInterstitialAd *)interstitialAd error:(enum APSSPNetworkError)error {
}
- (void)apsspInterstitialAdClosedWithInterstitialAd:(APSSPInterstitialAd *)interstitialAd {
}
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
func apsspInterstitialAdLoadSuccess(interstitialAd: APSSPInterstitialAd) {
    interstitialAd.present(from: self)
}
func apsspInterstitialAdLoadFail(interstitialAd: APSSPInterstitialAd, error: APSSPNetworkError) {
}
func apsspInterstitialAdClosed(interstitialAd: APSSPInterstitialAd) {
}
```

{% endtab %}
{% endtabs %}

### 리워드 비디오

| 기존                                                       | 신규 (ObjC에서 사용 시)                                                          |
| -------------------------------------------------------- | ------------------------------------------------------------------------- |
| `APSSPRewardVideoAdLoadSuccess:`                         | `apsspRewardVideoAdLoadSuccessWithRewardVideoAd:`                         |
| `APSSPRewardVideoAdLoadFail:error:`                      | `apsspRewardVideoAdLoadFailWithRewardVideoAd:error:`                      |
| `APSSPRewardVideoAdShowSuccess:`                         | `apsspRewardVideoAdShowSuccessWithRewardVideoAd:`                         |
| `APSSPRewardVideoAdShowFail:`                            | `apsspRewardVideoAdShowFailWithRewardVideoAd:error:`                      |
| `APSSPRewardVideoAdClosed:`                              | `apsspRewardVideoAdClosedWithRewardVideoAd:`                              |
| `APSSPRewardVideoAdPlayCompleted:adNetworkNo:completed:` | `apsspRewardVideoAdPlayCompletedWithRewardVideoAd:adNetworkNo:completed:` |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
- (void)APSSPRewardVideoAdLoadSuccess:(AdPopcornSSPRewardVideoAd *)rewardVideoAd {
    [rewardVideoAd presentFromViewController:self];
}
- (void)APSSPRewardVideoAdPlayCompleted:(AdPopcornSSPRewardVideoAd *)rewardVideoAd adNetworkNo:(long)adNetworkNo completed:(BOOL)completed {
}
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
- (void)apsspRewardVideoAdLoadSuccessWithRewardVideoAd:(APSSPRewardVideoAd *)rewardVideoAd {
    [rewardVideoAd presentFrom:self];
}
- (void)apsspRewardVideoAdPlayCompletedWithRewardVideoAd:(APSSPRewardVideoAd *)rewardVideoAd adNetworkNo:(NSInteger)adNetworkNo completed:(BOOL)completed {
}
```

{% endtab %}

{% tab title="신규 — Swift" %}

```swift
func apsspRewardVideoAdLoadSuccess(rewardVideoAd: APSSPRewardVideoAd) {
    rewardVideoAd.present(from: self)
}
func apsspRewardVideoAdPlayCompleted(rewardVideoAd: APSSPRewardVideoAd, adNetworkNo: Int, completed: Bool) {
}
```

{% endtab %}
{% endtabs %}

### 비디오 믹스

| 기존                                                    | 신규 (ObjC에서 사용 시)                                                    |
| ----------------------------------------------------- | ------------------------------------------------------------------- |
| `APSSPVideoMixAdLoadSuccess:videoMixAdType:`          | `apsspVideoMixAdLoadSuccessWithVideoMixAd:videoMixAdType:`          |
| `APSSPVideoMixAdLoadFail:error:`                      | `apsspVideoMixAdLoadFailWithVideoMixAd:error:`                      |
| `APSSPVideoMixAdClosed:videoMixAdType:`               | `apsspVideoMixAdClosedWithVideoMixAd:videoMixAdType:`               |
| `APSSPVideoMixAdPlayCompleted:adNetworkNo:completed:` | `apsspVideoMixAdPlayCompletedWithVideoMixAd:adNetworkNo:completed:` |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
- (void)APSSPVideoMixAdLoadSuccess:(AdPopcornSSPVideoMixAd *)videoMixAd videoMixAdType:(int)type {
    [videoMixAd presentFromViewController:self];
}
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
- (void)apsspVideoMixAdLoadSuccessWithVideoMixAd:(APSSPVideoMixAd *)videoMixAd videoMixAdType:(enum APSSPVideoMixAdType)videoMixAdType {
    [videoMixAd presentFrom:self];
}
```

{% endtab %}
{% endtabs %}

### 네이티브

| 기존                             | 신규 (ObjC에서 사용 시)                               |
| ------------------------------ | ---------------------------------------------- |
| `APSSPNativeAdLoadSuccess:`    | `apsspNativeAdLoadSuccessWithNativeAdView:`    |
| `APSSPNativeAdLoadFail:error:` | `apsspNativeAdLoadFailWithNativeAdView:error:` |
| `APSSPNativeAdImpression:`     | `apsspNativeAdImpressionWithNativeAd:`         |
| `APSSPNativeAdClicked:`        | `apsspNativeAdClickedWithNativeAd:`            |
| `APSSPNativeAdHidden:`         | `apsspNativeAdHiddenWithNativeAd:`             |

{% tabs %}
{% tab title="기존 (ObjC SDK)" %}

```objc
- (void)APSSPNativeAdLoadSuccess:(AdPopcornSSPNativeAd *)nativeAd {
}
- (void)APSSPNativeAdLoadFail:(AdPopcornSSPNativeAd *)nativeAd error:(AdPopcornSSPError *)error {
}
```

{% endtab %}

{% tab title="신규 — Objective-C" %}

```objc
- (void)apsspNativeAdLoadSuccessWithNativeAdView:(APSSPNativeAd *)nativeAdView {
}
- (void)apsspNativeAdLoadFailWithNativeAdView:(APSSPNativeAd *)nativeAdView error:(enum APSSPNetworkError)error {
}
```

{% endtab %}
{% endtabs %}

***

## 7. 설정 API 변경

| 기존                                                                     | 신규 (ObjC)                                                           | 신규 (Swift)                                                        |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `[AdPopcornSSP setUserId:@"USN"]`                                      | `[APSSPAds setUSerIDWithUsn:@"USN"]`                                | `APSSPAds.setUSerID(usn: "USN")`                                  |
| `[AdPopcornSSP setLogLevel:AdPopcornSSPLogAll]`                        | `settings.logType = APSSPLogTypeAll`                                | `settings.logType = .all`                                         |
| `[AdPopcornSSP tagForChildDirectedTreatment:YES]`                      | `[APSSPAds tagForChildDirectedTreatment:YES]`                       | `APSSPAds.tagForChildDirectedTreatment(true)`                     |
| `[AdPopcornSSP setUIDIdentifier:0 identifier:@"email"]`                | `[APSSPAds setUIDIdentifierWithIdentityType:0 identifier:@"email"]` | `APSSPAds.setUIDIdentifier(identityType: 0, identifier: "email")` |
| `[AdPopcornSSP gdprConsentAvailable:YES]`                              | (3.1.1에서 추가 예정)                                                     | (3.1.1에서 추가 예정)                                                   |
| `[AdPopcornSSP setAdInspectorEnabled:YES]`                             | `settings.adInspectorEnabled = YES`                                 | `settings.adInspectorEnabled = true`                              |
| `[AdPopcornSSP openCSViewController:self appKey:@"KEY" userId:@"USN"]` | `[APSSPAds presentCSViewController:self userID:@"USN"]`             | `APSSPAds.presentCSViewController(self, userID: "USN")`           |

***

## 8. Enum 변경

### 배너 사이즈

<table><thead><tr><th width="352.185791015625">기존</th><th>신규</th></tr></thead><tbody><tr><td><code>SSPBannerSize320x50</code> (int 0)</td><td><code>APSSPBannerSizeBanner320x50</code> (rawValue 1)</td></tr><tr><td><code>SSPBannerSize300x250</code> (int 1)</td><td><code>APSSPBannerSizeBanner300x250</code> (rawValue 2)</td></tr><tr><td><code>SSPBannerSize320x100</code> (int 2)</td><td><code>APSSPBannerSizeBanner320x100</code> (rawValue 3)</td></tr></tbody></table>

{% hint style="warning" %}
rawValue가 변경되었습니다. 숫자로 직접 지정하지 말고 enum 이름을 사용하세요.
{% endhint %}

### 에러 타입

<table><thead><tr><th width="353.4488525390625">기존</th><th>신규</th></tr></thead><tbody><tr><td><code>AdPopcornSSPError *error</code> (NSError 기반)</td><td><code>APSSPNetworkError</code> (enum, rawValue = 에러코드)</td></tr><tr><td><code>error.code</code></td><td><code>error</code> 자체가 에러코드 enum</td></tr></tbody></table>

### 로그 레벨

<table><thead><tr><th width="315.8662109375">기존</th><th>신규</th></tr></thead><tbody><tr><td><code>AdPopcornSSPLogAll</code></td><td><code>APSSPLogTypeAll</code></td></tr><tr><td><code>AdPopcornSSPLogNone</code></td><td><code>APSSPLogTypeNone</code></td></tr></tbody></table>

### VideoMix 타입

<table><thead><tr><th width="299.3385009765625">기존</th><th>신규</th></tr></thead><tbody><tr><td><code>int type</code> (2/4/6)</td><td><code>APSSPVideoMixAdType</code> enum</td></tr></tbody></table>

***

## 9. 미디에이션 Adapter 변경

### 기존 방식

* 수동으로 adapter `.m/.h` 파일을 프로젝트에 추가
* 각 업체 SDK를 별도로 Pod 설치
* `#import` 전환 (로컬 → framework) 필요

### 신규 방식

* `pod 'APSSPMediationAdMob'` 한 줄로 adapter + 3rd party SDK 자동 설치
* adapter 소스가 Pod에 포함되어 있어 별도 파일 추가 불필요
* `APSSPAdapterRegistry`가 설치된 adapter를 자동 탐색

### 네이티브 Renderer 변경

| 기존                                      | 신규                                   |
| --------------------------------------- | ------------------------------------ |
| `setAdMobRenderer:superView:`           | `bindAdMobRenderer(renderer:)`       |
| `setNAMRenderer:superView:`             | `bindNamRenderer(renderer:)`         |
| `setAdFitRenderer:superView:`           | `bindAdfitRenderer(renderer:)`       |
| `setAppLovinMaxRenderer:superView:`     | `bindApplovinMaxRenderer(renderer:)` |
| `setVungleRenderer:superView:`          | `bindVungleRenderer(renderer:)`      |
| `setFANNativeRenderer:superView:`       | `bindFBANNativeRenderer(renderer:)`  |
| `setMintegralNativeRenderer:superView:` | `bindMintegralRenderer(renderer:)`   |
| `setInMobiRenderer:superView:`          | `bindInMobiRenderer(renderer:)`      |
| `setFyberRenderer:superView:`           | `bindFyberRenderer(renderer:)`       |
| `setADOPRenderer:superView:`            | `bindAdopRenderer(renderer:)`        |
| `setGAMRenderer:superView:`             | `bindGamRenderer(renderer:)`         |
| `setAdForusRenderer:superView:`         | `bindAdForusRenderer(renderer:)`     |

> 신규 SDK에서는 `superView:` 파라미터가 제거되었습니다. APSSPNativeAd 자체가 UIView이므로 별도 superView 지정이 불필요합니다.

***

## 10. 삭제된 API

| 기존 API                               | 상태                            |
| ------------------------------------ | ----------------------------- |
| `setManualMediationSchedule:`        | 제거 (서버 스케줄만 사용)               |
| `getCurrentNetwork`                  | 제거                            |
| `isReady`                            | 제거 (delegate 콜백으로 대체)         |
| `getSDKVersion` / `getSDKVersionNum` | `APSSPAds.sdkVersion()` 으로 통합 |
| `frameworkName`                      | 제거                            |

***

## 11. 하이브리드 브릿지 변경

<table><thead><tr><th width="145.2542724609375">항목</th><th width="321.447021484375">기존</th><th>신규</th></tr></thead><tbody><tr><td>클래스</td><td><code>AdPopcornSSPWKScriptMessageHandler</code></td><td><code>APSSPWKScriptMessageHandler</code></td></tr></tbody></table>
