Menu

native advertising

1. Main development work instructions

1. Create a custom Native Adapter class that can inherit NSObject. And follow the ATAdAdapter protocol, it is recommended to end with NativeAdapter, and the class name needs to be configured to the custom advertising platform in the TopOn backend;

2. The custom adapter class must implement the method description As follows:

  • When the SDK needs to request to configure a custom advertising source, the method initWithNetworkCustomInfo: will be called to instantiate the adapter object;
  • Requesting a custom ad source ad will trigger the adapter's loadADWithInfo: method call;
  • Need to set rendererClass and inherit ATNativeRenderer, when the advertisement is rendered, you need to call this method to key Elements are converted according to the advertising platform SDK.

The specific method is explained as follows:

3. The callback method is described as follows: You need to customize a xxxCustomEvent class, inherit the ATBannerCustomEvent class, and add custom events through this class. Define the callback agent corresponding to the advertising platform. When the advertising platform has a callback, the method of calling ATBannerCustomEvent for the corresponding event will be passed back to TopOn SDK.

The specific callback method is described as follows:

Callback methodParameter descriptionDescription
-(void) trackNativeAdLoaded:(NSDictionary* ) assetsassets: native creative Execute a callback to the developer when the ad is loaded successfully
-(void) trackNativeAdLoadFailed:(NSError* )errorerror: Error messageAd loading failed Execute callback to the developer
-(void) trackNativeAdImpression-Execute a callback to the developer when the advertising page is opened
-(void) trackNativeAdClick -Callback to the developer when the ad is clicked
-(void) trackNativeAdClosed-Execute a callback to the developer when the ad is clicked to close

2. Specific integration instructions and examples

2.1 Adapter to implement advertising loading Class

1. Create a custom Native Adapter class, which can inherit NSObject. It is recommended to end with NativeAdapter. The class name needs to be configured to the custom advertising platform in the TopOn backend.

2. The custom adapter class must implement the following methods:

  • Implement initWithNetworkCustomInfo: instance Adapter object, you can perform relevant initialization of the advertising SDK here.
  • Implement the loadADWithInfo: method called when advertising is loaded to trigger the advertising request of the advertising SDK.
  • You need to set rendererClass and inherit ATNativeRenderer. When the advertisement is rendered, you need to call this method to perform key elements according to the advertising platform SDK.

The following is an integration example. For specific projects, please refer to demo Sample code in CustomAdapter:

Create and implement the TouTiaoNativeCustomAdapter class

//TouTiaoNativeCustomAdapter.h
#import <AnyThinkNative/AnyThinkNative.h>

@interface TouTiaoNativeCustomAdapter()<ATAdAdapter>
@property(nonatomic, readonly) TouTiaoNativeCustomEvent *customEvent;
@end

@implementation TouTiaoNativeCustomAdapter

/// Adapter initialization method
/// - Parameters:
///   - serverInfo: Data from the server
///   - localInfo: Data from the local
-(instancetype) initWithNetworkCustomInfo:(NSDictionary*)serverInfo localInfo:(NSDictionary*)localInfo {
    self = [super init];
    if (self != nil) {
    //TODO: add some code for initialize Network SDK
    }
    return self;
}

/// Adapter sends a load request, means the ad source sends an ad load request
/// - Parameters:
///   - serverInfo: Data from the server
///   - localInfo: Data from the local
///   - completion: completion
-(void) loadADWithInfo:(NSDictionary*)serverInfo localInfo:(NSDictionary*)localInfo completion:(void (^)(NSArray<NSDictionary *> *, NSError *))completion {
    _customEvent = [TouTiaoNativeCustomEvent new];
    _customEvent.isVideo = [serverInfo[@"is_video"] integerValue] == 1;
    _customEvent.requestCompletionBlock = completion;

    NSDictionary *extraInfo = localInfo;
    _customEvent.requestExtra = extraInfo;
    NSString *sizeKey = [serverInfo[@"media_size"] integerValue] > 0 ? @{@2:kATExtraNativeImageSize228_150, @1:kATExtraNativeImageSize690_388}[serverInfo[@"media_size"]] : extraInfo[kATExtraNativeImageSizeKey];
    NSInteger imgSize = [@{kATExtraNativeImageSize228_150:@9, kATExtraNativeImageSize690_388:@10}[sizeKey] integerValue];

    BUAdSlot *slot = [[NSClassFromString(@"BUAdSlot") alloc] init];
    slot.ID = serverInfo[@"slot_id"];
    slot.AdType = [@{@0:@(BUAdSlotAdTypeFeed), @1:@(BUAdSlotAdTypeDrawVideo), @2:@(BUAdSlotAdTypeBanner), @3:@(BUAdSlotAdTypeInterstitial)}[@([serverInfo[@"is_video"] integerValue])] integerValue];
    slot.isOriginAd = YES;
    slot.position = 1;
    slot.imgSize = [NSClassFromString(@"BUSize") sizeBy:imgSize];
    slot.isSupportDeepLink = YES;

    CGSize size = CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds) - 30.0f, 200.0f);
    if ([extraInfo[kExtraInfoNativeAdSizeKey] respondsToSelector:@selector(CGSizeValue)]) { size = [extraInfo[kExtraInfoNativeAdSizeKey] CGSizeValue]; }

    _adMgr = [[BUNativeExpressAdManager alloc] initWithSlot:slot adSize:size];
    _adMgr.delegate = _customEvent;
    _adMgr.adslot = slot;
    [_adMgr loadAd:[serverInfo[@"request_num"] integerValue]];
    
}
+(Class) rendererClass {
    return [ATTTNativeRenderer class];
}

2.2 Implementation of NativeRenderer advertising rendering

TopOn SDK internally encapsulates the rendering of native ads. Therefore, when implementing a custom Adapter, you need to implement the Renderer class. The native parameters returned by the advertising platform are mapped to TopOn internal objects.

1. Implement the Renderer class that inherits ATNativeRenderer, as follows:

@interface TouTiaoNativeRenderer : ATNativeRenderer
@property(nonatomic, readonly) TouTiaoNativeCustomEvent *customEvent;
@end

2. Implement the renderOffer method, which can perform functions required after rendering according to the requirements of the advertising platform, such as registering click events. , the reference is as follows:

-(void) renderOffer:(ATNativeADCache *)offer {
    [super renderOffer:offer];
    _customEvent = offer.assets[kAdAssetsCustomEventKey];
    _customEvent.adView = self.ADView;
    self.ADView.customEvent = _customEvent;
    // Since the Pangolin setup AD agency requires the BunativeExpress Manager, a custom key is passed in here for use.
    BUNativeExpressAdManager *nativeExpressAd = (BUNativeExpressAdManager *)offer.assets[@"tt_nativeexpress_manager"];
    nativeExpressAd.delegate = _customEvent;
    BUNativeExpressAdView *nativeFeed = offer.assets[kAdAssetsCustomObjectKey];
    nativeFeed.rootViewController = self.configuration.rootViewController;
    [nativeFeed render];
    [self.ADView addSubview:(UIView*)nativeFeed];
    nativeFeed.center = CGPointMake(CGRectGetMidX(self.ADView.bounds), CGRectGetMidY(self.ADView.bounds));

}

3 . If there is a MediaView in the advertising form, you need to implement createMediaView to return the mediaview object to TopOn. The reference is as follows:

-(__kindof UIView*)createMediaView {
    ATVideoView *videoView = [[ATVideoView alloc] initWithFrame:self.ADView.bounds URL:nil];
    videoView.autoPlay = ((ATNativeADCache*)self.ADView.nativeAd).placementModel.wifiAutoSwitch;
    return videoView;
}

2.3 CustomEvent class that implements advertising callback

You need to customize a xxxCustomEvent class, inherit the ATNativeCustomEvent class, and pass this class Add the callback agent corresponding to the custom advertising platform. When the advertising platform has a callback, the corresponding event method of calling ATNativeCustomEvent is passed back to the TopOn SDK.

The following is an integration example. For specific projects, please refer to demo:

Create and implement the TouTiaoNativeCustomEvent class:

The following is an example of pangolin Native advertising callback:

- (void)nativeExpressAdSuccessToLoad:(BUNativeExpressAdManager *)nativeExpressAd views:(NSArray<__kindof BUNativeExpressAdView *> *)views {
    NSLog(@"TTNative::nativeExpressAdSuccessToLoad:nativeAds:");
    if (views.count) {
        NSMutableArray<NSDictionary*>* assets = [NSMutableArray<NSDictionary*> array];
        [views enumerateObjectsUsingBlock:^(BUNativeExpressAdView *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSMutableDictionary *asset = [NSMutableDictionary dictionary];
            BUNativeExpressAdView* expressView = obj;
            [asset setValue:self forKey:kAdAssetsCustomEventKey];
            [asset setValue:expressView forKey:kATAdAssetsCustomObjectKey];
            // Native template advertising
            [asset setValue:@(1) forKey:kATNativeADAssetsIsExpressAdKey];
            [asset setValue:@(nativeExpressAdView.frame.size.width) forKey:kATNativeADAssetsNativeExpressAdViewWidthKey];
            [asset setValue:@(nativeExpressAdView.frame.size.height) forKey:kATNativeADAssetsNativeExpressAdViewHeightKey];
            
            expressView.rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
            [assets addObject:asset];
        }];
        self.requestCompletionBlock(assets, nil);
    }
}

- (void)nativeExpressAdFailToLoad:(BUNativeExpressAdManager *)nativeExpressAd error:(NSError *_Nullable)error{
    NSLog(@"%@",[NSString stringWithFormat:@"TTNative::nativeAdsManager:didFailWithError:%@", error]);
    self.requestCompletionBlock(nil, error);
}


- (void)nativeExpressAdViewRenderSuccess:(BUNativeExpressAdView *)nativeExpressAdView {
    NSLog(@"TTNative::nativeExpressAdViewRenderSuccess:");
}

- (void)nativeExpressAdViewDidClick:(BUNativeExpressAdView *)nativeExpressAdView {
    NSLog(@"TTNative::nativeAdDidClick:withView:");
    [self trackNativeAdClick];
}

- (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView dislikeWithReason:(NSArray<BUDislikeWords *> *)filterWords {
    NSLog(@"TTNative::nativeAd:dislikeWithReason:");
    [self trackNativeAdClosed];
}

- (void)nativeExpressAdViewPlayerDidPlayFinish:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *)error {
    NSLog(@"TTNative::nativeAd:nativeExpressAdViewPlayerDidPlayFinish:");
    [self trackNativeAdVideoEnd];
}

Note: In this class, the native creative returned by the advertising platform needs to be mapped to the corresponding asset dictionary of TopOn in the callback. The specific key field description is as follows:

KeyRequiredTypeDescription
kATAdAssetsCustomEventKeyYESNSObjectAfter the ad is displayed, the object that receives the ad agency event
kATNativeADAssetsUnitIDKeyNONSStringCode ID of the third-party advertising platform
kATAdAssetsCustomObjectKeyYESidAdvertising objects (data) returned by third-party platforms

Native template information flow also requires mapping key:

keyrequiredtypedescription
kATNativeADAssetsIsExpressAdKeyYESBOOLType of native information flow ad, template ad must be set
kATNativeADAssetsNativeExpressAdViewWidthKeyNONSNumberThe width of the template ad view
kATNativeADAssetsNativeExpressAdViewHeightKeyNONSNumberThe height of the template ad view

Native self-rendering information flow also needs a mapped key, which can be obtained after mapping The corresponding value of the advertising offer is obtained. If the value is not needed or does not exist, you do not need to pass it in, as follows:

keyrequiredtypedescription
kATNativeADAssetsIsExpressAdKeyNOBOOLThe type of native information flow ad, the default is self-rendering ad type
kATNativeADAssetsMainTitleKeyNONSStringTitle of the ad
kATNativeADAssetsMainTextKeyNO NSStringDescription of the ad
kATNativeADAssetsIconURLKey NONSStringAdvertising icon image URL address
kATNativeADAssetsIconImageKeyNOUIImageAdvertising icon image
kATNativeADAssetsImageURLKeyNONSStringURL address of the large image of the advertisement
kATNativeADAssetsMainImageKeyNOUIImageLarge image of ad
kATNativeADAssetsCTATextKeyNONSStringcta copy of advertisement
kATNativeADAssetsRatingKeyNONSStringAd's rating score
kATNativeADAssetsAdvertiserKeyNONSStringAdvertiser
kATNativeADAssetsContainsVideoFlagNOBOOLWhether it is a video ad
kATNativeADAssetsLogoURLKeyNONSStringURL address of the logo image of the advertisement
kATNativeADAssetsLogoImageKeyNOUIImageAdvertising logo image

If the platform does not provide an image download method, you can use TopOn's internal encapsulation method. The specific reference is as follows:

 dispatch_group_enter(image_download_group);
        [[ATImageLoader shareLoader] loadImageWithURL:[NSURL URLWithString:nativeAd.data.icon.imageURL] completion:^(UIImage *image, NSError *error) {
            if ([image isKindOfClass:[UIImage class]]) { asset[kNativeADAssetsIconImageKey] = image; }
            dispatch_group_leave(image_download_group);
        }];


Previous
Banner ads
Next
Custom advanced configuration
Last modified: 2025-05-30Powered by