Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

« Previous Version 12 Current »

목차

개요

이 문서에서 가이드 하는 내용은 BuzzAd iOS SDK의 Feed 지면의 기능을 설명하고 각 기능을 변경하는 방법을 설명합니다.

Feed 무한 스크롤

Feed 무한 스크롤 기능이 활성화되어 있으면 사용자에게 마지막 광고가 보였을 때 광고를 추가로 할당받습니다. 추가 요청에서 광고가 할당되지 않으면 더 이상 요청하지 않습니다. FeedConfig를 설정하여 무한 스크롤 기능을 활성화할 수 있습니다. 기본적으로 Feed 무한 스크롤 기능은 비활성화되어 있습니다.

다음은 무한 스크롤 기능을 활성화하는 예시입니다.

 Objective-C
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:@"YOUR_FEED_UNIT_ID"];
config.autoLoadingEnabled = YES;

 Swift
let config = BABFeedConfig(unitId: "YOUR_FEED_UNIT_ID")
config.autoLoadingEnabled = true

헤더 영역 자체 구현

Feed 헤더 영역을 자유로이 활용할 수 있습니다. 예를 들어, Feed 영역을 설명하는 공간으로도 활용할 수 있습니다.

BABFeedHeaderView의 구현 클래스를 구현하고, 구현한 View의 높이에 맞게 desiredHeight를 설정합니다.

필요에 따라 직접 구현한 UI 에 적립 가능한 금액을 표시할 수 있습니다. availableRewardDidUpdate를 통해 지급 가능한 금액을 알 수 있고, availableRewardDidUpdate 콜백에서 문구를 수정하여 표시할 수 있습니다.

다음은 헤더 영역을 자체 구현한 UI로 대체하는 예시입니다.

 Objective-C
@implementation CustomHeaderView {
  UILabel *_headerLabel;
}

- (instancetype)initWithCoder:(NSCoder *)coder{
  if (self = [super initWithCoder:coder]) {
    [self setUpView];
  }
  return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
    [self setUpView];
  }
  return self;
}

+ (CGFloat)desiredHeight {
  return 115.0f;
}

- (void)availableRewardDidUpdate:(double)reward {
  _headerLabel.text = [NSString stringWithFormat:@"+%d points available!", (int)reward];
}

- (void)setUpView {
  _headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
  _headerLabel.text = @"Custom Header Text";
  [self addSubview:_headerLabel];
  
  // LayoutConstraint 설정
  ...
}

@end
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:YOUR_FEED_UNIT_ID];
config.headerViewClass = [CustomHeaderView class];

 Swift
class CustomHeaderView: BABFeedHeaderView {
  required init?(coder: NSCoder) {
    super.init(coder: coder)
    setUpView()
  }

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

  override class func desiredHeight() -> CGFloat {
    return 115.0
  }
  
  override func availableRewardDidUpdate(_ reward: Double) {
    headerLabel.setText("\(reward) points available!")
  }

  func setUpView() {
    headerLabel = UILabel(frame: .zero)
    headerLabel.text = @"Custom Header Text";
    addSubview(headerLabel)
    
    // LayoutConstraint 설정
    ...
  }
}
let config = BABFeedConfig(unitId: YOUR_FEED_UNIT_ID)
config.headerViewClass = CustomHeaderView.self

광고 분류 기능

Feed 지면에서는 사용자가 광고를 선택적으로 참여할 수 있도록 탭과 필터 기능을 지원합니다.

탭 기능

사용자가 광고를 분류하여 볼 수 있도록 탭과 필터 기능이 기본으로 제공됩니다. 탭은 일반 광고와 쇼핑 적립형 광고를 구분하는 역할을 합니다. 설정하지 않았다면 탭은 보이지 않습니다.

다음은 탭 기능을 활성화하는 예시입니다.

 Objective-C
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:@"YOUR_FEED_UNIT_ID"];
config.tabUiEnabled = YES; 

 Swift
let config = BABFeedConfig(unitId: "YOUR_FEED_UNIT_ID")
config.tabUiEnabled = true

필터 기능

필터는 광고를 카테고리 별로 보다 세분화합니다. 필터는 탭에 종속되어 있습니다. 그래서, 탭이 비활성화되면 필터도 비활성화됩니다. 설정하지 않았다면 필터는 보이지 않습니다.

다음은 필터 기능을 활성화하는 예시입니다.

 Objective-C
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:@"YOUR_FEED_UNIT_ID"];
config.tabUiEnabled = YES;
config.filterUiEnabled = YES;

 Swift
let config = BABFeedConfig(unitId: "YOUR_FEED_UNIT_ID")
config.tabUiEnabled = true 
config.filterUiEnabled = true

광고 UI 자체 구현

BuzzAd iOS SDK에서 제공하는 광고는 일반 광고와 쇼핑 적립 광고가 있습니다. 각각의 광고에 따라 UI를 변경하는 방법이 상이합니다. 일반 광고과 쇼핑 적립 광고의 UI를 모두 변경하기 위해서는 각각 UI 변경을 진행해야 합니다.

추가로 광고의 노출, 클릭, 참여 이벤트 콜백을 받을 수 있습니다. 적용 방법은 광고 이벤트 콜백 수신을 참고하시기 바랍니다.

일반 광고 UI 자체 구현

다음은 일반 광고의 디자인을 변경하는 방법을 설명합니다.

우선 광고 레이아웃을 생성합니다. 아래 예시에서는 CustomAdViewHolder로 정의합니다. 광고 레이아웃의 최상위 컴포넌트는 BABNativeAdView이며, 아래 컴포넌트는 BABNativeAdView의 하위 컴포넌트로 구현해야 합니다.

설명

비고

필수 광고 제목

광고의 제목

  • 최대 10자

  • 생략 부호로 일정 길이 이상은 생략 가능

필수 광고 소재

이미지, 동영상 등 광고 소재

  • com.buzzvil.buzzad.benefit.presentation.media.MediaView 사용 필수

  • 종횡비 유지 필수

  • 여백 추가 가능

  • 이미지 사이즈 1200x627 [px]

필수 광고 설명

광고에 대한 상세 설명

  • 생략 부호로 일정 길이 이상은 생략 가능

  • 최대 40자

필수 광고주 아이콘

광고주 아이콘 이미지

  • 종횡비 유지 필수

  • 이미지 사이즈 80x80 [px]

필수 CTA 버튼

광고의 참여를 유도하는 버튼

  • com.buzzvil.buzzad.benefit.presentation.media.CtaView 사용 필수

  • 최대 7자

  • 생략 부호로 일정 길이 이상은 생략 가능

임의 광고 알림 문구

Sponsored view

  • 예시) “광고”, “ad”, “스폰서”, “Sponsored”

광고 레이아웃을 생성한 후, BABAdViewHolder의 구현 클래스를 구현합니다. BABAdViewHolder의 구현 클래스는 BABFeedConfig에 설정합니다.

다음은 Objective-C와 Swift로 구현한 예시입니다.

 Objective-C
@interface CustomAdViewHolder: BABAdViewHolder {
  BABNativeAdView *_adView;
  BABMediaView *_mediaView;
  UILabel *_titleLabel;
  ...
}
@end

@implementation CustomAdViewHolder

- (instancetype)initWithCoder:(NSCoder *)coder {
  if (self = [super initWithCoder:coder]) {
    [self setUpView];
  }
  return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
    [self setUpView];
  }
  return self;
}

- (void)setUpView {
  _adView = [[BABNativeAdView alloc] initWithFrame:CGRectZero];
  _mediaView = [[BABMediaView alloc] initWithFrame:CGRectZero];
  _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
  ...
  
  _adView.delegate = self;
  
  [self addSubview:_adView];
  [_adView addSubview:_mediaView];
  [_adView addSubview:_titleLabel];
  ...
  
  // LayoutConstraint 설정
  ...
}

// Bind view with ad
- (void)renderAd:(BABAd *)ad {
    [super renderAd:ad];
  
    self.titleLabel.text = ad.creative.title;
    self.descriptionLabel.text = ad.creative.body;
    [self.iconImageView sd_setImageWithURL:[NSURL URLWithString:ad.creative.iconUrl]];
  
    self.adView.ad = ad;
    self.adView.mediaView = self.mediaView;
    self.adView.clickableViews = @[self.ctaButton, self.iconImageView];
    
    [self updateCtaButtonWithAd:ad];
}

- (void)updateCtaButtonWithAd:(BABAd *)ad {
  NSString *callToAction = ad.creative.callToAction;
  double reward = ad.reward;
  double totalReward = [ad getTotalReward];
  BOOL isParticipated = [ad isParticipated];
  BOOL isClicked = [ad isClicked];
  BOOL isActionType = [ad isActionType];
  if (isClicked && isActionType && !isParticipated) {
    _rewardIcon.image = nil;
    _ctaLabel.text = @"참여 확인 중";
  } else {
    if (totalReward > 0 && isParticipated) {
      _rewardIcon.image = [UIImage imageNamed:@"ic_check"];
      _ctaLabel.text = @"참여 완료";
    } else if (reward > 0) {
      _rewardIcon.image = [UIImage imageNamed:@"ic_coin"];
      _ctaLabel.text = [NSString stringWithFormat:@"+%d %@", (int)reward, callToAction];
    } else {
      _rewardIcon.image = nil;
      _ctaLabel.text = callToAction;
    }
  }
}

#pragma mark -- BABNativeAdViewDelegate
- (void)BABNativeAdView:(BABNativeAdView *)adView didImpressAd:(BABAd *)ad {
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didClickAd:(BABAd *)ad {
  [self updateCtaButtonWithAd:ad];
}

- (void)BABNativeAdView:(BABNativeAdView *)adView willRequestRewardForAd:(BABAd *)ad {
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didRewardForAd:(BABAd *)ad withResult:(BABRewardResult)result {
  [self updateCtaButtonWithAd:ad];
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didParticipateAd:(BABAd *)ad {
  [self updateCtaButtonWithAd:ad];
}

@end
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:@"YOUR_FEED_UNIT_ID"];
config.adViewHolderClass = [CustomAdViewHolder class];
 Swift
class CustomAdViewHolder: BABAdViewHolder {
  private var adView = BABNativeAdView()
  private var mediaView = BABMediaView()
  private var titleLabel = UILabel()
  ...

  required init?(coder: NSCoder) {
    super.init(coder: coder)
    setUpView()
  }
  
  override init(frame: CGRect) {
    super.init(frame: frame)
    setUpView()
  }
  
  func setUpView() {
    adView.delegate = self
    addSubview(self.adView)
    adView.addSubview(self.mediaView)
    adView.addSubview(self.titleLabel)
    ...
    
    // LayoutConstraint 설정
    ...
  }

  // Bind view with ad
  override func renderAd(_ ad: BABAd) {
    super.renderAd(ad)
    
    self.titleLabel.text = ad.creative.title
    self.descriptionLabel.text = ad.creative.body
    
    if let urlString = ad.creative.iconUrl {
      self.iconImageView.sd_setImage(with: URL(string: urlString))
    }
    
    self.adView.ad = ad
    self.adView.mediaView = self.mediaView
    self.adView.clickableViews = [self.ctaButton, self.iconImageView]
    
    updateCtaButton(ad: ad)
  }
  
  func updateCtaButton(ad: BABAd) {
    let callToAction = ad.creative.callToAction ?? "디폴트 스트링"
    let reward = ad.reward
    let totalReward = ad.getTotalReward()
    let isParticipated = ad.isParticipated()
    let isClicked = ad.isClicked()
    let isActionType = ad.isActionType()
    if (isClicked && isActionType && !isParticipated) {
      rewardIcon.image = nil
      ctaLabel.text = "참여 확인 중"
    } else {
      if (totalReward > 0 && isParticipated) {
        rewardIcon.image = UIImage(named: "ic_check")
        ctaLabel.text = "참여 완료"
      } else if (reward > 0) {
        rewardIcon.image = UIImage(named: "ic_coin")
        ctaLabel.text = "\(Int(ad.reward))P \(callToAction)"
      } else {
        rewardIcon.image = nil
        ctaLabel.text = callToAction
      }
    }
  }
  
  // MARK: BABNativeAdViewDelegate
  func babNativeAdView(_ adView: BABNativeAdView, didImpress ad: BABAd) {
  }
  
  func babNativeAdView(_ adView: BABNativeAdView, didClick ad: BABAd) {
    updateCtaButton(ad: ad)
  }
  
  func babNativeAdView(_ adView: BABNativeAdView, willRequestRewardFor ad: BABAd) {
  }
  
  func babNativeAdView(_ adView: BABNativeAdView, didRewardFor ad: BABAd, with result: BABRewardResult) {
    updateCtaButton(ad: ad)
  }
  
  func babNativeAdView(_ adView: BABNativeAdView, didParticipateAd ad: BABAd) {
    updateCtaButton(ad: ad)
  }
}
let config = BABFeedConfig(unitId: "YOUR_FEED_UNIT_ID")
config.adViewHolderClass = CustomAdViewHolder.self

쇼핑 적립 광고 UI 자체 구현

다음은 쇼핑 적립 광고의 디자인을 변경하는 방법을 설명합니다. 쇼핑 적립 광고는 일반 광고에 비해 많은 정보를 제공합니다.

다음은 쇼핑 적립 광고의 디자인을 변경하는 방법을 설명합니다. 쇼핑 적립 광고는 일반 광고에는 없는 가격 정보 컴포넌트가 있습니다.

우선 광고 레이아웃을 생성합니다. 아래 예시에서는 CustomCpsAdViewHolder로 정의합니다. 광고 레이아웃의 최상위 컴포넌트는 BABNativeAdView이며, 아래 컴포넌트는 BABNativeAdView의 하위 컴포넌트로 구현해야 합니다.

설명

비고

필수 일반 광고의 필수 컴포넌트

일반 광고에서 정의하는 컴포넌트

  • Sponsored view는 권장

필수Category View

상품의 카테고리를 표시합니다.

권장OriginalPrice View

상품의 원가를 표시합니다.

권장Price View

상품의 할인된 가격을 표시합니다.

권장DiscountRate View

상품 가격의 할인율을 표시합니다.

  • 할인율은 원가와 할인가로 비교하여 산출해야 합니다.

광고 레이아웃을 생성한 후, BABAdViewHolder의 구현 클래스를 구현합니다. BABAdViewHolder의 구현 클래스는 BABFeedConfig에 설정합니다.

다음은 Objective-C와 Swift로 구현한 예시입니다.

 Objective-C
@interface CustomCpsAdViewHolder: BABAdViewHolder {
  BABNativeAdView *_adView;
  BABMediaView *_mediaView;
  UILabel *_titleLabel;
  ...
}
@end

@implementation CustomCpsAdViewHolder

- (instancetype)initWithCoder:(NSCoder *)coder {
  if (self = [super initWithCoder:coder]) {
    [self setUpView];
  }
  return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
    [self setUpView];
  }
  return self;
}

- (void)setUpView {
  _adView = [[BABNativeAdView alloc] initWithFrame:CGRectZero];
  _mediaView = [[BABMediaView alloc] initWithFrame:CGRectZero];
  _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
  
  _adView.delegate = self;
  
  [self addSubview:_adView];
  [_adView addSubview:_mediaView];
  [_adView addSubview:_titleLabel];
  ...
}

// 1) Populate your view (example using xib file)
- (void)loadFromNib {
  self.adView = [[NSBundle bundleForClass:[CustomCpsAdViewHolder class]] loadNibNamed:@"CustomAdViewHolder" owner:self options:nil][0];
  [self addSubview:self.adView];
}

// 2) Bind view with ad
- (void)renderAd:(BABAd *)ad {
  [super renderAd:ad];
  
  _titleLabel.text = ad.creative.title;
  
  // description 필드가 objc 객체에 기본으로 있어서 body로 컨버팅 하여 사용
  _descriptionLabel.text = ad.creative.body;
  
  [_iconImageView sd_setImageWithURL:[NSURL URLWithString:ad.creative.iconUrl]];
  
  // for CPS
  BABProduct *product = ad.product;
  if (product.discountedPrice != 0) {
    _priceView.text = [self formattedStringForNumber:@(product.discountedPrice)];
    _originalPriceView.text = [self formattedStringForNumber:@(product.price)];
    CGFloat discountRate = (1 - product.discountedPrice / product.price) * 100;
    _discountRateView.text = [NSString stringWithFormat:@"%.f%%", discountRate];
  } else {
    _priceView.text = [self formattedStringForNumber:@(product.price)];
    _originalPriceView.text = [self formattedStringForNumber:@(product.price)];
    _discountRateView.text = @"0%";
  }
  
  if (product.category != nil) {
    _categoryView.text = ad.product.category;
  } else {
    _categoryView.hidden = YES;
  }
  
  _adView.ad = ad;
  _adView.mediaView = _mediaView;
  _adView.clickableViews = @[_ctaButton, _iconImageView];
  
  [self updateCtaButtonWithAd:ad];
}

- (void)updateCtaButtonWithAd:(BABAd *)ad {
  NSString *callToAction = ad.creative.callToAction;
  double reward = ad.reward;
  double totalReward = [ad getTotalReward];
  BOOL isParticipated = [ad isParticipated];
  BOOL isClicked = [ad isClicked];
  BOOL isActionType = [ad isActionType];
  if (isClicked && isActionType && !isParticipated) {
    _rewardIcon.image = nil;
    _ctaLabel.text = @"참여 확인 중";
  } else {
    if (totalReward > 0 && isParticipated) {
      _rewardIcon.image = [UIImage imageNamed:@"ic_check"];
      _ctaLabel.text = @"참여 완료";
    } else if (reward > 0) {
      _rewardIcon.image = [UIImage imageNamed:@"ic_coin"];
      _ctaLabel.text = [NSString stringWithFormat:@"+%d %@", (int)reward, callToAction];
    } else {
      _rewardIcon.image = nil;
      _ctaLabel.text = callToAction;
    }
  }
}

- (NSString *)formattedStringForNumber:(NSNumber *)number {
  NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
  formatter.numberStyle = NSNumberFormatterDecimalStyle;
  return [formatter stringFromNumber:number];
}

#pragma mark -- BABNativeAdViewDelegate
// Handle ad callbacks
- (void)BABNativeAdView:(BABNativeAdView *)adView didImpressAd:(BABAd *)ad {
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didClickAd:(BABAd *)ad {
  [self updateCtaButtonWithAd:ad];
}

- (void)BABNativeAdView:(BABNativeAdView *)adView willRequestRewardForAd:(BABAd *)ad {
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didRewardForAd:(BABAd *)ad withResult:(BABRewardResult)result {
  [self updateCtaButtonWithAd:ad];
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didParticipateAd:(BABAd *)ad {
  [self updateCtaButtonWithAd:ad];
}

@end
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:@"YOUR_FEED_UNIT_ID"];
config.cpsAdViewHolderClass = [CustomCpsAdViewHolder class];
 Swift
class CustomCpsAdViewHolder: BABAdViewHolder {
  private var adView = BABNativeAdView()
  private var mediaView = BABMediaView()
  private var titleLabel = UILabel()
  ...

  required init?(coder: NSCoder) {
    super.init(coder: coder)
    setUpView()
  }
  
  override init(frame: CGRect) {
    super.init(frame: frame)
    setUpView()
  }
  
  func setUpView() {
    adView.delegate = self
    addSubview(self.adView)
    adView.addSubview(self.mediaView)
    adView.addSubview(self.titleLabel)
    ...
  }

  // 2) Bind view with ad
  override func renderAd(_ ad: BABAd) {
    super.renderAd(ad)
    
    self.titleLabel.text = ad.creative.title
    
    // description 필드가 objc 객체에 기본으로 있어서 body로 컨버팅 하여 사용
    self.descriptionLabel.text = ad.creative.body
    
    if let urlString = ad.creative.iconUrl {
      self.iconImageView.sd_setImage(with: URL(string: urlString))
    }
    
    // for CPS
    let product = ad.product
    if product.discountedPrice != 0 {
      self.priceView.text = NSNumber(value: product.discountedPrice).formattedString()
      self.originalPriceView.text = NSNumber(value: product.price).formattedString()
      let discountRate = (1 - product.discountedPrice / product.price) * 100
      self.discountRateView.text = String(format: "%d%%", Int(discountRate))
    } else {
      self.priceView.text = NSNumber(value: product.price).formattedString()
      self.originalPriceView.text = NSNumber(value: product.price).formattedString()
      self.discountRateView.text = "0%%"
    }
    
    if let category = product.category {
      self.categoryView.text = category
    } else {
      self.categoryView.isHidden = true
    }
    
    self.adView.ad = ad
    self.adView.mediaView = self.mediaView
    self.adView.clickableViews = [self.ctaButton, self.iconImageView]
    updateCtaButton(ad: ad)
  }
  
  func updateCtaButton(ad: BABAd) {
    let callToAction = ad.creative.callToAction ?? "디폴트 스트링"
    let reward = ad.reward
    let totalReward = ad.getTotalReward()
    let isParticipated = ad.isParticipated()
    let isClicked = ad.isClicked()
    let isActionType = ad.isActionType()
    if (isClicked && isActionType && !isParticipated) {
      rewardIcon.image = nil
      ctaLabel.text = "참여 확인 중"
    } else {
      if (totalReward > 0 && isParticipated) {
        rewardIcon.image = UIImage(named: "ic_check")
        ctaLabel.text = "참여 완료"
      } else if (reward > 0) {
        rewardIcon.image = UIImage(named: "ic_coin")
        ctaLabel.text = "\(Int(ad.reward))P \(callToAction)"
      } else {
        rewardIcon.image = nil
        ctaLabel.text = callToAction
      }
    }
  }
  
  // MARK: BABNativeAdViewDelegate
  // Handle ad callbacks
  func babNativeAdView(_ adView: BABNativeAdView, didImpress ad: BABAd) {
  }
  
  func babNativeAdView(_ adView: BABNativeAdView, didClick ad: BABAd) {
    updateCtaButton(ad: ad)
  }
  
  func babNativeAdView(_ adView: BABNativeAdView, willRequestRewardFor ad: BABAd) {
  }
  
  func babNativeAdView(_ adView: BABNativeAdView, didRewardFor ad: BABAd, with result: BABRewardResult) {
    updateCtaButton(ad: ad)
  }
  
  func babNativeAdView(_ adView: BABNativeAdView, didParticipateAd ad: BABAd) {
    updateCtaButton(ad: ad)
  }
}

extension NSNumber {
  func formattedString() -> String? {
    let formatter = NumberFormatter()
    formatter.numberStyle = .decimal
    return formatter.string(from: self)
  }
}
let config = BABFeedConfig(unitId: "YOUR_FEED_UNIT_ID")
config.cpsAdViewHolderClass = CustomCpsAdViewHolder.self

광고 이벤트 콜백 수신

필요에 따라 광고 노출, 클릭, 참여 이벤트 콜백을 받을 수 있습니다.

다음은 Objective-C와 Swift로 구현한 예시입니다.

 Objective-C
@interface CustomAdViewHolder: BABAdViewHolder <BABNativeAdViewDelegate>
@end

@implementation CustomAdViewHolder

- (void)loadFromNib {
    ...
    self.adView.delegate = self;
    ...
}


// Handle ad callbacks
- (void)BABNativeAdView:(BABNativeAdView *)adView didImpressAd:(BABAd *)ad {
  // 사용자에게 광고가 보여지면 호출됩니다.
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didClickAd:(BABAd *)ad {
  // 사용자가 광고를 클릭하여 참여하면 호출됩니다.
}

- (void)BABNativeAdView:(BABNativeAdView *)adView willRequestRewardForAd:(BABAd *)ad {
  // 사용자가 광고에 참여하고 리워드 요청을 하기 전에 호출됩니다.
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didRewardForAd:(BABAd *)ad withResult:(BABRewardResult)result {
  // SDK에서 광고 리워드 요청 후에 호출됩니다.
}

- (void)BABNativeAdView:(BABNativeAdView *)adView didParticipateAd:(BABAd *)ad {
  // 광고 참여가 확인되면 호출됩니다. 
}

@end

 Swift
class CustomAdViewHolder: BABAdViewHolder, BABNativeAdViewDelegate {
    // Populate your view (example using xib file)
    
    func loadFromNib() {
        ...
        self.adView.delegate = self
        ...
    }

    // Handle ad callbacks
    func babNativeAdView(_ adView: BABNativeAdView, didImpress ad: BABAd) {\
      // 사용자에게 광고가 보여지면 호출됩니다.
    }
  
    func babNativeAdView(_ adView: BABNativeAdView, didClick ad: BABAd) {
      // 사용자가 광고를 클릭하여 참여하면 호출됩니다.
    }
  
    func babNativeAdView(_ adView: BABNativeAdView, willRequestRewardFor ad: BABAd) {
      // 사용자가 광고에 참여하고 리워드 요청을 하기 전에 호출됩니다.
    }
  
    func babNativeAdView(_ adView: BABNativeAdView, didRewardFor ad: BABAd, with result: BABRewardResult) {
      // SDK에서 광고 리워드 요청 후에 호출됩니다.
    }
  
    func babNativeAdView(_ adView: BABNativeAdView, didParticipateAd ad: BABAd) {
      // 광고 참여가 확인되면 호출됩니다. 
    }
}

App Tracking Transparency (iOS 14 지원) 권한 획득 기능

Feed 지면에서 ATT 권한 획득을 위한 팝업 및 가이드 배너를 보여줄 수 있습니다.

Feed 진입 시 권한 획득 다이얼로그 노출

팝업 노출을 설정하면 iOS 14에서 ATT 권한 허용 여부를 결정하지 않은 사용자가 Feed 지면에 진입할 때 ATT 권한 획득 팝업이 보입니다.

다음은 Objective-C 와 Swift에서 설정하는 방법입니다.

 Objective-C
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:@"YOUR_FEED_UNIT_ID"];
config.shouldShowAppTrackingTransparencyDialog = YES;

 Swift
let config = BABFeedConfig(unitId: "YOUR_FEED_UNIT_ID")
config.shouldShowAppTrackingTransparencyDialog = true

ATT 권한에 대한 추가적인 설명은 iOS14를 위한 준비를 참조해 주세요.

Feed 헤더 영역에 ATT 권한 설명 배너 추가하기

Feed 지면 상단의 헤더 영역에 배너를 표시하여 사용자에게 ATT 권한에 대해서 설명할 수 있습니다.
제공을 거부한 사용자에 한정하여 보여집니다. 단, Feed 헤더 영역을 사용하는 경우에는 ATT 권한 설명 배너는 노출되지 않습니다.

다음은 Feed 지면 상단에 ATT 권한 설명 배너를 노출하는 설정 예시입니다.

 Objective-C
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:@"YOUR_FEED_UNIT_ID"];
config.shouldShowAppTrackingTransparencyGuideBanner = YES;

 Swift
let config = BABFeedConfig(unitId: "YOUR_FEED_UNIT_ID")
config.shouldShowAppTrackingTransparencyGuideBanner = true

 Info.plist 에 ATT 설명 페이지 URL 설정
<key>BuzzAdAppTrackingTransparencyLandingURL</key>
<string>YOUR_ATT_DESCRIPTION_URL</string>

Feed 지면 광고 미할당 안내 UI 자체 구현

사용자가 Feed 지면에 진입한 시점에 노출할 광고가 없다면 미 할당 안내 UI가 노출됩니다. BuzzAd iOS SDK는 위와 같은 기본 UI를 제공합니다. 안내 UI는 자체 구현하여 변경하거나 Feed 지면 광고 미할당 안내 UI 변경을 참고하여 이미지 혹은 문구만 변경하여 수정할 수도 있습니다.

다음은 자체 구현한 UI로 변경하는 예시입니다.

 Objective-C
@implementation CustomErrorViewHolder {
  UILabel *_errorLabel;
}

- (instancetype)initWithCoder:(NSCoder *)coder {
  if (self = [super initWithCoder:coder]) {
    [self setUpView];
  }
  return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
    [self setUpView];
  }
  return self;
}

- (void)setUpView {
  _errorLabel = [[UILabel alloc] initWithFrame:CGRectZero];
  _errorLabel.text = @"Custom Error View";
  [self addSubview:_errorLabel];
  
  // LayoutConstraint 설정
  ...
}

...
@end
BABFeedConfig *config = [[BABFeedConfig alloc] initWithUnitId:YOUR_FEED_UNIT_ID];
config.errorViewHolderClass = [CustomErrorViewHolder class];

 Swift
class CustomErrorViewHolder: UIView {
  private var errorLabel = UILabel()
  
  required init?(coder: NSCoder) {
    super.init(coder: coder)
    setUpView()
  }
  
  override init(frame: CGRect) {
    super.init(frame: frame)
    setUpView()
  }
  
  private func setUpView() {
    errorLabel.text = "Custom Error View"
    self.addSubview(errorLabel)
    
    // LayoutConstraint 설정
    ...
  }
  
  ...
}
let config = BABFeedConfig(unitId: FEED_UNIT_ID)
config.errorViewClass = CustomErrorView.self

Feed 지면에 진입하기 전에 광고를 미리 할당받아서 참여할 광고가 있는 경우에만 사용자를 Feed 지면으로 진입하도록 하면 미할당 안내 이미지를 보이지 않게 할 수 있습니다. 자세한 내용은 광고 미리 할당받기를 참고하시기 바랍니다.

기본 포인트 조회

사용자가 Feed 지면에 진입할 때 설정된 주기마다 기본 포인트를 지급합니다. BuzzAd iOS SDK 에서는 현재 사용자가 받을 수 있는 기본 포인트 양을 조회할 수 있습니다.

다음은 기본 포인트를 조회하는 예시입니다.

 Objective-C
[BuzzAdBenefit getAvailableFeedBaseRewardForUnitId:@"YOUR_FEED_UNIT_ID" onComplete:^(NSInteger baseReward) {
  // baseReward 를 사용하여 UI 업데이트 등..
];
 Swift
BuzzAdBenefit.getAvailableFeedBaseReward(forUnitId: "YOUR_FEED_UNIT_ID") { baseReward in
  // baseReward 를 사용하여 UI 업데이트 등..
}

  • No labels