iOS IntegrationIOS SDK
HeheBid iOS SDK Integration Guide
Section titled “HeheBid iOS SDK Integration Guide”1. Overview
Section titled “1. Overview”HeheBid iOS SDK (HeheSDK) is a client SDK for commercial ad monetization. The current release supports:
| Ad format | Description |
|---|---|
| Banner | Fixed-size banner with optional auto-refresh |
| Interstitial | Full-screen interstitial; the app chooses when to show after a successful load |
| Native | Direct integration is self-rendered; mediation follows each platform’s native conventions (Adapter handles creative display) |
| Rewarded | Full-screen rewarded ad; reward info is delivered via callback after completion |
The SDK is distributed as an XCFramework, compatible with devices (arm64) and simulators (arm64 / x86_64), and can be used from both Objective-C and Swift projects. SDK / Adapter packages are distributed as XCFramework, support device and simulator, and can be used in Objective-C / Swift projects.
Distribution channels:
| Channel | URL |
|---|---|
| CocoaPods Spec Repo | https://github.com/hehesdk/ios-sdk-specs.git |
| SPM | https://github.com/hehesdk/ios-sdk-release |
| CDN binary | https://res.wooymoon.com/sdk/release/ios/ |
2. Prerequisites
Section titled “2. Prerequisites”Before integrating the iOS SDK, complete the following on the HeheBid platform:
- Register and complete account verification
- Create an app and obtain your App Key
- Create ad placements and obtain Placement IDs
3. Requirements
Section titled “3. Requirements”| Item | Minimum |
|---|---|
| iOS | 13.0+ |
| Xcode | 15.0+ |
| Language | Objective-C / Swift 5.0+ |
| Package manager (optional) | CocoaPods 1.12+ / Swift Package Manager |
4. SDK Integration
Section titled “4. SDK Integration”Choose one of the following integration methods.
4.1 CocoaPods (Recommended)
Section titled “4.1 CocoaPods (Recommended)”Use the private Spec Repo with the standalone HeheSDK pod (Core only):
platform :ios, '13.0'use_frameworks! :linkage => :static
source 'https://cdn.cocoapods.org/'source 'https://github.com/hehesdk/ios-sdk-specs.git'
target 'YourApp' do pod 'HeheSDK', '0.2.10'endpod install --repo-updateIn Target → Frameworks, Libraries, and Embedded Content, add HeheSDK.xcframework
- Set Embed & Sign
Open the project with
.xcworkspace.
The legacypod 'HeheAdSDK'is a full-package compatibility path; new integrations should useHeheSDKor the standalone Adapter pods in Section 13.
4.2 Swift Package Manager
Section titled “4.2 Swift Package Manager”- Xcode: File → Add Package Dependencies…
- Repository URL:
https://github.com/hehesdk/ios-sdk-release- Version recommendation: Exact Version
0.2.10(or Up to Next Minor per your team policy) - Add the
HeheSDKproduct to your app target (for direct integration, select this product only)
Package.swift example:
dependencies: [ .package(url: "https://github.com/hehesdk/ios-sdk-release", exact: "0.2.10")],targets: [ .target( name: "YourApp", dependencies: [ .product(name: "HeheSDK", package: "ios-sdk-release") ] )]4.3 Manual integration
Section titled “4.3 Manual integration”- Download:
HeheSDK-0.2.10.xcframework.zip - Unzip to get
HeheSDK.xcframework, then drag it into your project (check Copy items if needed) - In Target → Frameworks, Libraries, and Embedded Content, add
HeheSDK.xcframework- Set Embed & Sign
Then continue with Section 5: Xcode Project Configuration.
5. Xcode Project Configuration
Section titled “5. Xcode Project Configuration”Complete these steps regardless of integration method.
5.1 Embed & Sign
Section titled “5.1 Embed & Sign”- Select app Target → General
- Under Frameworks, Libraries, and Embedded Content, confirm
HeheSDK.xcframework(orHeheSDK) is present - Set Embed to Embed & Sign
5.2 Linker flags
Section titled “5.2 Linker flags”Under Target → Build Settings → Other Linker Flags, add:
-ObjC5.3 Import headers
Section titled “5.3 Import headers”Objective-C
#import <HeheSDK/HeheSDK.h>Swift
After adding HeheSDK to the target:
import HeheSDKIf Swift cannot resolve the module, add to your bridging header or Build Settings → Import Paths:
#import <HeheSDK/HeheSDK.h>#import <HeheSDK/HHRewardedAd.h>#import <HeheSDK/HHNativeAd.h>6. Privacy & Compliance
Section titled “6. Privacy & Compliance”Apply these settings before initSDK as required by your compliance policy (required for direct integration; also applicable on mediation paths when the app calls initSDK early):
| Method | Description |
|---|---|
setConsentStatus: |
GDPR consent status |
setIsAgeRestrictedUser: |
COPPA age-restricted user flag |
setDoNotSell: |
CCPA Do Not Sell setting |
SKAdNetwork identifiers, Privacy Manifest, and related items must be configured by the host app based on your ad stack and store requirements.
7. SDK Initialization
Section titled “7. SDK Initialization”Call initialization in application:didFinishLaunchingWithOptions: after privacy settings when applicable.
Load ads only after initialization succeeds. Check status with isInitialized.
Objective-C
Section titled “Objective-C”#import <HeheSDK/HeheSDK.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1. Privacy (as needed) [[HeheAds shareSDK] setConsentStatus:YES]; [[HeheAds shareSDK] setIsAgeRestrictedUser:NO]; [[HeheAds shareSDK] setDoNotSell:NO];
// 2. Enable logs during integration testing (see Section 12) // [[HeheAds shareSDK] setLogEnabled:YES];
// 3. Initialize [[HeheAds shareSDK] initSDK:@"YOUR_APP_KEY" onSuccess:^{ NSLog(@"HeheSDK initialized"); } onError:^(NSError *error) { NSLog(@"HeheSDK init failed: %@", error.localizedDescription); }];
return YES;}import UIKitimport HeheSDK
func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
HeheAds.shareSDK().setConsentStatus(true) HeheAds.shareSDK().setIsAgeRestrictedUser(false) HeheAds.shareSDK().setDoNotSell(false)
// HeheAds.shareSDK().setLogEnabled(true)
HeheAds.shareSDK().initSDK("YOUR_APP_KEY", onSuccess: { print("HeheSDK initialized") }, onError: { error in print("HeheSDK init failed: \(error.localizedDescription)") })
return true}8. Banner Ads
Section titled “8. Banner Ads”The following is the direct API. For mediation, use AdMob / TopOn official Banner APIs (see Section 13).
Supported sizes
Section titled “Supported sizes”| Enum | Size |
|---|---|
HHBannerAdSize320x50 / .size320x50 |
320 × 50 |
HHBannerAdSize320x100 / .size320x100 |
320 × 100 |
HHBannerAdSize300x250 / .size300x250 |
300 × 250 |
Integration flow
Section titled “Integration flow”- Create
HHBannerAd(Placement ID + size) - Set
delegate, and optionallyrefreshInterval(seconds;0means no auto-refresh) - Call
loadAd - In
bannerAdDidLoad:,addSubview:to your container (no need to set frame manually; the SDK centers by size in the parent view) - Call
destroywhen the page is dismissed or the ad is no longer needed (after destroy you cannotloadAdagain; create a new instance)
Objective-C
Section titled “Objective-C”@interface BannerViewController () <HHBannerAdDelegate>@property (nonatomic, strong) HHBannerAd *bannerAd;@end
@implementation BannerViewController
- (void)viewDidLoad { [super viewDidLoad];
self.bannerAd = [[HHBannerAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID" bannerSize:HHBannerAdSize320x50]; self.bannerAd.delegate = self; self.bannerAd.refreshInterval = 30; [self.bannerAd loadAd];}
- (void)bannerAdDidLoad:(HHBannerAd *)bannerAd { [self.view addSubview:bannerAd];}
- (void)bannerAd:(HHBannerAd *)bannerAd didFailWithError:(NSError *)error { NSLog(@"Banner load failed: %@", error.localizedDescription);}
- (void)bannerAdDidImpression:(HHBannerAd *)bannerAd { NSLog(@"Banner impression");}
- (void)bannerAdDidClick:(HHBannerAd *)bannerAd { NSLog(@"Banner click");}
- (void)bannerAdDidClose:(HHBannerAd *)bannerAd { NSLog(@"Banner closed");}
- (void)dealloc { [self.bannerAd destroy];}
@endclass BannerViewController: UIViewController, HHBannerAdDelegate {
private var bannerAd: HHBannerAd?
override func viewDidLoad() { super.viewDidLoad() let banner = HHBannerAd(placementID: "YOUR_PLACEMENT_ID", bannerSize: .size320x50) banner.delegate = self banner.refreshInterval = 30 banner.loadAd() bannerAd = banner }
func bannerAdDidLoad(_ bannerAd: HHBannerAd) { view.addSubview(bannerAd) }
func bannerAd(_ bannerAd: HHBannerAd, didFailWithError error: Error) { print("Banner load failed: \(error.localizedDescription)") }
deinit { bannerAd?.destroy() }}9. Interstitial Ads
Section titled “9. Interstitial Ads”The following is the direct API. For mediation, use AdMob / TopOn official interstitial APIs.
Integration flow
Section titled “Integration flow”Create HHInterstitialAd → loadAd → isReady == true → showAdFromViewController:To show again after close, call loadAd again. On page exit you may call destroy: to clear the corresponding placement cache.
Objective-C
Section titled “Objective-C”@interface InterstitialViewController () <HHInterstitialAdDelegate>@property (nonatomic, strong) HHInterstitialAd *interstitialAd;@end
@implementation InterstitialViewController
- (void)viewDidLoad { [super viewDidLoad]; self.interstitialAd = [[HHInterstitialAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"]; self.interstitialAd.delegate = self; [self.interstitialAd loadAd];}
- (IBAction)showInterstitial:(id)sender { if (self.interstitialAd.isReady) { [self.interstitialAd showAdFromViewController:self]; }}
- (void)interstitialAdDidLoad:(HHInterstitialAd *)interstitialAd { NSLog(@"Interstitial loaded");}
- (void)interstitialAd:(HHInterstitialAd *)interstitialAd didFailWithError:(NSError *)error { NSLog(@"Interstitial load failed: %@", error.localizedDescription);}
- (void)interstitialAdDidClose:(HHInterstitialAd *)interstitialAd { [self.interstitialAd loadAd]; // Preload next}
- (void)dealloc { [self.interstitialAd destroy:@[@"YOUR_PLACEMENT_ID"]];}
@endclass InterstitialViewController: UIViewController, HHInterstitialAdDelegate {
private var interstitialAd: HHInterstitialAd?
override func viewDidLoad() { super.viewDidLoad() let ad = HHInterstitialAd(placementID: "YOUR_PLACEMENT_ID") ad.delegate = self ad.loadAd() interstitialAd = ad }
@IBAction func showInterstitial(_ sender: Any) { guard let ad = interstitialAd, ad.isReady else { return } ad.showAdFromViewController(self) }
func interstitialAdDidClose(_ interstitialAd: HHInterstitialAd) { interstitialAd.loadAd() }
deinit { interstitialAd?.destroy(["YOUR_PLACEMENT_ID"]) }}You can also call
showAdFromRootViewControllerto present from an appropriate window root view controller.
10. Native Ads (Self-Rendered)
Section titled “10. Native Ads (Self-Rendered)”The following is the direct API. For mediation, use each platform’s official native API (see Section 13). Adapters download and assemble main image / icon; the app should not call
HHNativeAdViewdirectly on mediation paths.
Integration flow
Section titled “Integration flow”- Create
HHNativeAdViewand setdelegate - First
addSubviewto your page container, thenloadAd - In
nativeAdViewDidLoad:, readadMaterialand build subviews inside that View - Impression and click navigation are handled automatically by the SDK on the container—no extra click-view registration
- Call
destroywhen the page is dismissed
Creative HHNativeAdMaterial
Section titled “Creative HHNativeAdMaterial”| Property | Description |
|---|---|
title |
Title |
desc |
Description (optional) |
iconURL |
Icon URL (app downloads and displays) |
imageURL |
Main image URL (optional; app downloads and displays) |
ctaText |
Call-to-action text |
rating |
Rating 0–5; 0 means no rating |
Objective-C
Section titled “Objective-C”- (void)loadNativeAd { HHNativeAdView *adView = [[HHNativeAdView alloc] initWithPlacementID:@"YOUR_NATIVE_PLACEMENT_ID"]; adView.delegate = self; adView.frame = self.nativeContainer.bounds; adView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.nativeContainer addSubview:adView]; self.nativeAdView = adView; [adView loadAd];}
- (void)nativeAdViewDidLoad:(HHNativeAdView *)nativeAdView { HHNativeAdMaterial *material = nativeAdView.adMaterial; if (material == nil) { return; } // Build title / icon / main image / CTA inside nativeAdView [self buildNativeContentInAdView:nativeAdView material:material];}
- (void)nativeAdView:(HHNativeAdView *)nativeAdView didFailWithError:(NSError *)error { NSLog(@"Native ad load failed: %@", error.localizedDescription);}
- (void)dealloc { [self.nativeAdView destroy];}func loadNativeAd() { let adView = HHNativeAdView(placementID: "YOUR_NATIVE_PLACEMENT_ID") adView.delegate = self adView.frame = nativeContainer.bounds adView.autoresizingMask = [.flexibleWidth, .flexibleHeight] nativeContainer.addSubview(adView) nativeAdView = adView adView.loadAd()}
func nativeAdViewDidLoad(_ nativeAdView: HHNativeAdView) { guard let material = nativeAdView.adMaterial else { return } buildNativeContent(in: nativeAdView, material: material)}
deinit { nativeAdView?.destroy()}11. Rewarded Ads
Section titled “11. Rewarded Ads”The following is the direct API. For mediation, use AdMob / TopOn official rewarded APIs.
Integration flow
Section titled “Integration flow”Create HHRewardedAd (placementID + userID + customData?) → loadAd → isReady → showAdFromViewController: → didRewardWithInfo: / didFailToRewardWithError:userIDis required; emptyuserIDcausesloadAdto failcustomDatais optional and is passed through to the reward result- Confirm
isReady == truebefore showing - After the user meets reward criteria,
didRewardWithInfo:is called; otherwisedidFailToRewardWithError:
Reward result HHAdRewardInfo
Section titled “Reward result HHAdRewardInfo”| Property | Description |
|---|---|
userID |
User ID passed at creation |
userCustomData |
Custom data passed at creation (nil if not provided) |
name |
Reward name |
amount |
Reward amount |
serverSideVerify |
Whether reward is verified server-side; when YES, prefer server notification for granting |
canEarnReward |
Whether the reward can be granted (typically YES on success callback) |
Objective-C
Section titled “Objective-C”- (void)loadRewardedAd { self.rewardedAd = [[HHRewardedAd alloc] initWithPlacementID:@"YOUR_REWARDED_PLACEMENT_ID" userID:@"YOUR_USER_ID" customData:nil]; self.rewardedAd.delegate = self; [self.rewardedAd loadAd];}
- (IBAction)showRewarded:(id)sender { if (self.rewardedAd.isReady) { [self.rewardedAd showAdFromViewController:self]; }}
- (void)rewardedAd:(HHRewardedAd *)rewardedAd didRewardWithInfo:(HHAdRewardInfo *)rewardInfo { if (rewardInfo.canEarnReward) { // Grant reward; when serverSideVerify is YES, prefer server-side granting NSLog(@"Reward %@ x %ld", rewardInfo.name, (long)rewardInfo.amount); }}
- (void)rewardedAd:(HHRewardedAd *)rewardedAd didFailToRewardWithError:(NSError *)error { NSLog(@"Reward not earned: %@", error.localizedDescription);}
- (void)rewardedAdDidClose:(HHRewardedAd *)rewardedAd { [self.rewardedAd loadAd];}
- (void)dealloc { [self.rewardedAd destroy:@[@"YOUR_REWARDED_PLACEMENT_ID"]];}func loadRewardedAd() { let ad = HHRewardedAd(placementID: "YOUR_REWARDED_PLACEMENT_ID", userID: "YOUR_USER_ID", customData: nil) ad.delegate = self ad.loadAd() rewardedAd = ad}
@IBAction func showRewarded(_ sender: Any) { guard let ad = rewardedAd, ad.isReady else { return } ad.showAdFromViewController(self)}
func rewardedAd(_ rewardedAd: HHRewardedAd, didRewardWithInfo rewardInfo: HHAdRewardInfo) { guard rewardInfo.canEarnReward else { return } print("Reward \(rewardInfo.name) x \(rewardInfo.amount)")}
deinit { rewardedAd?.destroy(["YOUR_REWARDED_PLACEMENT_ID"])}12. Integration Helpers
Section titled “12. Integration Helpers”Test device IDFA
Section titled “Test device IDFA”Set before initSDK, and register the same IDFA as a test device on the HEHE developer platform:
[[HeheAds shareSDK] setTestDeviceIDFA:@"YOUR_DEVICE_IDFA"];HeheAds.shareSDK().setTestDeviceIDFA("YOUR_DEVICE_IDFA")Pass nil or an empty string to clear.
Debug logging
Section titled “Debug logging”Enable during integration; disable for production builds:
[[HeheAds shareSDK] setLogEnabled:YES];HeheAds.shareSDK().setLogEnabled(true)13. Integration Checklist
Section titled “13. Integration Checklist”Before release, confirm:
- App Key and Placement IDs obtained
- HeheSDK integrated (CocoaPods / SPM / manual), version 0.2.10+
-
-ObjCadded to Other Linker Flags - Privacy APIs set before
initSDKas needed -
loadAdcalled only after successful initialization -
isReadychecked before showing interstitial / rewarded -
destroycalled when Banner / Native pages are dismissed; calldestroy:for interstitial / rewarded as needed - Non-empty
userIDpassed for rewarded ads - Native ads self-rendered inside
HHNativeAdViewand added to the view hierarchy - Full load → display → click flow verified on a real device
Appendix: Delegate Callbacks
Section titled “Appendix: Delegate Callbacks”HHBannerAdDelegate
Section titled “HHBannerAdDelegate”| Callback | When |
|---|---|
bannerAdDidLoad: |
Ad loaded successfully |
bannerAd:didFailWithError: |
Ad load failed |
bannerAdDidImpression: |
Ad impression logged |
bannerAdDidClick: |
User clicked the ad |
bannerAdDidLeaveApp: |
User left the app after click |
bannerAdDidClose: |
User closed the banner |
HHInterstitialAdDelegate
Section titled “HHInterstitialAdDelegate”| Callback | When |
|---|---|
interstitialAdDidLoad: |
Ad loaded successfully |
interstitialAd:didFailWithError: |
Ad load failed |
interstitialAd:displayFailWithError: |
Ad display failed |
interstitialAdWillLogImpression: |
Ad impression logged |
interstitialAdDidClick: |
User clicked the ad |
interstitialAdWillClose: |
Ad about to close |
interstitialAdDidClose: |
Ad closed |
HHNativeAdDelegate
Section titled “HHNativeAdDelegate”| Callback | When |
|---|---|
nativeAdDidLoad: |
Ad loaded successfully; adMaterial is available |
nativeAd:didFailWithError: |
Ad load failed |
nativeAdDidImpression: |
Ad impression logged |
nativeAdDidClick: |
User clicked the ad |
nativeAdDidLeaveApp: |
User left the app after click |
HHRewardedAdDelegate
Section titled “HHRewardedAdDelegate”| Callback | When |
|---|---|
rewardedAdDidLoad: |
Ad loaded successfully |
rewardedAd:didFailWithError: |
Ad load failed |
rewardedAd:displayFailWithError: |
Ad display failed |
rewardedAdWillLogImpression: |
Ad impression logged |
rewardedAdDidClick: |
User clicked the ad |
rewardedAdWillClose: |
Ad about to close |
rewardedAdDidClose: |
Ad closed |
rewardedAd:didRewardWithInfo: |
User earned the reward |
rewardedAd:didFailToRewardWithError: |
Reward not earned |
Public API types
Section titled “Public API types”| Class | Description |
|---|---|
HeheAds |
SDK global entry (initialization, privacy settings) |
HHBannerAd |
Banner ad |
HHInterstitialAd |
Interstitial ad |
HHRewardedAd |
Rewarded ad |
HHNativeAd |
Native ad (self-rendered) |
HHNativeAdMaterial |
Native self-rendered creative |
HHAdRewardInfo |
Reward result info |
Support: For integration issues, contact HeheBid technical support or your account manager.