본문으로 건너뛰기

고급 설정

이 페이지에서는 피드 지면에서 구현할 수 있는 기능과 각 기능의 설정을 변경하는 방법을 확인할 수 있습니다.

지면 상의 기능을 변경하거나 구현하려면 SDK에서 제공하는 기본 UI를 사용하거나 직접 클래스를 구현해야 합니다. 피드를 구성하는 주요 기능들은 아래 그림과 같습니다.

✏️  참고
BZVFeedViewController의 UI를 변경하려면 디자인 커스터마이징 토픽을 참고하세요.

하위 뷰 컨트롤러로 피드 연동하기

더 다양한 연동 방식을 제공하기 위해 BuzzAd iOS용 SDK는 피드 지면을 제공하는 기본 방식인 present, push 외에도 하위 뷰 컨트롤러를 통한 연동을 지원합니다.

하위 뷰 컨트롤러로 피드 지면을 연동하려면, 상위 뷰 컨트롤러에 하위 뷰 컨트롤러를 추가하세요.

다음은 하위 뷰 컨트롤러로 피드 지면을 추가하여 연동하는 예시입니다.

import BuzzAdBenefit

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)
}
}

광고 분류 기능

피드 광고 분류 기능은 탭과 필터 UI를 사용하여 유형 별로 분류된 광고를 사용자에게 보여주는 기능입니다. 탭과 필터 기능을 사용하면 사용자가 참여하고 싶은 유형의 광고만 볼 수 있어 사용자의 광고 참여 경험과 광고 효율을 높일 수 있습니다.

광고 분류 기능에 대한 설정은 앱에서 코드를 수정하거나 재배포하지 않고 변경할 수 있습니다. 설정을 변경하려면 버즈빌 담당자에게 연락하세요.

광고 분류 탭과 필터

탭의 갯수, 탭의 이름, 탭으로 모아서 게재할 광고 유형을 설정할 수 있습니다. 탭은 최대 3개까지 설정할 수 있으며, 초기에는 광고 적립, 쇼핑 적립 탭이 설정됩니다. 이 중에서 광고 적립 탭에는 쇼핑 광고를 제외한 나머지 유형의 광고가 노출되며, 쇼핑 적립 탭에는 쇼핑 광고가 노출됩니다.

탭으로 분류할 수 있는 광고의 유형은 노출형 광고, 참여형 광고, 비디오 광고, 소셜 미디어 광고, 쇼핑 광고입니다. 각 탭은 한 개 이상의 광고 유형으로 구성할 수 있습니다. 단, 쇼핑 광고의 경우 다른 광고 유형과 함께 탭으로 구성할 수 없습니다.

탭이 여러 개의 광고 유형으로 구성되면 ‘클릭하기’, ‘참여하기’ 등 광고 유형을 세분화하는 필터 UI가 노출됩니다.

무한 스크롤 기능

피드 무한 스크롤 기능은 사용자가 피드에 진입해 할당된 광고 목록을 끝까지 스크롤 해 더 이상 볼 수 있는 광고가 없으면 자동으로 추가 광고를 할당해 기능입니다. 이 기능은 기본적으로 활성화되어 있으며, 앱에서 코드를 수정하거나 재배포를 하지 않고 무한 스크롤 기능의 활성화 여부를 설정할 수 있습니다. 설정을 변경하려면 버즈빌 담당자에게 연락하세요.

헤더 영역 자체 구현하기

피드 헤더 영역을 자유롭게 활용할 수 있습니다. 예를 들어, 피드 지면을 설명하는 공간으로 활용하거나 적립 가능한 금액을 표시할 수도 있습니다.

다음은 헤더 영역을 변경하는 예시입니다.

BZVFeedHeaderViewHolder를 상속하는 클래스를 생성하고 Custom View를 헤더 영역에 구현합니다. 그리고 BZVFeedConfigheaderViewHolderClass 속성에 새로 구현한 클래스를 추가합니다.

final class CustomHeaderViewHolder: BZVFeedHeaderViewHolder {
let headerLabel = UILabel(frame: .zero)

override class func desiredHeight() -> CGFloat {
return 100.0
}

required init?(coder: NSCoder) {
super.init(coder: coder)
setUpView()
}

override init(frame: CGRect) {
super.init(frame: frame)
setUpView()
}

func setUpView() {
addSubview(headerLabel)

// LayoutConstraint 설정
...
}

override func availableRewardDidUpdate(_ reward: Int) {
headerLabel.text = "리워드 \(reward)원"
}
}
let config = BZVFeedConfig { builder in
builder.unitId = "YOUR_FEED_UNIT_ID"
builder.headerViewHolderClass = CustomHeaderViewHolder.self
}

기본 적립 포인트 알림 팝업 자체 구현하기

사용자가 광고에 참여하지 않아도 피드에 접근하면 일정 주기마다 포인트를 지급합니다. 기본 포인트 지급 알림 팝업을 직접 구현하고 디자인을 변경하여 사용자 경험을 개선할 수 있습니다.

 중요
이 기능은 BuzzAd iOS용 SDK v3.2.x부터 추가되었습니다. v3.2.x 미만의 버전을 연동한 경우 이 기능을 탑재하려면 v3.2.x 이상으로 업데이트하세요.

다음은 기본 적립 포인트 지급 알림 팝업을 직접 구현하는 예시입니다.

  1. BZVFeedBaseRewardViewHolder를 상속하는 클래스를 생성하세요.
final class CustomFeedBaseRewardViewHolder: BZVFeedBaseRewardViewHolder {
let baseRewardLabel = UILabel(frame: .zero)

override class func desiredHeight() -> CGFloat {
return 100.0
}

required init?(coder: NSCoder) {
super.init(coder: coder)
setUpView()
}

override init(frame: CGRect) {
super.init(frame: frame)
setUpView()
}

func setUpView() {
addSubview(baseRewardLabel)

// LayoutConstraint 설정
...
}

override func didUpdateBaseReward(_ baseReward: Int) {
baseRewardLabel.text = "Received \(baseReward) points"
}
}
  1. 이전 단계에서 생성한 CustomFeedBaseRewardViewHolderBZVFeedConfig에 설정하세요.
let config = BZVFeedConfig { builder in
builder.unitId = "YOUR_FEED_UNIT_ID"
builder.baseRewardViewHolderClass = CustomFeedBaseRewardViewHolder.self
}

광고 디자인 자체 구현하기

BuzzAd iOS용 SDK에서 제공하는 광고는 일반 광고와 쇼핑 적립 광고가 있습니다.

  • 일반 광고: 쇼핑 광고를 제외한 나머지 유형의 광고입니다.
  • 쇼핑 적립 광고: 사용자가 광고를 통해 물건 구매를 달성하는 경우 사용자에게 구매 금액의 일정 비율을 포인트로 돌려주는 광고입니다.

두 유형 모두 광고를 표현할 수 있는 다양한 정보로 구성됩니다. 일반 광고와 쇼핑 적립 광고를 구성하는 요소와 UI에 대해서는 아래의 표를 참고하세요.

광고 유형구성 요소설명
공통(일반, 쇼핑)광고 제목 (필수)광고의 제목입니다. 최대 10자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호로 대체할 수 있습니다.
광고 소재 (필수)
  • 이미지, 동영상 등 광고 소재입니다. 광고 소재의 종횡비는 반드시 유지해야 합니다.
  • BZVMediaView를 사용해서 표시해야 합니다.
  • 사이즈: 1,200 x 627 (px)
  • 여백을 추가할 수 있습니다. 자세한 내용은 버즈빌 담당자에게 문의하세요.
광고 설명 (필수)광고에 대한 상세 설명입니다. 최대 40자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호로 대체할 수 있습니다.
광고주 아이콘 (필수)
  • 광고주 아이콘 이미지입니다. 반드시 아이콘의 종횡비를 유지해야 합니다.
  • 사이즈: 80 x 80 (px)
CTA 버튼 (필수)
  • 광고의 참여를 유도하는 버튼입니다. 최대 7자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호로 대체할 수 있습니다.
  • BZVDefaultCtaView 클래스를 사용해서 표시해야 합니다.

  • ✏️  참고
    CTA 버튼의 디자인을 변경하려면 CTA 버튼 자체 구현하기 토픽을 참고하세요.
광고 알림 문구 (권장)광고임을 명시하는 문구입니다. (예: 광고, ad, 스폰서, Sponsored)
쇼핑 적립OriginalPrice View (권장)상품의 원가를 표시합니다.
Price View (권장)상품의 할인된 가격을 표시합니다.
DiscountRate View (권장)상품 가격의 할인율을 표시합니다. 할인율은 원가와 할인가로 비교하여 산출해서 표시해야 합니다.

일반 광고 디자인 자체 구현하기

일반 광고의 디자인을 변경하려면 다음의 절차를 따르세요.

  1. 일반 광고용 BZVFeedAdViewHolder의 상속 클래스를 구현하세요.
  • 하위 뷰로 BZVNativeAdView, BZVMediaView, BZVDefaultCtaView 클래스를 추가하세요.
  • renderAd에서 BZVNativeAdViewBinder를 이용하여 광고 데이터(NativeAd)를 앞서 생성한 CustomFeedAdViewHolder에 바인딩하세요.
import UIKit
import BuzzAdBenefit

final class CustomFeedAdViewHolder: BZVFeedAdViewHolder {
let nativeAdView = BZVNativeAdView(frame: .zero)
let mediaView = BZVMediaView(frame: .zero)
let iconImageView = UIImageView(frame: .zero)
let titleLabel = UILabel(frame: .zero)
let descriptionLabel = UILabel(frame: .zero)
let ctaView = BZVDefaultCtaView(frame: .zero)
lazy var viewBinder = BZVNativeAdViewBinder { builder in
builder.nativeAdView = self.nativeAdView
builder.mediaView = self.mediaView
builder.iconImageView = self.iconImageView
builder.titleLabel = self.titleLabel
builder.descriptionLabel = self.descriptionLabel
builder.ctaView = self.ctaView
}

required init?(coder: NSCoder) {
super.init(coder: coder)
setUpView()
}

override init(frame: CGRect) {
super.init(frame: frame)
setUpView()
}

func setUpView() {
addSubview(nativeAdView)
nativeAdView.addSubview(mediaView)
nativeAdView.addSubview(iconImageView)
nativeAdView.addSubview(titleLabel)
nativeAdView.addSubview(descriptionLabel)
nativeAdView.addSubview(ctaView)

// LayoutConstraint 설정
...
}

override func renderAd(_ ad: BZVNativeAd) {
viewBinder.bind(with: ad)
}
}

BZVNativeAdEventDelegate을 통해 광고 콜백 이벤트 수신 기능을 부가적으로 추가할 수도 있습니다.

import UIKit
import BuzzAdBenefit

final class CustomFeedAdViewHolder: BZVFeedAdViewHolder, BZVNativeAdEventDelegate {

override func renderAd(_ ad: BZVNativeAd) {
viewBinder.bind(with: ad)
ad.add(self)
}

// MARK: BZVNativeAdEventDelegate
func didImpress(_ nativeAd: BZVNativeAd) {
}

func didClick(_ nativeAd: BZVNativeAd) {
}

func didRequestReward(for nativeAd: BZVNativeAd) {
}

func didReward(for nativeAd: BZVNativeAd, with result: BZVRewardResult) {
}

func didParticipateAd(_ nativeAd: BZVNativeAd) {
}
}
  1. BZVFeedConfig에 위에서 작성한 CustomFeedAdViewHolder를 광고 뷰 홀더로 설정하세요.
let config = BZVFeedConfig { builder in
builder.unitId = "YOUR_FEED_UNIT_ID"
builder.adViewHolderClass = CustomFeedAdViewHolder.self
}

쇼핑 적립 광고 디자인 자체 구현하기

쇼핑 적립 광고의 디자인을 변경하려면 다음의 절차를 따르세요.

  1. 일반 광고 디자인 자체 구현하기 토픽을 참고해 BZVFeedAdViewHolder의 상속 클래스를 구현하세요.
  • 일반 광고용 레이아웃에서 priceLabel, originalPriceLabel, discountPercentageLabel을 추가해야 합니다.
import UIKit
import BuzzAdBenefit

final class CustomFeedCpsAdViewHolder: BZVFeedAdViewHolder {
let nativeAdView = BZVNativeAdView(frame: .zero)
let mediaView = BZVMediaView(frame: .zero)
let iconImageView = UIImageView(frame: .zero)
let titleLabel = UILabel(frame: .zero)
let descriptionLabel = UILabel(frame: .zero)
let ctaView = BZVDefaultCtaView(frame: .zero)
let priceLabel = UILabel(frame: .zero)
let originalPriceLabel = UILabel(frame: .zero)
let discountRateLabel = UILabel(frame: .zero)
lazy var viewBinder = BZVNativeAdViewBinder { builder in
builder.nativeAdView = self.nativeAdView
builder.mediaView = self.mediaView
builder.iconImageView = self.iconImageView
builder.titleLabel = self.titleLabel
builder.descriptionLabel = self.descriptionLabel
builder.ctaView = self.ctaView
// 부가 기능: 텍스트를 클릭할 수 있도록 설정합니다.
builder.clickableViews = [
self.mediaView,
self.ctaView,
self.priceLabel,
self.originalPriceLabel,
self.discountRateLabel,
]
}

required init?(coder: NSCoder) {
super.init(coder: coder)
setUpView()
}

override init(frame: CGRect) {
super.init(frame: frame)
setUpView()
}

private func setUpView() {
// 광고 레이아웃 컴포넌트를 생성합니다.
...생략...
nativeAdView.addSubview(priceLabel)
nativeAdView.addSubview(originalPriceLabel)
nativeAdView.addSubview(discountRateLabel)

// LayoutConstraint 설정
...생략...
}

override func renderAd(_ ad: BZVNativeAd) {
viewBinder.bind(with: ad)

let product = ad.product
if product.discountedPrice != 0 {
// 할인이 있는 쇼핑 광고
priceLabel.text = NSNumber(value: product.discountedPrice).formattedString()
originalPriceLabel.text = NSNumber(value: product.price).formattedString()
let discountRate = (1 - product.discountedPrice / product.price) * 100
discountRateLabel.text = String(format: "%d%%", Int(discountRate))
} else {
// 할인이 없는 쇼핑 광고
priceLabel.text = NSNumber(value: product.discountedPrice).formattedString()
originalPriceLabel.text = NSNumber(value: product.price).formattedString()
discountRateLabel.text = "0%%"
}
}
}

extension NSNumber {
func formattedString() -> String? {
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
return numberFormatter.string(from: self)
}
}
  1. 이전 단계에서 작성한 CustomFeedAdViewHolderBZVFeedConfig에 쇼핑 광고 뷰 홀더로 설정하세요.
let config = BZVFeedConfig { builder in
builder.unitId = "YOUR_FEED_UNIT_ID"
builder.cpsAdViewHolderClass = CustomCpsAdViewHolder.self
}

CTA 버튼 자체 구현하기

BuzzAd iOS용 SDK에서 기본으로 제공하는 UI를 사용하지 않고 CTA 버튼을 자체적으로 구현할 수 있습니다.

CTA 버튼을 직접 구현하려면 CtaViewProtocol 프로토콜을 준수하는 UIView 클래스의 서브클래스를 생성하세요.

다음은 UIStackView를 활용하여 CTA View 클래스를 생성한 예시입니다.

import UIKit
import BuzzAdBenefit

final class CustomCtaView: UIStackView, BZVCtaViewProtocol {
let rewardImageView = UIImageView(frame: .zero)
let rewardLabel = UILabel(frame: .zero)
let ctaLabel = UILabel(frame: .zero)

required init(coder: NSCoder) {
super.init(coder: coder)
setUpView()
}

override init(frame: CGRect) {
super.init(frame: frame)
setUpView()
}

private func setUpView() {
addArrangedSubview(rewardImageView)
addArrangedSubview(rewardLabel)
addArrangedSubview(ctaLabel)
}

// MARK: BZVCtaViewProtocol
func renderRewardNotAvailableViewState(withCtaText ctaText: String) {
// 리워드가 없는 광고에 대한 CTA 뷰 레이아웃을 정의합니다.
rewardImageView.isHidden = true
rewardLabel.isHidden = true
ctaLabel.text = ctaText
}

func renderRewardAvailableViewState(withCtaText ctaText: String, reward: Int) {
// 리워드가 있는 광고에 대한 CTA 뷰 레이아웃을 정의합니다.
rewardImageView.isHidden = false
rewardLabel.isHidden = false

rewardImageView.image = UIImage(named: "YOUR_REWARD_IMAGE")
rewardLabel.text = "+\(reward)"
ctaLabel.text = ctaText
}

func renderParticipatingViewState(withCtaText ctaText: String) {
// 참여 확인 중인 광고에 대한 CTA 뷰 레이아웃을 정의합니다.
rewardImageView.isHidden = true
rewardLabel.isHidden = true
ctaLabel.text = "YOUR_PARTICIPATING_TEXT"
}

func renderParticipatedViewState(withCtaText ctaText: String) {
// 참여 완료한 광고에 대한 CTA 뷰 레이아웃을 정의합니다.
rewardImageView.isHidden = false
rewardLabel.isHidden = true

rewardImageView.image = UIImage(named: "YOUR_PARTICIPATED_IMAGE")
ctaLabel.text = "YOUR_PARTICIPATED_TEXT"
}
}

광고 미할당 안내 디자인 자체 구현하기

피드 지면에 진입한 시점에 노출할 광고가 없다면 광고 미할당 안내 UI가 표시됩니다. 미할당 안내 디자인은 자체 구현하여 변경할 수 있습니다.

다음은 미할당 안내 디자인을 변경하는 예시입니다.

BZVFeedErrorViewHolder를 상속하는 클래스를 생성합니다. 그리고 BZVFeedConfigerrorViewHolderClass 속성에 새로 구현한 클래스를 추가합니다. 선택적으로 updateViewWithError 메소드를 오버라이드하여 에러에 따라 UI를 업데이트 할 수 있습니다.

import UIKit
import BuzzAdBenefit

final class CustomFeedErrorViewHolder: BZVFeedErrorViewHolder {
let imageView = UIImageView(image: UIImage(named: "YOUR_ERROR_IMAGE_NAME"))

required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}

override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}

private func setupView() {
addSubview(imageView)

// LayoutConstraint 설정
...
}

override func updateViewWithError(_ error: Error) {
// error에 따라 UI를 업데이트 할 수 있는 코드 작성
}
}

let config = BZVFeedConfig { builder in
builder.unitId = "YOUR_FEED_UNIT_ID"
builder.errorViewHolderClass = CustomFeedErrorViewHolder.self
}

사용자의 활동 추적 권한 획득 기능

BuzzAd iOS용 SDK는 iOS 14 이상에서 사용자의 활동 추적 권한(App Tracking Transparency)을 획득하기 위한 다양한 기능을 제공합니다. 그 중 피드 지면에서는 활동 추적 권한을 획득하기 위한 다이얼로그 및 배너를 보여줄 수 있습니다.

피드 진입 시 활동 추적 권한 허용 다이얼로그 표시하기

다이얼로그 표시 설정을 하면 iOS 14 이상의 기기에서 활동 추적 허용 권한을 허용하지 않은 사용자가 피드 지면에 진입할 때 다이얼로그가 나타납니다.

다음은 피드 진입 시 활동 추적 권한 허용 다이얼로그를 표시하는 예시입니다.

let config = BZVFeedConfig { builder in
builder.unitId = "YOUR_FEED_UNIT_ID"
builder.shouldShowAppTrackingTransparencyDialog = true
}

✏️  참고
활동 추적 권한 허용에 대한 부가 기능은 iOS 14를 위한 대응 토픽을 참고하세요.

활동 추적 권한 허용에 대한 안내 배너 추가하기

피드 헤더 영역에 더 많은 리워드 획득 기회를 안내하는 배너를 표시하여 사용자가 활동 추적 권한을 허용하도록 장려할 수 있습니다. 권한 제공을 거부한 사용자에게만 표시됩니다.

✏️  참고
피드 헤더 영역을 자체 구현하는 경우에는 활동 추적 권한의 허용을 안내하는 배너가 노출되지 않습니다.

다음은 활동 추적 권한 허용 안내 배너를 추가하는 예시입니다.

let config = BZVFeedConfig { builder in
builder.unitId = "YOUR_FEED_UNIT_ID"
builder.shouldShowAppTrackingTransparencyGuideBanner = true
}

Info.plist 파일의 속성 값을 추가하여 배너를 클릭할 때 랜딩하는 URL을 변경할 수도 있습니다.

<key>BuzzAdAppTrackingTransparencyLandingURL</key>
<string>YOUR_ATT_DESCRIPTION_URL</string>

광고 타입 확인하기

BuzzAd Android용 SDK는 노출형, 액션형 등 다양한 광고 유형별로 차별화된 리워드 제공 등 다양한 기획을 지원하기 위해 광고 유형을 확인할 수 있는 API를 제공합니다. API에 대한 자세한 내용은 자주 하는 질문광고 타입 확인하기를 참고하세요.

개인정보 수집 동의 UI

BuzzAd iOS용 SDK는 사용자의 개인정보 수집 동의를 받기 위한 UI를 제공합니다.

개인정보 수집 동의 UI를 구현할 수 있는 API에 대한 정보는 아래 표를 참고하세요.

ClassAPI설명
BuzzAdBenefitprivacyPolicyManager (정적 변수)BZVPrivacyPolicyManager 인스턴스를 반환합니다.
BZVPrivacyPolicyManagerpresentConsentForm(on viewController: UIViewController, onComplete: ((Bool) -> Void)? = nil)개인정보 수집 동의 UI를 표시합니다.

❌  오류
이 메서드는 메인 쓰레드에서만 실행해야 합니다. 그렇지 않으면 크래시 오류가 발생할 수 있습니다.
grantConsent()개인정보 수집에 동의합니다.
revokeConsent()개인정보 수집 동의를 철회합니다.
isConsentGranted()개인정보 수집 동의 여부를 확인합니다.