마이그레이션 v5 → v6
여기에서는 Buzzvil iOS SDK v5 에서 Buzzvil iOS SDK v6 으로 마이그레이션하기 위한 설정을 안내합니다.
GitHub 샘플 코드를 통해 실제 구현에 사용된 예제를 확인하세요.
✏️ 참고
이 가이드는 v5, v6 최신 기준으로 작성되었습니다.
❗️ 주의
Buzzvil SDK 6점대는 버즈빌 서버에서 Configuration 설정을 완료해야 정상 동작합니다. 따라서 하위 버전에서 마이그레이션 하실때 반드시 버즈빌 담당 매니저 혹은 팀 메일(partnership@buzzvil.com)로 문의 부탁드립니다.
✅ 중요
Buzzvil SDK 5점대부터는 계약 구조가 변경되었습니다. BuzzAd SDK 3점대 및 BuzzScreen SDK 4점대에서 Buzzvil SDK 6점대로 마이그레이션하는 경우, 계약서 갱신에 대해 반드시 버즈빌 담당 매니저 혹은 팀 메일(partnership@buzzvil.com)로 문의 부탁드립니다.
시작하기
요구 사항
- 아래와 같이 Buzzvil SDK v6 에서 변경된 요구 사양을 확인하고 프로젝트 설정에 반영하세요.
요구 사양
- deployment target
- 최소 지원: iOS 13 이상
- 권장 버전: iOS 14 이상
- Xcode 16.0 이상
연동용 ID 발급받기
Feed(베네핏허브)가 웹 베네핏허브로 변경되며 더 이상 Feed Unit ID를 연동 코드에서 직접 사용하지 않습니다.
App ID와 Native Unit ID, Interstitial Unit ID는 기존과 동일하게 사용하실 수 있습니다.
포인트 적립 서버 연동하기
럭키박스, 미션팩이 추가되므로 포스트백 연동 가이드의 안내에 따라 요청 파라미터 처리가 필요합니다.
SDK 설치하기
Swift Package Manager
Swift 패키지를 가져오려면 아래 단계를 따르세요.
✏️ 참고
CocoaPods 기반 프로젝트에서 이전하는 경우 pod deintegrate를 실행하여 Xcode 프로젝트에서 CocoaPods를 삭제합니다. CocoaPods에서 생성된 .xcworkspace 파일은 나중에 안전하게 삭제할 수 있습니다.
Xcode에서
File > Add Package Dependencies로 이동합니다.Buzzvil SDK Swift Package GitHub 저장소를 검색합니다.
https://github.com/Buzzvil/buzzvil-ios-sdk
사용할 버전을 선택합니다. Up to Next Minor Version(최대 다음 마이너 버전) 사용을 권장합니다.
패키지 프로덕트에서
BuzzvilSDK를 선택합니다.
✏️ 참고
버즈배너를 사용하지 않는 경우BuzzvilSDK-WithoutThirdParty를 선택할 수 있습니다. 이 경우 버즈배너 및 베네핏허브 내 전면 광고 기능이 제한됩니다.
패키지 종속 항목을 추가하는 방법에 관한 자세한 내용은 Apple Developer 공식 문서를 참고하세요.
Cocoapods
Buzzvil SDK를 설치하려면 CocoaPods을 사용하여 Podfile에 BuzzvilSDK를 추가하세요.
✏️ 참고
아래의 코드 스니펫은 최신 버전의 라이브러리를 기준으로 작성되었습니다.
pod 'BuzzvilSDK', '~> 6.6.2'참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
pod 'BuzzAdBenefit', '= 5.31.3'
SDK 초기화하기
BuzzvilSDK 초기화하기
BuzzBenefitConfig.Builder의 생성자의 파라미터 이름이 변경 되었습니다. appID에서 appId로 변경 되었습니다.
- Swift
- Objective C
import BuzzvilSDK
let config = BuzzBenefitConfig.Builder(appId: "YOUR_APP_ID")
.build()
BuzzBenefit.shared.initialize(with: config)
@import BuzzvilSDK;
BuzzBenefitConfig *config = [BuzzBenefitConfig configWith:^(BuzzBenefitConfigBuilder * _Nonnull builder) {
builder.appId = @"YOUR_APP_ID";
}];
[[BuzzBenefit sharedInstance] initializeWith:config];
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective C
import BuzzvilSDK
let config = BuzzBenefitConfig.Builder(appID: "YOUR_APP_ID")
.build()
BuzzBenefit.shared.initialize(with: config)
```objectivec
@import BuzzvilSDK;
BuzzBenefitConfig *config = [BuzzBenefitConfig configWithBlock:^(BuzzBenefitConfigBuilder * _Nonnull builder) {
builder.appID = @"YOUR_APP_ID";
}];
[[BuzzBenefit sharedInstance] initializeWithConfig:config];
```
다크모드 설정하기
다크모드는 코드단계에서 설정하는것이 아닌 서버값을 통해서 변경하도록 업데이트 되었습니다. 이에 따라 기존에 사용하던 다크모드 관련 코드를 삭제하세요.
| 다크 모드 설정 옵션 | 설명 |
|---|---|
BuzzBenefitUserInterfaceStyleLight | 시스템의 다크 모드 설정과 관계 없이 라이트 모드를 사용합니다. |
BuzzBenefitUserInterfaceStyleDark | 시스템의 다크 모드 설정과 관계 없이 다크 모드를 사용합니다. |
BuzzBenefitUserInterfaceStyleSystem | SDK의 다크 모드 설정 기본 값입니다. 시스템의 다크 모드 설정을 사용합니다. |
기존에 사용하던 다크모드 설정 관련 함수를 삭제해야 합니다.
- Swift
- Objective C
import BuzzvilSDK
@main
final class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
// ...생략...
BuzzBenefit.shared.setUserInterfaceStyle(.system) // 삭제 처리
return true
}
}
@import BuzzvilSDK;
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ...생략...
[[BuzzBenefit sharedInstance] setUserInterfaceStyle:BuzzBenefitUserInterfaceStyleSystem]; // 삭제 처리
return YES;
}
@end
로그인 요청하기
변경 사항이 없습니다.
베네핏허브
연동
베네핏허브 초기화하기
기존에 BZVFeedConfig를 사용하여 BuzzBenefitConfig에 등록하는 방식이 삭제 되었습니다. 이에 따라 BuzzBenefitConfig에 setDefaultFeedConfig함수도 삭제되어서 관련 코드를 삭제 해야 합니다.
- Swift
- Objective-C
import BuzzvilSDK
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
let config = BuzzBenefitConfig.Builder(appId: "YOUR_APP_ID")
.build()
BuzzBenefit.shared.initialize(with: config)
return true
}
}
@import BuzzvilSDK;
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
BuzzBenefitConfig *config = [BuzzBenefitConfig configWith:^(BuzzBenefitConfigBuilder * _Nonnull builder) {
builder.appId = @"YOUR_APP_ID";
}];
[BuzzBenefit sharedInstance] initializeWithConfig:config];
return YES;
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import BuzzvilSDK
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
let feedConfig = BZVFeedConfig { builder in
builder.unitID = "YOUR_FEED_UNIT_ID"
}
let config = BuzzBenefitConfig.Builder("YOUR_APP_ID")
.setDefaultFeedConfig(feedConfig)
.build()
BuzzBenefit.shared.initialize(with: config)
return true
}
}
@import BuzzvilSDK;
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
BZVFeedConfig *feedConfig = [BZVFeedConfig configWithBlock:^(BZVFeedConfigBuilder * _Nonnull builder) {
builder.unitID = @"YOUR_FEED_UNIT_ID";
}];
BuzzBenefitConfig *config = [BuzzBenefitConfig configWithBlock:^(BuzzBenefitConfigBuilder * _Nonnull builder) {
builder.appID = @"YOUR_APP_ID";
builder.defaultFeedConfig = feedConfig;
}];
[BuzzBenefit sharedInstance] initializeWithConfig:config];
return YES;
}
@end
베네핏허브 표시하기
기존의 BZVBuzzAdFeed객체가 BuzzBenefitHub객체로 이름이 변경되었습니다. 변경된 객체를 통해 BenefitHub를 보여줍니다.
기존의 ViewController 를 받아와 하위 뷰 컨트롤러로 사용하는 방법은 동일하게 지원합니다.
- Swift
- Objective C
let yourViewController = UIViewController()
let benefitHub = BuzzBenefitHub()
benefitHub.show(on: yourViewController)
UIViewController *yourViewController = [[UIViewController alloc] init];
BuzzBenefitHub *benefitHub = [[BuzzBenefitHub alloc] init];
[benefitHub showOn:yourViewController];
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
/** 참고 - 변경 전 코드(BuzzAdBenefit v5) **/
let yourViewController = UIViewController()
let buzzAdFeed = BZVBuzzAdFeed { _ in }
buzzAdFeed.show(on: yourViewController)
/** 참고 - 변경 전 코드(BuzzAdBenefit v5) **/
UIViewController *yourViewController = [[UIViewController alloc] init];
BZVBuzzAdFeed *buzzAdFeed = [BZVBuzzAdFeed feedWithBlock:^(BZVBuzzAdFeedBuilder * _Nonnull builder) {}];
[buzzAdFeed showOn:yourViewController];
기본 설정 이외의 베네핏허브 표시하기
기본 설정 이외의 베네핏허브를 표시하는 기능은 삭제 되었습니다. BuzzBenefitHub 객체를 선언하여 베네핏허브를 표시할 수 있습니다.
이에 사용되던 BZVFeedConfig 관련 코드 삭제가 필요합니다.
럭키박스
베네핏허브 객체를 통해 럭키박스를 곧바로 실행할 수 있도록 기능이 업데이트 되었습니다. 기존에 제공하던 럭키박스를 바로 표시하기기능을 실행하기 위한 코드가 변경 되었습니다.
- Swift
- Objective C
let yourViewController = UIViewController()
let benefitHub = BuzzBenefitHub()
let benefitHubConfig = BuzzBenefitHubConfig.Builder()
.setQueryParams(BuzzBenefitHubPage.luckyBox.toRedirectQueryParams())
.build()
benefitHub.setConfig(benefitHubConfig)
benefitHub.show(on: yourViewController)
UIViewController *yourViewController = [[UIViewController alloc] init];
BuzzBenefitHubConfig * benefithubConfig = [BuzzBenefitHubConfig configWith:^(BuzzBenefitHubConfigBuilder * _Nonnull builder) {
builder.queryParams = [BuzzBenefitHubPage.luckyBox toRedirectQueryParams];
}];
[self.benefitHub setConfig:benefithubConfig];
[benefitHub showOn:yourViewController];
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
/** 참고 - 변경 전 코드(BuzzAdBenefit v5) **/
let yourViewController = UIViewController()
let feedConfig = BZVFeedConfig { builder in
builder.unitID = "BENEFIT_HUB_UNIT_ID"
builder.initialNavigationPage = .luckyBox
}
let buzzAdFeed = BZVBuzzAdFeed(block: { builder in
builder.config = feedConfig
})
/** 참고 - 변경 전 코드(BuzzAdBenefit v5) **/
UIViewController *yourViewController = [[UIViewController alloc] init];
BZVFeedConfig *feedConfig = [BZVFeedConfig configWithBlock:^(BZVFeedConfigBuilder * _Nonnull builder) {
builder.unitID = @"BENEFITHUB_UNIT_ID";
builder.initialNavigationPage = BZVFeedInitialNavigationPageLuckyBox;
}];
BZVBuzzAdFeed *buzzAdFeed = [BZVBuzzAdFeed feedWithBlock:^(BZVBuzzAdFeedBuilder * _Nonnull builder) {
builder.config = feedConfig;
}];
[buzzAdFeed showOn:yourViewController];
미션팩
베네핏허브 객체를 통해 미션팩을 곧바로 실행할 수 있도록 기능이 업데이트 되었습니다. 기존에 제공하던 미션팩을 바로 표시하기 기능을 실행하기 위한 코드가 변경 되었습니다.
- Swift
- Objective C
let yourViewController = UIViewController()
let benefitHub = BuzzBenefitHub()
let benefitHubConfig = BuzzBenefitHubConfig.Builder()
.setQueryParams(BuzzBenefitHubPage.missionPack.toRedirectQueryParams())
.build()
benefitHub.setConfig(benefitHubConfig)
benefitHub.show(on: yourViewController)
UIViewController *yourViewController = [[UIViewController alloc] init];
BuzzBenefitHubConfig * benefithubConfig = [BuzzBenefitHubConfig configWith:^(BuzzBenefitHubConfigBuilder * _Nonnull builder) {
builder.queryParams = [BuzzBenefitHubPage.missionPack toRedirectQueryParams];
}];
[self.benefitHub setConfig:benefithubConfig];
[benefitHub showOn:yourViewController];
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
/** 참고 - 변경 전 코드(BuzzAdBenefit v5) **/
let yourViewController = UIViewController()
let feedConfig = BZVFeedConfig { builder in
builder.unitID = "BENEFIT_HUB_UNIT_ID"
builder.initialNavigationPage = .missionPack
}
let buzzAdFeed = BZVBuzzAdFeed(block: { builder in
builder.config = feedConfig
})
/** 참고 - 변경 전 코드(BuzzAdBenefit v5) **/
UIViewController *yourViewController = [[UIViewController alloc] init];
BZVFeedConfig *feedConfig = [BZVFeedConfig configWithBlock:^(BZVFeedConfigBuilder * _Nonnull builder) {
builder.unitID = @"BENEFITHUB_UNIT_ID";
builder.initialNavigationPage = BZVFeedInitialNavigationPageMissionPack;
}];
BZVBuzzAdFeed *buzzAdFeed = [BZVBuzzAdFeed feedWithBlock:^(BZVBuzzAdFeedBuilder * _Nonnull builder) {
builder.config = feedConfig;
}];
[buzzAdFeed showOn:yourViewController];
적립내역
기존에 제공하지 않던 적립내역을 표시할 수 있는 페이지가 추가 되었습니다. 베네핏허브를 거치지 않고 곧바로 열 수 있는 기능 또한 제공 하고 있습니다.
- Swift
- Objective C
let yourViewController = UIViewController()
let benefitHub = BuzzBenefitHub()
let benefitHubConfig = BuzzBenefitHubConfig.Builder()
.setQueryParams(BuzzBenefitHubPage.history.toRedirectQueryParams())
.build()
benefitHub.setConfig(benefitHubConfig)
benefitHub.show(on: yourViewController)
UIViewController *yourViewController = [[UIViewController alloc] init];
BuzzBenefitHubConfig * benefithubConfig = [BuzzBenefitHubConfig configWith:^(BuzzBenefitHubConfigBuilder * _Nonnull builder) {
builder.queryParams = [BuzzBenefitHubPage.history toRedirectQueryParams];
}];
[self.benefitHub setConfig:benefithubConfig];
[benefitHub showOn:yourViewController];
앱 UI 에 진입 경로 구현
BZVFeedEntryView 관련 기능이 삭제 되었습니다. BuzzBenefitHub 를 통해서 베네핏허브를 실행 시키는 방법으로 업데이트가 필요합니다. BZVFeedEntryView 을 사용하여 작성된 코드를 삭제 해주세요.
적립 가능한 포인트 표시하기
BZVBuzzAdFeed 를 통해 제공되던 availableReward 기능이 삭제 되었습니다. BZVBuzzAdFeed.load() 기능또한 제거되어서 관련 코드 제거가 필요합니다.
추가 구현
하위 뷰 컨트롤러로 베네핏허브 연동하기
기존과 동일하게 기능을 제공하지만, class 이름이 변경되었습니다. 이에 맞게 코드 업데이트가 필요합니다.
- Swift
- Objective C
import BuzzvilSDK
final class ContainerViewController: UIViewController {
let benefitHub = BuzzBenefitHub()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
displayContentViewController(benefitHub.getViewController())
}
private func displayContentViewController(_ contentViewController: UIViewController) {
addChild(contentViewController)
contentViewController.view.frame = view.bounds
view.addSubview(contentViewController.view)
contentViewController.didMove(toParent: self)
}
}
@import BuzzvilSDK;
@interface ContainerViewController ()
@property (nonatomic, strong, readonly) BuzzBenefitHub *benefitHub;
@end
@implementation ContainerViewController
- (void)viewDidLoad {
[super viewDidLoad];
_benefitHub = [[BuzzBenefitHub alloc] init];
[self displayContentViewController:[_benefitHub getViewController]];
}
- (void)displayContentViewController:(UIViewController*)contentViewController {
[self addChildViewController:contentViewController];
contentViewController.view.frame = self.view.bounds;
[self.view addSubview:contentViewController.view];
[contentViewController didMoveToParentViewController:self];
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective C
import BuzzvilSDK
final class ContainerViewController: UIViewController {
let buzzAdFeed = BZVBuzzAdFeed { builder in }
override func viewDidLoad() {
super.viewDidLoad()
displayContentViewController(buzzAdFeed.viewController)
}
private func displayContentViewController(_ contentViewController: UIViewController) {
addChild(contentViewController)
contentViewController.view.frame = view.bounds
view.addSubview(contentViewController.view)
contentViewController.didMove(toParent: self)
}
}
```objectivec
@import BuzzvilSDK;
@interface ContainerViewController ()
@property (nonatomic, strong, readonly) BZVBuzzAdFeed *buzzAdFeed;
@end
@implementation ContainerViewController
- (void)viewDidLoad {
[super viewDidLoad];
_buzzAdFeed = [BZVBuzzAdFeed feedWithBlock:^(BZVBuzzAdFeedBuilder * _Nonnull builder) {}];
[self displayContentViewController:[_buzzAdFeed viewController]];
}
- (void)displayContentViewController:(UIViewController*)contentViewController {
[self addChildViewController:contentViewController];
contentViewController.view.frame = self.view.bounds;
[self.view addSubview:contentViewController.view];
[contentViewController didMoveToParentViewController:self];
}
@end
```
네이티브
연동
1 단계. 준비하기
변경 사항이 없습니다.
2 단계. 광고 레이아웃 구성하기
기존과 거의 동일하게 기능을 제공하지만, Class 이름이 변경 되었습니다.
BZVMediaView -> BuzzMediaView
BZVDefaultCtaView -> BuzzDefaultCtaView
BZVNativeAd2View -> BuzzNativeAdView
BZVNativeAd2ViewBinder -> BuzzNativeViewBinder
더해서 BuzzNativeViewBinder.Builder()의 생성자에 들어가던 UnitID 값이 삭제 되고 BuzzNative로 이관 되었습니다.
그리고 베네핏허브 진입점으로 활용되던 BZVNativeToFeedView가 삭제 되었습니다. 관련 코드 삭제가 필요합니다.
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class ViewController: UIViewController {
private let nativeAdView = BuzzNativeAdView(frame: .zero)
private let mediaView = BuzzMediaView(frame: .zero)
private let iconImageView = UIImageView(frame: .zero)
private let titleLabel = UILabel(frame: .zero)
private let descriptionLabel = UILabel(frame: .zero)
private let ctaView = BuzzDefaultCtaView(frame: .zero)
private lazy var viewBinder = BuzzNativeViewBinder.Builder()
.nativeAdView(nativeAdView)
.mediaView(mediaView)
.iconImageView(iconImageView)
.titleLabel(titleLabel)
.descriptionLabel(descriptionLabel)
.ctaView(ctaView)
.build()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(nativeAdView)
nativeAdView.addSubview(mediaView)
nativeAdView.addSubview(iconImageView)
nativeAdView.addSubview(titleLabel)
nativeAdView.addSubview(descriptionLabel)
nativeAdView.addSubview(ctaView)
// AutoLayout Constraints 설정
// ...
}
}
@import BuzzvilSDK;
@interface ViewController ()
@property (nonatomic, strong, readonly) BuzzNativeAdView *nativeAdView;
@property (nonatomic, strong, readonly) BuzzMediaView *mediaView;
@property (nonatomic, strong, readonly) UIImageView *iconImageView;
@property (nonatomic, strong, readonly) UILabel *titleLabel;
@property (nonatomic, strong, readonly) UILabel *descriptionLabel;
@property (nonatomic, strong, readonly) BuzzDefaultCtaView *ctaView;
@property (nonatomic, strong, readonly) BuzzNativeViewBinder *viewBinder;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_nativeAdView = [[BuzzNativeAdView alloc] initWithFrame:CGRectZero];
[self.view addSubview:_nativeAdView];
_mediaView = [[BuzzMediaView alloc] initWithFrame:CGRectZero];
[_nativeAdView addSubview:_mediaView];
_iconImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
[_nativeAdView addSubview:_iconImageView];
_titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[_nativeAdView addSubview:_titleLabel];
_descriptionLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[_nativeAdView addSubview:_descriptionLabel];
_ctaView = [[BuzzDefaultCtaView alloc] initWithFrame:CGRectZero];
[_nativeAdView addSubview:_ctaView];
_viewBinder = [BuzzNativeViewBinder viewBinderWithk:^(BuzzNativeViewBinderBuilder * _Nonnull builder) {
builder.nativeAdView = self.nativeAdView;
builder.mediaView = self.mediaView;
builder.iconImageView = self.iconImageView;
builder.titleLabel = self.titleLabel;
builder.descriptionLabel = self.descriptionLabel;
builder.ctaView = self.ctaView;
}];
// AutoLayout Constraints 설정
// ...
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class ViewController: UIViewController {
private let nativeAd2View = BZVNativeAd2View(frame: .zero)
private let mediaView = BZVMediaView(frame: .zero)
private let iconImageView = UIImageView(frame: .zero)
private let titleLabel = UILabel(frame: .zero)
private let descriptionLabel = UILabel(frame: .zero)
private let ctaView = BZVDefaultCtaView(frame: .zero)
private let nativeToFeedView = BZVNativeToFeedView(frame: .zero)
private lazy var viewBinder = BZVNativeAd2ViewBinder
.Builder(unitId: "YOUR_NATIVE_UNIT_ID")
.nativeAd2View(nativeAd2View)
.mediaView(mediaView)
.iconImageView(iconImageView)
.titleLabel(titleLabel)
.descriptionLabel(descriptionLabel)
.ctaView(ctaView)
.build()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(nativeAd2View)
nativeAd2View.addSubview(mediaView)
nativeAd2View.addSubview(iconImageView)
nativeAd2View.addSubview(titleLabel)
nativeAd2View.addSubview(descriptionLabel)
nativeAd2View.addSubview(ctaView)
self.view.addSubView(nativeToFeedView)
nativeToFeedView.setUnitId("YOUR_NATIVE_UNIT_ID")
// AutoLayout Constraints 설정
// ...
}
}
@import BuzzvilSDK;
@interface ViewController ()
@property (nonatomic, strong, readonly) BZVNativeAd2View *nativeAd2View;
@property (nonatomic, strong, readonly) BZVMediaView *mediaView;
@property (nonatomic, strong, readonly) UIImageView *iconImageView;
@property (nonatomic, strong, readonly) UILabel *titleLabel;
@property (nonatomic, strong, readonly) UILabel *descriptionLabel;
@property (nonatomic, strong, readonly) BZVDefaultCtaView *ctaView;
@property (nonatomic, strong, readonly) BZVNativeAd2ViewBinder *viewBinder;
@property (nonatomic, strong, readonly) BZVNativeToFeedView *nativeToFeedView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_nativeAd2View = [[BZVNativeAd2View alloc] initWithFrame:CGRectZero];
[self.view addSubview:_nativeAd2View];
_mediaView = [[BZVMediaView alloc] initWithFrame:CGRectZero];
[_nativeAd2View addSubview:_mediaView];
_iconImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
[_nativeAd2View addSubview:_iconImageView];
_titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[_nativeAd2View addSubview:_titleLabel];
_descriptionLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[_nativeAd2View addSubview:_descriptionLabel];
_ctaView = [[BZVDefaultCtaView alloc] initWithFrame:CGRectZero];
[_nativeAd2View addSubview:_ctaView];
_viewBinder = [BZVNativeAd2ViewBinder viewBinderWithBlock:^(BZVNativeAd2ViewBinderBuilder * _Nonnull builder) {
builder.unitId = @"YOUR_NATIVE_UNIT_ID";
builder.nativeAd2View = self.nativeAd2View;
builder.mediaView = self.mediaView;
builder.iconImageView = self.iconImageView;
builder.titleLabel = self.titleLabel;
builder.descriptionLabel = self.descriptionLabel;
builder.ctaView = self.ctaView;
}];
_nativeToFeedView = [[BZVNativeToFeedView alloc] initWithFrame:CGRectZero];
[self.view addSubview:_nativeToFeedView];
[_nativeToFeedView setWithUnitId:@"YOUR_NATIVE_UNIT_ID"];
// AutoLayout Constraints 설정
// ...
}
@end
3 단계. 광고 보여주기
광고 할당을 위해 사용되던 BZVNativeAd2ViewBinder.bind()함수가 사라지고 BuzzNative.load()함수로 변경 되었습니다. BuzzNative에서 할당받은 광고를 ViewBinder를 통해 화면에 보여지는 방식으로 업데이트 되었습니다. 이에 따라 광고 할당을 위한 코드 업데이트가 필요합니다.
- Swift
- Objective-C
final class ViewController: UIViewController {
private lazy var native = BuzzNative(unitId: "YOUR_NATIVE_UNIT_ID")
private lazy var viewBinder = BuzzNativeViewBinder.Builder()
.nativeAdView(nativeAdView)
.mediaView(mediaView)
.iconImageView(iconImageView)
.titleLabel(titleLabel)
.descriptionLabel(descriptionLabel)
.ctaView(ctaView)
.build()
override func viewDidLoad() {
// Warning: retain cycle 방지를 위해 closure 내에서 반드시 weak self를 사용해주세요.
native.subscribeRefreshEvents(
onRequest: { [weak self] in
// 광고 갱신 할당을 요청한 상태입니다.
// 이후에는 onSuccess, onFailure 중 하나가 호출됩니다.
// 광고 자동 갱신을 시도할 때마다 반복적으로 호출됩니다.
},
onSuccess: { [weak self] nativeAd in
// 광고 갱신 할당에 성공하면 호출됩니다.
},
onFailure: { [weak self] error in
// 더 이상 갱신할 수 있는 광고가 없을 때 호출됩니다.
}
)
// 광고 할당을 수행합니다.
native.load(
onSuccess: { [weak self] nativeAd in
// 초기 광고 할당에 성공하면 호출됩니다.
},
onFailure: { [weak self] error in
// 초기 광고 할당에 실패하면 호출됩니다.
}
)
// 할당된 광고 표시를 자동으로 수행합니다.
viewBinder.bind(native)
}
}
@interface ViewController ()
@property (nonatomic, strong, readonly) BuzzNative *native;
@property (nonatomic, strong, readonly) BuzzNativeViewBinder *viewBinder;
@end
@implementation ViewController
- (void)viewDidLoad {
// ...생략...
// Warning: retain cycle 방지를 위해 weak self를 사용해주세요.
__weak typeof(self) weakSelf = self;
[_viewBinder subscribeRefreshEvents:^{
// 광고 갱신 할당을 요청한 상태입니다.
// 이후에는 onSuccess, onFailure 중 하나가 호출됩니다.
// 광고 자동 갱신을 시도할 때마다 반복적으로 호출됩니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
// ...
}
} onSuccess:^(BuzzNativeAd * _Nonnull nativeAd) {
// 광고 갱신 할당에 성공하면 호출됩니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
// ...
}
} onError:^(NSError * _Nonnull error) {
// 더 이상 갱신할 수 있는 광고가 없을 때 호출됩니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
// ...
}
}];
// 광고 할당을 수행합니다.
[_native loadOnSuccess:^(BuzzNativeAd * _Nonnull nativeAd) {
// 초기 광고 할당에 성공하면 호출됩니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
// ...
}
} onFailure:^(NSError * _Nonnull error) {
// 초기 광고 할당에 실패하면 호출됩니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
// ...
}
}];
// 할당된 광고 표시를 자동으로 수행합니다.
[_viewBinder bindWithNative:_native];
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
final class ViewController: UIViewController {
// ...생략...
private let activityIndicatorView = UIActivityIndicatorView(frame: .zero)
override func viewDidLoad() {
// ...생략...
// Warning: retain cycle 방지를 위해 closure 내에서 반드시 weak self를 사용해주세요.
viewBinder.subscribeEvents(onRequest: { [weak self] in
// 광고 할당을 요청한 상태입니다.
// 이후에는 onNext, onCompleted, onError 중 하나가 호출됩니다.
// 광고 자동 갱신을 시도할 때마다 반복적으로 호출됩니다.
// 로딩 화면 등을 구현할 수 있습니다.
self?.activityIndicatorView.startAnimating()
}, onNext: { [weak self] nativeAd2 in
// 광고 할당에 성공하면 호출됩니다.
// 이후에 광고 갱신 시 onRequest가 다시 호출됩니다.
// 광고 자동 갱신을 성공할 때마다 반복적으로 호출됩니다.
// 로딩 화면 등을 구현한 경우, 여기에서 로딩을 종료합니다.
self?.activityIndicatorView.stopAnimating()
}, onError: { [weak self] error in
// 최초 광고 할당에 실패하면 호출됩니다.
// 로딩 화면 등을 구현한 경우, 여기에서 로딩을 종료합니다.
self?.activityIndicatorView.stopAnimating()
// NativeAd2View를 숨기거나, Error UI로 대체할 수 있습니다.
print("Failed to load ad by \(error.localizedDescription).")
}, onCompleted: { [weak self] in
// 더 이상 갱신할 수 있는 광고가 없을 때 호출됩니다.
// 로딩 화면 등을 구현한 경우, 여기에서 로딩을 종료합니다.
self?.activityIndicatorView.stopAnimating()
})
// 광고 할당 및 표시를 자동으로 수행합니다.
viewBinder.bind()
}
}
@interface ViewController ()
// ...생략...
@property (nonatomic, strong, readonly) UIActivityIndicatorView *activityIndicatorView;
@end
@implementation ViewController
- (void)viewDidLoad {
// ...생략...
// Warning: retain cycle 방지를 위해 weak self를 사용해주세요.
__weak typeof(self) weakSelf = self;
[_viewBinder subscribeEventsOnRequest:^{
// 광고 할당을 요청하면 호출됩니다.
// 이후에는 onNext, onCompleted, onError 중 하나가 호출됩니다.
// 광고 자동 갱신을 시도할 때마다 반복적으로 호출됩니다.
// 로딩 화면 등을 구현할 수 있습니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView startAnimating];
}
} onNext:^(BZVNativeAd2 * _Nonnull nativeAd2) {
// 광고 할당에 성공하면 호출됩니다.
// 이후에 광고 갱신 시 onRequest가 다시 호출됩니다.
// 광고 자동 갱신을 성공할 때마다 반복적으로 호출됩니다.
// 로딩 화면 등을 구현한 경우, 여기에서 로딩을 종료합니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView stopAnimating];
}
} onError:^(NSError * _Nonnull error) {
// 최초 광고 할당에 실패하면 호출됩니다.
// 로딩 화면 등을 구현한 경우, 여기에서 로딩을 종료합니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView stopAnimating];
}
// NativeAd2View를 숨기거나, Error UI로 대체할 수 있습니다.
NSLog(@"Failed to load ad by %@.", error.localizedDescription);
} onCompleted:^{
// 더 이상 갱신할 수 있는 광고가 없을 때 호출됩니다.
// 로딩 화면 등을 구현한 경우, 여기에서 로딩을 종료합니다.
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView stopAnimating];
}
}];
// 광고 할당 및 표시를 자동으로 수행합니다.
[_viewBinder bind];
}
@end
베이스 리워드 금액 표시하기
베이스 리워드를 미리 표시하는 기능이 삭제 되었습니다. 이에 따라 BuzzAdBenefit.getAvailableFeedBaseReward()함수도 삭제되어서 관련 코드삭제가 필요합니다.
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
BuzzAdBenefit.getAvailableFeedBaseReward(for: YOUR_FEED_UNIT_ID) { [weak self] (reward) in
guard let self = self else { return }
if reward > 0 {
self.nativeToFeedLabel.text = "\(reward) 포인트 받고 더 많은 참여 기회 보기"
} else {
self.nativeToFeedLabel.text = "더 많은 참여 기회 보기"
}
}
__weak typeof(self) weakSelf = self;
[BuzzAdBenefit getAvailableFeedBaseRewardFor:@"YOUR_FEED_UNIT_ID" onComplete:^(NSInteger reward) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
if (reward > 0) {
strongSelf.nativeToFeedLabel.text = [NSString stringWithFormat:@"%d 포인트 받고 더 많은 참여 기회 보기", reward];
} else {
strongSelf.nativeToFeedLabel.text = @"더 많은 참여 기회 보기";
}
}
}];
추가 구현
동영상 광고 리스너 등록하기
Native 지면에서는 동영상 광고가 제공되지 않기 때문에 동영상 광고 리스너는 제거 되었습니다. BZVNativeAdViewVideoDelegate protocol이 삭제 되었기 때문에 관련 코드 삭제가 필요합니다.
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class ViewController: UIViewController {
private let nativeAd2View = BZVNativeAd2View(frame: .zero)
// ...생략...
override func viewDidLoad() {
// ...생략...
nativeAd2View.videoDelegate = self
}
}
// MARK: BZVNativeAdViewVideoDelegate
extension ViewController: BZVNativeAdViewVideoDelegate {
func bzvNativeAdView(_ nativeAdView: BZVNativeAdView, willStartPlayingVideoAd nativeAd: BZVNativeAd) {
// 비디오 광고의 비디오가 시작하기 직전에 호출됩니다.
}
func bzvNativeAdView(_ nativeAdView: BZVNativeAdView, didResumeVideoAd nativeAd: BZVNativeAd) {
// 비디오 광고의 비디오가 재생되면 호출됩니다.
}
func bzvNativeAdView(_ nativeAdView: BZVNativeAdView, willReplayVideoAd nativeAd: BZVNativeAd) {
// 비디오 광고의 비디오가 리플레이되면 호출됩니다.
}
func bzvNativeAdView(_ nativeAdView: BZVNativeAdView, didPauseVideoAd nativeAd: BZVNativeAd) {
// 비디오 광고의 비디오가 일시정지되면 호출됩니다.
}
func bzvNativeAdView(_ nativeAdView: BZVNativeAdView, didFinishPlayingVideoAd nativeAd: BZVNativeAd) {
// 비디오 광고의 비디오가 종료되면 호출됩니다.
}
}
@import BuzzvilSDK;
@interface ViewController () <BZVNativeAdViewVideoDelegate>
@property (nonatomic, strong, readonly) BZVNativeAd2View *nativeAd2View;
// ...생략...
@end
@implementation ViewController
- (void)viewDidLoad {
// ...생략...
_nativeAd2View.videoDelegate = self;
}
#pragma mark - BZVNativeAdViewVideoDelegate
- (void)BZVNativeAdView:(BZVNativeAdView *)nativeAdView willStartPlayingVideoAd:(BZVNativeAd *)nativeAd {
// 비디오 광고의 비디오가 시작하기 직전에 호출됩니다.
}
- (void)BZVNativeAdView:(BZVNativeAdView *)nativeAdView didResumeVideoAd:(BZVNativeAd *)nativeAd {
// 비디오 광고의 비디오가 재생되면 호출됩니다.
}
- (void)BZVNativeAdView:(BZVNativeAdView *)nativeAdView willReplayVideoAd:(BZVNativeAd *)nativeAd {
// 비디오 광고의 비디오가 리플레이되면 호출됩니다.
}
- (void)BZVNativeAdView:(BZVNativeAdView *)nativeAdView didPauseVideoAd:(BZVNativeAd *)nativeAd {
// 비디오 광고의 비디오가 일시정지되면 호출됩니다.
}
- (void)BZVNativeAdView:(BZVNativeAdView *)nativeAdView didFinishPlayingVideoAd:(BZVNativeAd *)nativeAd {
// 비디오 광고의 비디오가 종료되면 호출됩니다.
}
@end
광고 이벤트 리스너 등록하기
BZVNativeAd2ViewBinder를 통해 광고 이벤트를 받을 수 있던 부분이 BuzzNative 객체를 통해 받도록 변경 되었습니다. 이에 따라 코드 업데이트가 필요합니다.
- Swift
- Objective-C
final class ViewController: UIViewController {
// ...생략...
override func viewDidLoad() {
// ...생략...
// Native 광고 이벤트 처리를 위한 closure를 등록하고 각 이벤트에 따라 필요한 기능을 구현합니다.
// Warning: retain cycle 방지를 위해 closure 내에서 반드시 weak self를 사용해주세요.
native.subscribeAdEvents(onImpressed: { [weak self] nativeAd in
// Native 광고가 유저에게 노출되었을 때 호출됩니다.
}, onClicked: { [weak self] nativeAd in
// 유저가 Native 광고를 클릭했을 때 호출됩니다.
}, onRewardRequested: { [weak self] nativeAd in
// 리워드 적립 요청시에 호출됩니다.
}, onRewarded: { [weak self] nativeAd, rewardResult in
// 리워드 적립 결과를 수신했을 때 호출됩니다.
}, onParticipated: { [weak self] nativeAd in
// 광고 참여가 완료되었을 때 호출됩니다.
})
// ...생략...
}
}
@implementation ViewController
- (void)viewDidLoad {
// ...생략...
// Native 광고 이벤트 처리를 위한 closure를 등록하고 각 이벤트에 따라 필요한 기능을 구현합니다.
// Warning: retain cycle 방지를 위해 closure 내에서 반드시 weak self를 사용해주세요.
__weak typeof(self) weakSelf = self;
[_native subscribeAdEventsOnImpressed:^(BuzzNativeAd * _Nonnull nativeAd) {
__strong typeof(self) strongSelf = weakSelf;
// Native 광고가 유저에게 노출되었을 때 호출됩니다.
} onClicked:^(BuzzNativeAd * _Nonnull nativeAd) {
__strong typeof(self) strongSelf = weakSelf;
// 유저가 Native 광고를 클릭했을 때 호출됩니다.
} onRewardRequested:^(BuzzNativeAd * _Nonnull nativeAd) {
__strong typeof(self) strongSelf = weakSelf;
// 리워드 적립 요청시에 호출됩니다.
} onRewarded:^(BuzzNativeAd * _Nonnull nativeAd, BuzzRewardResult rewardResult) {
__strong typeof(self) strongSelf = weakSelf;
// 리워드 적립 결과를 수신했을 때 호출됩니다.
} onParticipated:^(BuzzNativeAd * _Nonnull nativeAd) {
__strong typeof(self) strongSelf = weakSelf;
// 광고 참여가 완료되었을 때 호출됩니다.
}];
// ...생략...
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
final class ViewController: UIViewController {
// ...생략...
override func viewDidLoad() {
// ...생략...
// Native 광고 이벤트 처리를 위한 closure를 등록하고 각 이벤트에 따라 필요한 기능을 구현합니다.
// 로그 기록, 단순 알림 외에 다른 동작을 추가하는 것을 권장하지 않습니다. 자동 갱신 등 네이티브 2.0의 기능과 직접 구현한 동작이 충돌할 수 있습니다.
// Warning: 반드시 bind 함수를 호출하기 전에 호출해야 해야합니다.
// Warning: retain cycle 방지를 위해 closure 내에서 반드시 weak self를 사용해주세요.
viewBinder.subscribeAdEvents(onImpressed: { [weak self] nativeAd2 in
// Native 광고가 유저에게 노출되었을 때 호출됩니다.
}, onClicked: { [weak self] nativeAd2 in
// 유저가 Native 광고를 클릭했을 때 호출됩니다.
}, onRewardRequested: { [weak self] nativeAd2 in
// 리워드 적립 요청시에 호출됩니다.
}, onRewarded: { [weak self] nativeAd2, rewardResult in
// 리워드 적립 결과를 수신했을 때 호출됩니다.
}, onParticipated: { [weak self] nativeAd2 in
// 광고 참여가 완료되었을 때 호출됩니다.
})
viewBinder.bind()
}
}
</TabItem>
<TabItem value="objectivec" label="Objective-C">
@implementation ViewController
- (void)viewDidLoad {
// ...생략...
// Native 광고 이벤트 처리를 위한 closure를 등록하고 각 이벤트에 따라 필요한 기능을 구현합니다.
// 로그 기록, 단순 알림 외에 다른 동작을 추가하는 것을 권장하지 않습니다. 자동 갱신 등 네이티브 2.0의 기능과 직접 구현한 동작이 충돌할 수 있습니다.
// Warning: 반드시 bind 함수를 호출하기 전에 호출해야 해야합니다.
// Warning: retain cycle 방지를 위해 closure 내에서 반드시 weak self를 사용해주세요.
__weak typeof(self) weakSelf = self;
[_viewBinder subscribeAdEventsOnImpressed:^(BZVNativeAd2 * _Nonnull nativeAd2) {
__strong typeof(self) strongSelf = weakSelf;
// Native 광고가 유저에게 노출되었을 때 호출됩니다.
} onClicked:^(BZVNativeAd2 * _Nonnull nativeAd2) {
__strong typeof(self) strongSelf = weakSelf;
// 유저가 Native 광고를 클릭했을 때 호출됩니다.
} onRewardRequested:^(BZVNativeAd2 * _Nonnull nativeAd2) {
__strong typeof(self) strongSelf = weakSelf;
// 리워드 적립 요청시에 호출됩니다.
} onRewarded:^(BZVNativeAd2 * _Nonnull nativeAd2, BZVRewardResult rewardResult) {
__strong typeof(self) strongSelf = weakSelf;
// 리워드 적립 결과를 수신했을 때 호출됩니다.
} onParticipated:^(BZVNativeAd2 * _Nonnull nativeAd2) {
__strong typeof(self) strongSelf = weakSelf;
// 광고 참여가 완료되었을 때 호출됩니다.
}];
[_viewBinder bind];
}
@end
리워드 적립 결과 (BZVRewardResult)
BZVRewardResult에서 BuzzRewardResult 로 클래스 명이 변경 되었습니다. 리워드 적립 결과(BuzzRewardResult) 종류를 참고하세요.
캐러셀 구현하기
캐러셀의 기본 기능 구현하기
1 단계. 광고 할당 받기
기존에 사용하고있던 class 및 함수들이 변경 되었습니다. 아래 표를 참고하여 코드를 업데이트 해 주세요
| AS-IS | TO-BE |
|---|---|
BZVNativeAd2Pool | BuzzNativeGroup |
BZVNativeAd2Pool.loadAds() | BuzzNativeGroup.load() |
completionHandler | onSuccess |
errorHandler | onFailure |
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class CarouselViewController: UIViewController {
private let unitId = "YOUR_UNIT_ID"
// 최대 10개의 광고를 요청할 수 있습니다.
private let adRequestCount = 5
// 실제 할당받은 광고의 개수입니다.
// 이 값은 collectionView datasource의 collectionView(_:numberOfItemsInSection:) 함수의 return 값으로 사용합니다.
private var loadedAdCount = 0
// 광고 중복 할당을 막기 위해 하나의 캐러셀에 하나의 BuzzNativeGroup 인스턴스를 생성하여 사용합니다.
private lazy var nativeGroup = BuzzNativeGroup(unitId: unitId)
override func viewDidLoad() {
super.viewDidLoad()
setupCarousel()
}
private func setupCarousel() {
// BuzzNativeGroup에 광고 할당을 요청합니다.
nativeGroup.load(
count: adRequestCount,
onSuccess: { [weak self] adCount in
// 실제로 할당받은 광고의 개수(count)를 업데이트합니다.
self?.loadedAdCount = adCount
},
onFailure: { [weak self] error in
// 광고 할당 실패 시 발생하는 NSError 오류 코드에 대한 자세한 내용은 오류 코드가 나타납니다 토픽을 참고하세요.
}
)
}
}
@import BuzzvilSDK;
static NSString * const kUnitId = @"YOUR_UNIT_ID";
@interface CarouselViewController ()
// 최대 10개의 광고를 요청할 수 있습니다.
@property (nonatomic, assign, readonly) NSInteger adRequestCount;
// 실제 할당받은 광고의 개수입니다.
// 이 값은 collectionView datasource의 collectionView(_:numberOfItemsInSection:) 함수의 return 값으로 사용합니다.
@property (nonatomic, assign, readwrite) NSInteger loadedAdCount;
// 광고 중복 할당을 막기 위해 하나의 캐러셀에 하나의 BuzzNativeGroup 인스턴스를 생성하여 사용합니다.
@property (nonatomic, strong, readonly) BuzzNativeGroup *nativeGroup;
@end
@implementation CarouselViewController
- (void)viewDidLoad {
[super viewDidLoad];
_adRequestCount = 5;
_loadedAdCount = 0;
_nativeGroup = [[BuzzNativeGroup alloc] initWithUnitId:kUnitId];
[self setupCarousel];
}
- (void)setupCarousel {
__weak typeof(self) weakSelf = self;
// BuzzNativeGroup에 광고 할당을 요청합니다.
[self.nativeGroup loadWithCount:self.adRequestCount onSuccess:^(NSInteger count) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
// 실제로 할당받은 광고의 개수(count)를 업데이트합니다.
strongSelf.loadedAdCount = count;
}
} onFailure:^(NSError * _Nonnull error) {
// 광고 할당 실패 시 발생하는 NSError 오류 코드에 대한 자세한 내용은 오류 코드가 나타납니다 토픽을 참고하세요.
}];
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class CarouselViewController: UIViewController {
private let unitID = "YOUR_UNIT_ID"
// 최대 10개의 광고를 요청할 수 있습니다.
private let adRequestCount = 5
// 실제 할당받은 광고의 개수입니다.
// 이 값은 collectionView datasource의 collectionView(_:numberOfItemsInSection:) 함수의 return 값으로 사용합니다.
private var loadedAdCount = 0
// 광고 중복 할당을 막기 위해 하나의 캐러셀에 하나의 NativeAd2Pool 인스턴스를 생성하여 사용합니다.
private lazy var pool = BZVNativeAd2Pool(unitId: unitId)
override func viewDidLoad() {
super.viewDidLoad()
setupCarousel()
}
private func setupCarousel() {
// BZVNativeAd2Pool에 광고 할당을 요청합니다.
pool.loadAds(count: adRequestCount) { [weak self] adCount in
// 실제로 할당받은 광고의 개수(adCount)를 업데이트합니다.
self?.loadedAdCount = adCount
} errorHandler: { [weak self] error in
// 광고 할당 실패 시 발생하는 NSError 오류 코드에 대한 자세한 내용은 오류 코드가 나타납니다 토픽을 참고하세요.
}
}
}
@import BuzzvilSDK;
static NSString * const kUnitId = @"YOUR_UNIT_ID";
@interface CarouselViewController ()
// 최대 10개의 광고를 요청할 수 있습니다.
@property (nonatomic, assign, readonly) NSInteger adRequestCount;
// 실제 할당받은 광고의 개수입니다.
// 이 값은 collectionView datasource의 collectionView(_:numberOfItemsInSection:) 함수의 return 값으로 사용합니다.
@property (nonatomic, assign, readwrite) NSInteger loadedAdCount;
// 광고 중복 할당을 막기 위해 하나의 캐러셀에 하나의 NativeAd2Pool 인스턴스를 생성하여 사용합니다.
@property (nonatomic, strong, readonly) BZVNativeAd2Pool *pool;
@end
@implementation CarouselViewController
- (void)viewDidLoad {
[super viewDidLoad];
_adRequestCount = 5;
_loadedAdCount = 0;
_pool = [[BZVNativeAd2Pool alloc] initWithUnitId:kUnitId];
[self setupCarousel];
}
- (void)setupCarousel {
__weak typeof(self) weakSelf = self;
// BZVNativeAd2Pool에 광고 할당을 요청합니다.
[self.pool loadAdsWithCount:self.adRequestCount completionHandler:^(NSInteger adCount) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
// 실제로 할당받은 광고의 개수(adCount)를 업데이트합니다.
strongSelf.loadedAdCount = adCount;
}
} errorHandler:^(NSError * _Nonnull error) {
// 광고 할당 실패 시 발생하는 NSError 오류 코드에 대한 자세한 내용은 오류 코드가 나타납니다 토픽을 참고하세요.
}];
}
@end
2단계. UICollectionViewCell 구현하기
기존에 구현되어있던 UICollectionViewCell에서 setPoool() 함수를 통해 구현되어 있던 부분을 bind(with native: BuzzNative)로 바꿔서 BuzzNative 객체를 UIcollectionUIViewCell에 전달하여 필요한 코드를 추가하여야 합니다.
- Swift
- Objective-C
final class CarouselCell: UICollectionViewCell {
// ...
private lazy var viewBinder = BuzzNativeViewBinder.Builder()
.nativeAdView(nativeAdView)
.mediaView(mediaView)
.iconImageView(iconImageView)
.titleLabel(titleLabel)
.descriptionLabel(descriptionLabel)
.ctaView(ctaView)
.build()
// ...
override func prepareForReuse() {
super.prepareForReuse()
// prepareForReuse 내에서 unbind를 반드시 호출하여 cell을 재사용할 때 문제가 발생하지 않게 합니다.
viewBinder.unbind()
}
// collectionView의 collectionView(_:cellForItemAt:) 시점에 호출합니다.
func bind(with native: BuzzNative) {
// bind()를 호출하면 할당된 광고 표시 및 갱신이 자동으로 수행됩니다.
viewBinder.bind(native)
}
}
@interface CarouselCell : UICollectionViewCell
- (void)bind:(BuzzNativeAd *)native;
@end
@interface CarouselCell ()
// ...
@property (nonatomic, strong, readonly) BuzzNativeViewBinder *viewBinder;
@end
@implementation CarouselCell
// ...
- (void)prepareForReuse {
[super prepareForReuse];
// prepareForReuse 내에서 unbind를 반드시 호출하여 cell을 재사용할 때 문제가 발생하지 않게 합니다.
[_viewBinder unbind];
}
// collectionView의 collectionView(_:cellForItemAt:) 시점에 호출합니다.
- (void)bind {
// bind()를 호출하면 할당된 광고 표시 및 갱신이 자동으로 수행됩니다.
[_viewBinder bindWithNative:native];
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
final class CarouselCell: UICollectionViewCell {
// ...
private lazy var viewBinder = BZVNativeAd2ViewBinder
.Builder(unitId: "YOUR_NATIVE_UNIT_ID")
.nativeAd2View(nativeAd2View)
.mediaView(mediaView)
.iconImageView(iconImageView)
.titleLabel(titleLabel)
.descriptionLabel(descriptionLabel)
.ctaView(ctaView)
.build()
// ...
override func prepareForReuse() {
super.prepareForReuse()
// prepareForReuse 내에서 unbind를 반드시 호출하여 cell을 재사용할 때 문제가 발생하지 않게 합니다.
viewBinder.unbind()
}
// collectionView의 collectionView(_:cellForItemAt:) 시점에 호출합니다.
func setPool(with pool: BZVNativeAd2Pool, for adKey: Int) {
// 해당 index(adKey)에 해당하는 NativeAd2ViewBinder가 NativeAd2Pool을 사용하도록 합니다.
viewBinder.setPool(pool, at: adKey)
}
// collectionView의 collectionView(_:cellForItemAt:) 시점에 호출합니다.
func bind() {
// NativeAd2ViewBinder의 bind()를 호출하면 광고 할당 및 갱신이 자동으로 수행됩니다.
viewBinder.bind()
}
}
@interface CarouselCell : UICollectionViewCell
- (void)setPool:(BZVNativeAd2Pool *)pool forAdKey:(NSInteger)adKey;
- (void)bind;
@end
@interface CarouselCell ()
// ...
@property (nonatomic, strong, readonly) BZVNativeAd2ViewBinder *viewBinder;
@end
@implementation CarouselCell
// ...
- (void)prepareForReuse {
[super prepareForReuse];
// prepareForReuse 내에서 unbind를 반드시 호출하여 cell을 재사용할 때 문제가 발생하지 않게 합니다.
[_viewBinder unbind];
}
// collectionView의 collectionView(_:cellForItemAt:) 시점에 호출합니다.
- (void)setPool:(BZVNativeAd2Pool *)pool forAdKey:(NSInteger)adKey {
// 해당 index(adKey)에 해당하는 NativeAd2ViewBinder가 NativeAd2Pool을 사용하도록 합니다.
[_viewBinder setPool:pool at:adKey];
}
// collectionView의 collectionView(_:cellForItemAt:) 시점에 호출합니다.
- (void)bind {
// NativeAd2ViewBinder의 bind()를 호출하면 광고 할당 및 갱신이 자동으로 수행됩니다.
[_viewBinder bind];
}
@end
베네핏허브 진입 슬라이드
기능이 삭제되어 BZVFeedPromotionView, BZVFeedPromotionViewBinder가 삭제되었습니다. 관련 코드에서 해당 코드들을 제거 해 주세요. 이전 가이드에 있던 FeedPromitionCell도 제거 해야 합니다.
베네핏허브 진입
베네핏허브 진입점으로써 활용되고 있던 BZVFeedEntryView 클래스가 삭제 되었습니다. 베네핏허브 진입을 위한 코드로 변경이 필요 합니다. 아래의 코드로 업데이트 해 주세요.
- Swift
- Objective C
let yourViewController = UIViewController()
let benefitHub = BuzzBenefitHub()
benefitHub.show(on: yourViewController)
UIViewController *yourViewController = [[UIViewController alloc] init];
BuzzBenefitHub *benefitHub = [[BuzzBenefitHub alloc] init];
[benefitHub showOn:yourViewController];
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class CarouselFeedEntryView: BZVFeedEntryView {
private lazy var button: UIButton = {
let button = UIButton(type: .system)
button.setTitle("포인트 더 받으러 가기", for: .normal)
button.tintColor = .systemBlue
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
setupLayout()
}
required init?(coder: NSCoder) {
fatalError()
}
private func setupView() {
addSubview(button)
clickableViews = [button]
}
private func setupLayout() {
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.topAnchor.constraint(equalTo: topAnchor),
button.leadingAnchor.constraint(equalTo: leadingAnchor),
button.trailingAnchor.constraint(equalTo: trailingAnchor),
button.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
}
@import UIKit;
@import BuzzvilSDK;
@interface CarouselFeedEntryView: BZVFeedEntryView
@end
@interface CarouselFeedEntryView ()
@property (nonatomic, strong, readonly) UIButton *button;
@end
@implementation CustomFeedEntryView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setupView];
[self setupLayout];
}
return self;
}
- (void)setupView {
_button = [[UIButton alloc] initWithFrame:CGRectZero];
[_button setTitle:@"포인트 더 받으러 가기" forState:UIControlStateNormal];
[_button setTitleColor:[UIColor systemBlueColor] forState:UIControlStateNormal];
[self addSubview:_button];
self.clickableViews = @[self.button];
}
- (void)setupLayout {
_button.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[_button.topAnchor constraintEqualToAnchor:self.topAnchor],
[_button.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
[_button.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
[_button.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
]];
}
@end
캐러셀의 부가 기능 구현하기
로딩 화면 구현하기
분리되어있던 함수가 UICollectionViewCell에서 만든 bind(with native: BuzzNative) 함수 안으로 이동 되었습니다.
- Swift
- Objective-C
final class CarouselCell: UICollectionViewCell {
// ...
private lazy var activityIndicatorView: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(frame: .zero)
indicator.hidesWhenStopped = true
return indicator
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
setupLayout()
}
private func setupView() {
// ...
contentView.addSubview(activityIndicatorView)
}
private func setupLayout() {
// ...
activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor),
activityIndicatorView.centerYAnchor.constraint(equalTo: centerYAnchor),
])
}
func bind(with native: BuzzNative) {
native.subscribeRefreshEvents(
onRequest: { [weak self] in
self?.activityIndicatorView.startAnimating()
self?.nativeAdView.alpha = 0.5
},
onSuccess: { [weak self] _ in
self?.activityIndicatorView.stopAnimating()
self?.nativeAdView.alpha = 1
},
onFailure: { [weak self] error in
self?.activityIndicatorView.stopAnimating()
self?.nativeAdView.alpha = 1
},
)
viewBinder.bind(native: native)
}
}
extension CarouselViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// ...
cell.bind(with: native)
return cell
}
}
@interface CarouselCell ()
// ...
@property (nonatomic, strong, readonly) UIActivityIndicatorView *activityIndicatorView;
@end
@implementation CarouselCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupView];
[self setupLayout];
}
return self;
}
- (void)setupView {
// ...
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero];
_activityIndicatorView.hidesWhenStopped = YES;
[self.contentView addSubview:_activityIndicatorView];
}
- (void)setupLayout {
// ...
_activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[_activityIndicatorView.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],
[_activityIndicatorView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
]];
}
- (void)bindWithNative:(BuzzNative *)native {
__weak typeof(self) weakSelf = self;
[_native subscribeRefreshEventsOnRequest:^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView startAnimating];
strongSelf.nativeAdView.alpha = 0.5;
}
} onSuccess:^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView stopAnimating];
strongSelf.nativeAdView.alpha = 1;
}
} onFailure:^(NSError * _Nonnull error) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView stopAnimating];
strongSelf.nativeAdView.alpha = 1;
}
}];
}
@end
@implementation CarouselViewController
// ...
#pragma mark - UICollectionViewDataSource
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// ...
[cell bindWithNative:native];
return cell;
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
final class CarouselCell: UICollectionViewCell {
// ...
private lazy var activityIndicatorView: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(frame: .zero)
indicator.hidesWhenStopped = true
return indicator
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
setupLayout()
}
private func setupView() {
// ...
contentView.addSubview(activityIndicatorView)
}
private func setupLayout() {
// ...
activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor),
activityIndicatorView.centerYAnchor.constraint(equalTo: centerYAnchor),
])
}
func setupLoading() {
viewBinder.subscribeEvents(onRequest: { [weak self] in
self?.activityIndicatorView.startAnimating()
self?.nativeAd2View.alpha = 0.5
}, onNext: { [weak self] _ in
self?.activityIndicatorView.stopAnimating()
self?.nativeAd2View.alpha = 1
}, onError: { [weak self] in
self?.activityIndicatorView.stopAnimating()
self?.nativeAd2View.alpha = 1
print("error: \($0)")
}, onCompleted: { [weak self] in
self?.activityIndicatorView.stopAnimating()
self?.nativeAd2View.alpha = 1
print("completed")
})
}
}
extension CarouselViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// ...
cell.setupLoading()
cell.setPool(with: pool, for: indexPath.item)
cell.bind()
return cell
}
}
@interface CarouselCell : UICollectionViewCell
// ...
- (void)setupLoading
@end
@interface CarouselCell ()
// ...
@property (nonatomic, strong, readonly) UIActivityIndicatorView *activityIndicatorView;
@end
@implementation CarouselCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupView];
[self setupLayout];
}
return self;
}
- (void)setupView {
// ...
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero];
_activityIndicatorView.hidesWhenStopped = YES;
[self.contentView addSubview:_activityIndicatorView];
}
- (void)setupLayout {
// ...
_activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[_activityIndicatorView.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],
[_activityIndicatorView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
]];
}
- (void)setupLoading {
__weak typeof(self) weakSelf = self;
[_viewBinder subscribeEventsOnRequest:^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView startAnimating];
strongSelf.nativeAd2View.alpha = 0.5;
}
} onNext:^(BZVNativeAd2 * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView stopAnimating];
strongSelf.nativeAd2View.alpha = 1;
}
} onError:^(NSError * _Nonnull error) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView stopAnimating];
strongSelf.nativeAd2View.alpha = 1;
NSLog(@"error: %@", error);
}
} onCompleted:^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.activityIndicatorView stopAnimating];
strongSelf.nativeAd2View.alpha = 1;
NSLog(@"completed");
}
}];
}
@end
@implementation CarouselViewController
// ...
#pragma mark - UICollectionViewDataSource
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// ...
[cell setupLoading];
[cell setPool:_pool forIndex:indexPath.item];
[cell bind];
return cell;
}
@end
광고 이벤트 리스너 등록하기
함수 변경 ! 위치도 변경 ! bind() 안에 있음
분리되어있던 함수가 UICollectionViewCell에서 만든 bind(with native: BuzzNative) 함수 안으로 이동 되었습니다. 기존에 사용하던 BZVNativeAd2ViewBinder class 가 아닌 BuzzNative 객체를 통해서 등록하도록 변경 되었습니다.
- Swift
- Objective-C
final class CarouselCell: UICollectionViewCell {
// ...
func bind(with native: BuzzNative) {
// ...
native.subscribeAdEvents(
onImpressed: { [weak self] in
print("impressed: \($0.title)")
},
onClicked: { [weak self] in
print("clicked: \($0.title)")
},
onRewardRequested: { [weak self] in
print("requested reward: \($0.title)")
},
onRewarded: { [weak self] in
print("received reward result: \($0.title), \($1)")
},
onParticipated: { [weak self] in
print("participated: \($0.title)")
}
)
// ...
}
}
extension CarouselViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// ...
cell.bind(with: native)
return cell
}
}
@implementation CarouselCell
// ...
- (void)bindWithNative:(BuzzNative *)native {
__weak typeof(self) weakSelf = self;
[native subscribeAdEventsOnImpressed:^(BuzzNativeAd * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"impressed: %@", ad.title);
}
} onClicked:^(BuzzNativeAd * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"clicked: %@", ad.title);
}
} onRewardRequested:^(BuzzNativeAd * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"requested reward: %@", ad.title);
}
} onRewarded:^(BuzzNativeAd * _Nonnull ad, BuzzRewardResult result) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"received reward result: %@", ad.title);
}
} onParticipated:^(BuzzNativeAd * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"participated: %@", ad.title);
}
}];
}
@end
@implementation CarouselViewController
// ...
#pragma mark - UICollectionViewDataSource
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// ...
[cell bindWithNative:native];
return cell;
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
final class CarouselCell: UICollectionViewCell {
// ...
func setupEventListeners() {
viewBinder.subscribeAdEvents(onImpressed: { [weak self] in
print("impressed: \($0.title)")
}, onClicked: { [weak self] in
print("clicked: \($0.title)")
}, onRewardRequested: { [weak self] in
print("requested reward: \($0.title)")
}, onRewarded: { [weak self] in
print("received reward result: \($0.title), \($1)")
}, onParticipated: { [weak self] in
print("participated: \($0.title)")
})
}
}
extension CarouselViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// ...
cell.setupEventListeners()
cell.setPool(with: pool, for: indexPath.item)
cell.bind()
return cell
}
}
@interface CarouselCell : UICollectionViewCell
// ...
- (void)setupEventListeners;
@end
@implementation CarouselCell
// ...
- (void)setupEventListeners {
__weak typeof(self) weakSelf = self;
[_viewBinder subscribeAdEventsOnImpressed:^(BZVNativeAd2 * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"impressed: %@", ad.title);
}
} onClicked:^(BZVNativeAd2 * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"clicked: %@", ad.title);
}
} onRewardRequested:^(BZVNativeAd2 * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"requested reward: %@", ad.title);
}
} onRewarded:^(BZVNativeAd2 * _Nonnull ad, BZVRewardResult result) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"received reward result: %@", ad.title);
}
} onParticipated:^(BZVNativeAd2 * _Nonnull ad) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"participated: %@", ad.title);
}
}];
}
@end
@implementation CarouselViewController
// ...
#pragma mark - UICollectionViewDataSource
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// ...
[cell setupEventListeners];
[cell setPool:_pool forIndex:indexPath.item];
[cell bind];
return cell;
}
@end
인터스티셜(Interstitial)
연동
1 단계. 준비하기
변경 사항이 없습니다.
2 단계. 광고 할당 및 표시하기
기존에 사용하던 Class 의 이름 및 프로토콜이 변경 되었습니다. 아래를 참고하시어 코드를 업데이트 해 주세요.
기존 Interstitial 객체 BZVBuzzAdInterstitial -> BuzzInterstitial 변경
BuzzInterstitial의 초기화이 방식 변경 되었습니다. 아래의 코드를 참고하여 업데이트 해 주세요.
기존 Delegate protocol BZVBuzzAdInterstitialDelegate -> ~BuzzInterstitialDelegate` 변경
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class ViewController: UIViewController, BuzzInterstitialDelegate {
let buzzAdInterstitial = BuzzInterstitial(unitId: "YOUR_INTERSTITIAL_UNIT_ID", type: .dialog)
override func viewDidLoad() {
super.viewDidLoad()
buzzAdInterstitial.delegate = self
buzzAdInterstitial.load()
}
}
extension ViewController: BuzzInterstitialDelegate {
func BuzzInterstitialDidLoadAd(_ interstitial: BuzzInterstitial) {
// 할당된 광고가 있으면 호출됩니다.
// Interstitial 광고를 화면에 표시합니다.
interstitial.present(on: self)
}
func BuzzInterstitialDidFail(toLoadAd interstitial: BuzzInterstitial, withError error: Error) {
// 할당된 광고가 없으면 호출됩니다.
}
func BuzzInterstitialDidDismiss(_ viewController: UIViewController) {
// Interstitial 지면이 종료되면 호출됩니다.
// 필요에 따라 추가 기능을 구현하세요.
}
}
@import BuzzvilSDK;
@interface ViewController () <BuzzInterstitialDelegate>
@property (nonatomic, strong, readonly) BuzzInterstitial *buzzAdInterstitial;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_buzzAdInterstitial = [[BuzzInterstitial alloc] initWithUnitId:@"YOUR_INTERSTITIAL_UNIT_ID" type:BuzzInterstitialTypeDialog];
_buzzAdInterstitial.delegate = self;
[_buzzAdInterstitial load];
}
#pragma mark - BuzzInterstitialDelegate
- (void)BuzzInterstitialDidLoadAd:(BuzzInterstitial *)interstitial {
// 할당된 광고가 있으면 호출됩니다.
// Interstitial 광고를 화면에 표시합니다.
[interstitial presentOnViewController:self];
}
- (void)BuzzInterstitialDidFailToLoadAd:(BuzzInterstitial *)interstitial withError:(NSError *)error {
// 할당된 광고가 없으면 호출됩니다.
}
- (void)BuzzInterstitialDidDismiss:(UIViewController *)viewController {
// Interstitial 지면이 종료되면 호출됩니다.
// 필요에 따라 추가 기능을 구현하세요.
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class ViewController: UIViewController, BZVBuzzAdInterstitialDelegate {
let buzzAdInterstitial = BZVBuzzAdInterstitial { builder in
builder.unitId = "YOUR_INTERSTITIAL_UNIT_ID"
builder.type = .dialog
}
override func viewDidLoad() {
super.viewDidLoad()
buzzAdInterstitial.delegate = self
buzzAdInterstitial.load()
}
}
extension ViewController: BZVBuzzAdInterstitialDelegate {
func bzvBuzzAdInterstitialDidLoadAd(_ interstitial: BZVBuzzAdInterstitial) {
// 할당된 광고가 있으면 호출됩니다.
// Interstitial 광고를 화면에 표시합니다.
interstitial.present(on: self)
}
func bzvBuzzAdInterstitialDidFail(toLoadAd interstitial: BZVBuzzAdInterstitial, withError error: Error) {
// 할당된 광고가 없으면 호출됩니다.
}
func bzvBuzzAdInterstitialDidDismiss(_ viewController: UIViewController) {
// Interstitial 지면이 종료되면 호출됩니다.
// 필요에 따라 추가 기능을 구현하세요.
}
}
@import BuzzvilSDK;
@interface ViewController () <BZVBuzzAdInterstitialDelegate>
@property (nonatomic, strong, readonly) BZVBuzzAdInterstitial *buzzAdInterstitial;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_buzzAdInterstitial = [BZVBuzzAdInterstitial interstitialWithBlock:^(BZVBuzzAdInterstitialBuilder * _Nonnull builder) {
builder.unitId = @"YOUR_INTERSTITIAL_UNIT_ID";
builder.type = BZVBuzzAdInterstitialTypeDialog;
}];
_buzzAdInterstitial.delegate = self;
[_buzzAdInterstitial load];
}
#pragma mark - BZVBuzzAdInterstitialDelegate
- (void)BZVBuzzAdInterstitialDidLoadAd:(BZVBuzzAdInterstitial *)interstitial {
// 할당된 광고가 있으면 호출됩니다.
// Interstitial 광고를 화면에 표시합니다.
[interstitial presentOnViewController:self];
}
- (void)BZVBuzzAdInterstitialDidFailToLoadAd:(BZVBuzzAdInterstitial *)interstitial withError:(NSError *)error {
// 할당된 광고가 없으면 호출됩니다.
}
- (void)BZVBuzzAdInterstitialDidDismiss:(UIViewController *)viewController {
// Interstitial 지면이 종료되면 호출됩니다.
// 필요에 따라 추가 기능을 구현하세요.
}
@end
3 단계. 인터스티셜에 베네핏허브 진입점 추가하기
Intersitial 에서 베네핏허브로 갈 수 있는 버튼을 추가하는 옵션이 변경 되었습니다.
더이상 옵션이 제공되는 형태가 아닌 진입점이 항상 보이는 형태로 업데이트 되었습니다. 기존의 buzzAdBenefitRouter 관련 코드가 삭제 되어야 합니다.
- Swift
- Objective-C
let feedConfig = BZVFeedConfig { builder in
builder.unitID = "YOUR_FEED_UNIT_ID"
}
let buzzAdInterstitial = BZVBuzzAdInterstitial { builder in
builder.unitId = "YOUR_INTERSTITIAL_UNIT_ID"
builder.type = .dialog
builder.buzzAdBenefitRouter = BuzzBenefitRouterFactory.createFeedRouter(feedConfig) // 삭제 처리
}
BZVFeedConfig *feedConfig = [BZVFeedConfig configWithBlock:^(BZVFeedConfigBuilder * _Nonnull builder) {
builder.unitID = @"YOUR_FEED_UNIT_ID";
}];
BZVBuzzAdInterstitial *buzzAdInterstitial = [BZVBuzzAdInterstitial interstitialWithBlock:^(BZVBuzzAdInterstitialBuilder * _Nonnull builder) {
builder.unitId = @"YOUR_INTERSTITIAL_UNIT_ID";
builder.type = BZVBuzzAdInterstitialTypeDialog;
builder.buzzAdBenefitRouter = [BuzzBenefitRouterFactory createFeedRouter:feedConfig];
}];
버즈배너 (BuzzBanner)
기존에 제공하던 클래스들의 이름이 변경 되었습니다. 아래를 확인하여 적절하게 변환해야 합니다.
| AS-IS | TO-BE |
|---|---|
| BuzzAdBenefitBannerView | BuzzBannerSize |
| BuzzAdBenefitBannerSize | BuzzBannerView |
| BuzzAdBenefitBannerViewDelegate | BuzzBannerViewDelegate |
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class ViewController: UIViewController {
private lazy var bannerView: BuzzBannerView = {
let bannerView = BuzzBannerView(frame: .zero)
bannerView.delegate = self
return bannerView
}()
override func viewDidLoad() {
super.viewDidLoad()
let config = BuzzBannerConfig.Builder(placementId: placementID)
.setSize(.w320h50)
.build()
bannerView.setConfig(rootViewController: self, config: config)
view.addSubview(bannerView)
// ...
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
bannerView.requestAd()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
bannerView.removeAd()
}
}
extension ViewController: BuzzBannerViewDelegate {
func bannerView(_ bannerView: BuzzBannerView, didLoadApid: String) {
// Banner에 광고가 할당 되었을 때 호출 됩니다.
}
func bannerView(_ bannerView: BuzzBannerView, didFailApid: String, error: NSError) {
// Banner에 광고 할당이 실패했을 때 호출 됩니다.
}
func bannerView(_ bannerView: BuzzBannerView, didClickApid: String) {
// Banner가 클릭되었을 때 호출 됩니다.
}
func bannerView(_ bannerView: BuzzBannerView, didRemoveApid: String) {
// Banner가 제거되었을 떄 호출 됩니다.
}
}
@import BuzzvilSDK;
@interface ViewController () <BuzzBannerViewDelegate>
@property (nonatomic, strong, readonly) BuzzBannerView *bannerView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupView];
}
- (void)setupView {
BuzzBannerConfig * config = [BuzzBannerConfig configWith:^(BuzzBannerConfigBuilder * _Nonnull builder) {
builder.placementId = @"YOUR_PLCEMENT_ID";
builder.size = BuzzBannerSizeW320h50;
}];
_bannerView = [[BuzzBannerView alloc] initWithFrame:CGRectZero];
[_bannerView setConfigWithRootViewController:self config:config];
[self.view addSubview:_bannerView];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[_bannerView requestAd];
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[_bannerView removeAd];
}
#pragma mark - BuzzBannerViewDelegate
- (void)bannerView:(BuzzBannerView * _Nonnull)bannerView didClickApid:(NSString * _Nonnull)didClickApid {
// Banner에 광고가 할당 되었을 때 호출 됩니다.
}
- (void)bannerView:(BuzzBannerView * _Nonnull)bannerView didFailApid:(NSString * _Nonnull)didFailApid error:(NSError * _Nonnull)error {
// Banner에 광고 할당이 실패했을 때 호출 됩니다.
}
- (void)bannerView:(BuzzBannerView * _Nonnull)bannerView didLoadApid:(NSString * _Nonnull)didLoadApid {
// Banner가 클릭되었을 때 호출 됩니다.
}
- (void)bannerView:(BuzzBannerView * _Nonnull)bannerView didRemoveApid:(NSString * _Nonnull)didRemoveApid {
// Banner가 제거되었을 떄 호출 됩니다.
}
@end
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class ViewController: UIViewController {
private lazy var bannerView: BuzzAdBenefitBannerView = {
let bannerView = BuzzAdBenefitBannerView(frame: .zero)
bannerView.delegate = self
return bannerView
}()
override func viewDidLoad() {
super.viewDidLoad()
let config = BuzzAdBenefitBannerConfig.Builder(placementID: placementID)
.setSize(.w320h50)
.build()
bannerView.setConfig(rootViewController: self, config: config)
view.addSubview(bannerView)
// ...
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
bannerView.requestAd()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
bannerView.removeAd()
}
}
extension ViewController: BuzzAdBenefitBannerViewDelegate {
func bannerView(_ bannerView: BuzzAdBenefitBannerView, didLoadApid: String) {
// Banner에 광고가 할당 되었을 때 호출 됩니다.
}
func bannerView(_ bannerView: BuzzAdBenefitBannerView, didFailApid: String, error: NSError) {
// Banner에 광고 할당이 실패했을 때 호출 됩니다.
}
func bannerView(_ bannerView: BuzzAdBenefitBannerView, didClickApid: String) {
// Banner가 클릭되었을 때 호출 됩니다.
}
func bannerView(_ bannerView: BuzzAdBenefitSDK.BuzzAdBenefitBannerView, didRemoveApid: String) {
// Banner가 제거되었을 떄 호출 됩니다.
}
}
@import BuzzvilSDK;
@interface ViewController () <BuzzAdBenefitBannerViewDelegate>
@property (nonatomic, strong, readonly) BuzzAdBenefitBannerView *bannerView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupView];
}
- (void)setupView {
BuzzAdBenefitBannerConfig * config = [BuzzAdBenefitBannerConfig configWithBlock:^(BuzzAdBenefitBannerConfigBuilder * _Nonnull builder) {
builder.placementID = @"YOUR_PLACEMENT_ID";
builder.size = BuzzAdBenefitBannerSizeW320h50;
}];
_bannerView = [[BuzzAdBenefitBannerView alloc] initWithFrame:CGRectZero];
[_bannerView setConfigWithRootViewController:self config:config];
[self.view addSubview:_bannerView];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[_bannerView requestAd];
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[_bannerView removeAd];
}
#pragma mark - BuzzAdBenefitBannerViewDelegate
- (void)bannerView:(BuzzAdBenefitBannerView * _Nonnull)bannerView didClickApid:(NSString * _Nonnull)didClickApid {
// Banner에 광고가 할당 되었을 때 호출 됩니다.
}
- (void)bannerView:(BuzzAdBenefitBannerView * _Nonnull)bannerView didFailApid:(NSString * _Nonnull)didFailApid error:(NSError * _Nonnull)error {
// Banner에 광고 할당이 실패했을 때 호출 됩니다.
}
- (void)bannerView:(BuzzAdBenefitBannerView * _Nonnull)bannerView didLoadApid:(NSString * _Nonnull)didLoadApid {
// Banner가 클릭되었을 때 호출 됩니다.
}
- (void)bannerView:(BuzzAdBenefitBannerView * _Nonnull)bannerView didRemoveApid:(NSString * _Nonnull)didRemoveApid {
// Banner가 제거되었을 떄 호출 됩니다.
}
@end
UI 설정
기존에 제공하뎐 Theme 관련 코드는 대부분 사라지고 CTA 버튼 자체 구현만 남아있습니다. 다른 색상관련 코드는 삭제처리가 필요합니다. 주요 색상을 설정하기 위해서는 버즈빌 담당자(help@buzzvil.com)을 통해 서버설정으로 설정할 수 있습니다.
CTA 버튼 자체 구현
CTA 버튼 자체 구현 시 필요 한 프로토콜 이름이 변경 되었습니다.
BZVCtaViewProtocol -> BuzzCtaViewProtocol
- Swift
- Objective-C
// MARK: BZVCtaViewProtocol
protocol BZVCtaViewProtocol {
// 리워드가 없는 광고에 대한 CTA 뷰 레이아웃을 정의합니다.
func renderRewardNotAvailableViewState(withCtaText ctaText: String)
// 리워드가 있는 광고에 대한 CTA 뷰 레이아웃을 정의합니다.
func renderRewardAvailableViewState(withCtaText ctaText: String, reward: Int)
// 참여 확인 중인 광고에 대한 CTA 뷰 레이아웃을 정의합니다.
func renderParticipatingViewState(withCtaText ctaText: String)
// 참여 완료한 광고에 대한 CTA 뷰 레이아웃을 정의합니다.
func renderParticipatedViewState(withCtaText ctaText: String)
}
@objc
public protocol BuzzCtaViewProtocol: AnyObject {
@objc
func renderParticipatingViewState(ctaText: String)
@objc
func renderParticipatedViewState(ctaText: String)
@objc
func renderRewardAvailableViewState(ctaText: String, reward: Int)
@objc
func renderRewardNotAvailableViewState(ctaText: String)
}
자체 구현 인앱 브라우저
해당 버전에서는 자체 구현 인앱 브라우저를 지원하지 않습니다.
이전에 제공하던 BuzzAdBrowser, BZVLauncher, BZVLauncherDelegate 관련 코드가 삭제되어야 합니다
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
final class CustomBrowserViewController: UIViewController {
private lazy var browserViewController: UIViewController = {
BuzzAdBrowser.sharedInstance().browserViewController()
}()
override func viewDidLoad() {
super.viewDidLoad()
displayContentViewController(browserViewController)
}
private func displayContentViewController(_ contentViewController: UIViewController) {
addChild(contentViewController)
contentViewController.view.frame = view.bounds
view.addSubview(contentViewController.view)
contentViewController.didMove(toParent: self)
}
}
@interface CustomBrowserViewController: UIViewController
@end
@interface CustomBrowserViewController ()
@property (nonatomic, strong, readonly) UIViewController *browserViewController;
@end
@implementation CustomBrowserViewController
- (void)viewDidLoad {
[super viewDidLoad];
_browserViewController = [BuzzAdBrowser.sharedInstance browserViewController];
[self displayContentViewController:_browserViewController];
}
- (void)displayContentViewController:(UIViewController *)contentViewController {
[self addChildViewController:contentViewController];
contentViewController.view.frame = self.view.bounds;
[self.view addSubview:contentViewController.view];
[contentViewController didMoveToParentViewController:self];
}
@end
- Swift
- Objective-C
import Foundation
import BuzzvilSDK
final class CustomLauncher: NSObject, BZVLauncher {
// 런처와 관련된 이벤트를 수신할 수 있습니다.
var delegate: BZVLauncherDelegate?
func open(with launchInfo: BZVLaunchInfo) {
// launchInfo의 인자를 확인하여 광고 또는 콘텐츠인지 미리 판단할 수 있습니다.
if let ad = launchInfo.ad {
if ad.isDeepLink {
// 딥링크 광고일 경우 필요한 작업을 할 수 있습니다.
}
} else if let article = launchInfo.article {
let sourceURL = article.sourceURL
}
let customBrowserViewController = CustomBrowserViewController()
YOUR_ROOT_VIEW_CONTROLLER.presentedViewController?.present(customBrowserViewController, animated: true, completion: nil)
}
}
@import BuzzvilSDK;
@interface CustomLauncher : NSObject <BZVLauncher>
// 런처와 관련된 이벤트를 수신할 수 있습니다.
@property (nonatomic, weak, readwrite, nullable) id<BZVLauncherDelegate> delegate;
@end
@implementation CustomLauncher
- (void)openWithLaunchInfo:(BZVLaunchInfo *)launchInfo {
// launchInfo의 인자를 확인하여 광고 또는 콘텐츠인지 미리 판단할 수 있습니다.
if (launchInfo.ad != nil) {
if (launchInfo.ad.isDeepLink) {
// 딥링크 광고일 경우 필요한 작업을 할 수 있습니다.
}
} else if (launchInfo.article != nil){
NSString *sourceURL = launchInfo.article.sourceURL;
}
// Custom Browser 실행
CustomBrowserViewController *customBrowserViewController = [[CustomBrowserViewController alloc] init];
[YOUR_ROOT_VIEW_CONTROLLER.presentedViewController presentViewController:customBrowserViewController animated:YES completion:nil];
}
@end
- Swift
- Objective-C
let launcher = CustomLauncher()
BuzzAdBenefit.setLauncher(launcher)
CustomLauncher *launcher = [[CustomLauncher alloc] init];
[BuzzAdBenefit setLauncher:launcher];
개인정보 처리방침 동의하기
개인정보 처리방침에 대한 동의 여부와 동의를 하기 위한 함수가 변경 되었습니다.
| 상태값 | enum |
|---|---|
| 동의 | BuzzPrivacyConsentStatus.granted |
| 거부 | BuzzPrivacyConsentStatus.revoked |
- Swift
- Objective-C
BuzzAdBenefit.shared.loadPrivacyConsentStatus(onSuccess: { [weak self] status in
// 현재 개인정보 처리 방침 상태를 가져올 수 있습니다
}, onFailure: { [weak self] error in
// 개인정보 처리방침에 대한 상태를 가져오는데 실패 했을 경우 호출 됩니다.
})
BuzzAdBenefit.shared.grantPrivacyConsent(onSuccess: { [weak self] in
// 개인정보 처리방침 동의에 성공했을 경우 호출 됩니다.
}, onFailure: { [weak self] error in
// 개인정보 처리방침 동의 요청에 실패했을 경우 호출 됩니다.
})
[BuzzAdBenefit.sharedInstance loadPrivacyConsentStatusOnSuccess:^(enum BuzzPrivacyConsentStatus status) {
// 현재 개인정보 처리 방침 상태를 가져올 수 있습니다
} onFailure:^(NSError * _Nonnull error) {
// 개인정보 처리방침에 대한 상태를 가져오는데 실패 했을 경우 호출 됩니다.
}];
[BuzzAdBenefit.sharedInstance grantPrivacyConsentOnSuccess:^{
// 개인정보 처리방침 동의에 성공했을 경우 호출 됩니다.
} onFailure:^(NSError * _Nonnull error) {
// 개인정보 처리방침 동의 요청에 실패했을 경우 호출 됩니다.
}];
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
let privacyPolicyManager = BuzzAdBenefit.privacyPolicyManager
// 직접 구현한 개인정보 제3자 제공 동의 UI에서 동의를 받았을 경우 아래 코드를 실행하면, 피드 화면에서 개인정보 제3자 제공 동의 UI가 노출되지 않으면서 광고 할당이 정상적으로 진행 됩니다.
// 아래의 코드를 실행하지 않을 경우 피드 진입 시 개인정보 제3자 제공 동의 UI가 노출되기 때문에 필수적으로 실행이 필요합니다.
privacyPolicyManager.grantConsent()
// 아래 코드를 통해서 수집 동의를 철회할 수 있습니다. 이 코드가 실행되면 피드에서 광고 할당이 이루어지지 않습니다.
privacyPolicyManager.revokeConsent()
BZVPrivacyPolicyManager *privacyPolicyManager = [BuzzAdBenefit privacyPolicyManager];
// 직접 구현한 개인정보 제3자 제공 동의 UI 에서 동의를 받았을 경우 아래 코드를 실행하면, 피드 화면에서 개인정보 제3자 제공 동의 UI가 노출되지 않으면서 광고 할당이 정상적으로 진행 됩니다.
// 아래의 코드를 실행하지 않을 경우 피드 진입 시 개인정보 제3자 제공 동의 UI가 노출되기 때문에 필수적으로 실행이 필요합니다.
[privacyPolicyManager grantConsent];
// 아래 코드를 통해서 수집 동의를 철회할 수 있습니다. 이 코드가 실행되면 피드에서 광고 할당이 이루어지지 않습니다.
[privacyPolicyManager revokeConsent];
미션팩
기존에 단독으로 제공하던 BuzzAdMissionPack 클래스가 삭제되고 BuzzBenefitHub 로 통합 되었습니다. 관련 코드 삭제가 필요합니다.
참고 - 변경 전 코드(BuzzAdBenefit SDK v5)
- Swift
- Objective-C
import UIKit
import BuzzvilSDK
class MissionPackViewController: UIViewController {
let missionPack = BuzzAdBenefitMissionPack(unitId: "YOUR_MISSION_PACK_UNIT_ID")
override func viewDidLoad() {
super.viewDidLoad()
showMissionPack()
}
// missionPack 사용가능한지 체크하기
func checkCanOpenMissionPack() {
missionPack.canOpen {
print ("MissionPack Can open !")
} onFailure: { error in
print ("MissionPack Can't open error: \(error.localizedDescription)")
}
}
// missionPack 화면에 표시하기
func showMissionPack() {
missionPack.show(on: self, onFailure: { error in
print ("MissionPack Can't open error: \(error.localizedDescription)")
})
}
}
@import BuzzvilSDK;
#import "MissionPackViewController.h"
@interface MissionPackViewController()
@property (nonatomic, strong, readonly) BuzzAdBenefitMissionPack * missionPack;
@end
@implementation MissionPackViewController
- (void)viewDidLoad {
[super viewDidLoad];
_missionPack = [[BuzzAdBenefitMissionPack alloc] initWithUnitId:@"YOUR_MISSION_PACK_UNIT_ID"];
}
- (void)checkCanOpenMissionPack {
[_missionPack canOpenOnSuccess:^{
// missionPack 이 열릴 수 있을 때 호출 됩니다.
} onFailure:^(NSError * _Nonnull error) {
// missionPack 이 열릴 수 없을 때 호출 됩니다.
}];
}
- (void)showMissionPack {
[_missionPack showOn:self onFailure:^(NSError * _Nonnull error) {
// missionPack 이 열릴 수 없을 때 호출 됩니다.
}];
}
@end