跳转到内容

iOS 集成iOS

HeheBid iOS SDK(HeheSDK)是面向商业级广告变现场景的客户端 SDK,当前版本支持以下广告形态:

广告类型 说明
Banner(横幅) 固定尺寸横幅,支持自动刷新
Interstitial(插页) 全屏插页,加载成功后由 App 择机展示
Native(原生) 直连为自渲染;聚合侧按各平台原生规范接入(Adapter 负责素材展示)
Rewarded(激励) 全屏激励广告,完成后回调发奖信息

SDK 以 XCFramework 形式分发,兼容真机(arm64)与模拟器(arm64 / x86_64),可在 Objective-C 与 Swift 工程中直接调用。 SDK / Adapter 以 XCFramework 分发,支持真机与模拟器,可在 Objective-C / Swift 工程中使用。

分发地址:

渠道 地址
CocoaPods Spec Repo https://github.com/hehesdk/ios-sdk-specs.git
SPM https://github.com/hehesdk/ios-sdk-release
CDN 二进制 https://res.wooymoon.com/sdk/release/ios/

在开始 iOS SDK 集成前,请确保您已在 HeheBid 平台完成以下步骤:

  1. 注册并完成账户认证
  2. 创建应用并获取 App Key
  3. 创建广告位并获取广告位 ID(Placement ID)

项目 最低要求
iOS 系统版本 iOS 13.0+
Xcode 15.0+
开发语言 Objective-C / Swift 5.0+
包管理工具(可选) CocoaPods 1.12+ / Swift Package Manager

根据项目情况,选择以下任意一种方式集成 SDK。

使用私有 Spec Repo + 独立 Pod HeheSDK(仅下载 Core):

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'
end
终端窗口
pod install --repo-update

在 Target → Frameworks, Libraries, and Embedded Content 中添加 HeheSDK.xcframework

  • 设置 Embed & Sign

请使用 .xcworkspace 打开工程。
废弃写法 pod 'HeheAdSDK' 为整包兼容,新接入请使用 HeheSDK 或第 13 节独立 Adapter Pod。

  1. Xcode:File → Add Package Dependencies…
  2. 仓库地址:
https://github.com/hehesdk/ios-sdk-release
  1. 版本建议:Exact Version 0.2.10(或按团队策略选择 Up to Next Minor)
  2. 将 Product HeheSDK 添加到 App Target(直连仅勾选此项)

Package.swift 示例:

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")
]
)
]
  1. 下载:
    HeheSDK-0.2.10.xcframework.zip
  2. 解压得到 HeheSDK.xcframework,拖入工程(勾选 Copy items if needed)
  3. 在 Target → Frameworks, Libraries, and Embedded Content 中添加 HeheSDK.xcframework
    • 设置 Embed & Sign

完成后继续完成第 5 节工程配置。


无论采用何种集成方式,请完成以下工程配置。

  1. 选中 App Target → General
  2. 在 Frameworks, Libraries, and Embedded Content 中确认已包含 HeheSDK.xcframework(或 HeheSDK)
  3. 将 Embed 选项设置为 Embed & Sign

在 Target → Build Settings → Other Linker Flags 中添加:

-ObjC

Objective-C

#import <HeheSDK/HeheSDK.h>

Swift

在 Target 中已添加 HeheSDK 后,直接:

import HeheSDK

如 Swift 无法识别模块,可在 Target 的 Build Settings → Import Paths 或 Bridging Header 中补充:

YourApp-Bridging-Header.h
#import <HeheSDK/HeheSDK.h>
#import <HeheSDK/HHRewardedAd.h>
#import <HeheSDK/HHNativeAd.h>

建议在 initSDK 之前按业务合规要求设置(直连必用;聚合路径下 App 若提前调用 initSDK 时同样适用):

方法 用途
setConsentStatus: GDPR 用户同意状态
setIsAgeRestrictedUser: COPPA 年龄限制标识
setDoNotSell: CCPA Do Not Sell

SKAdNetwork 标识符、Privacy Manifest 等由 宿主 App 按投放与商店要求自行配置。


建议在 application:didFinishLaunchingWithOptions: 中、隐私配置完成后调用。
请在初始化成功后再请求广告。 可用 isInitialized 查询状态。

#import <HeheSDK/HeheSDK.h>
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1. 隐私(按需)
[[HeheAds shareSDK] setConsentStatus:YES];
[[HeheAds shareSDK] setIsAgeRestrictedUser:NO];
[[HeheAds shareSDK] setDoNotSell:NO];
// 2. 联调可开日志(见第 12 节)
// [[HeheAds shareSDK] setLogEnabled:YES];
// 3. 初始化
[[HeheAds shareSDK] initSDK:@"YOUR_APP_KEY"
onSuccess:^{
NSLog(@"HeheSDK 初始化成功");
}
onError:^(NSError *error) {
NSLog(@"HeheSDK 初始化失败: %@", error.localizedDescription);
}];
return YES;
}
import UIKit
import 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 初始化成功")
}, onError: { error in
print("HeheSDK 初始化失败: \(error.localizedDescription)")
})
return true
}

以下为 直连 API。聚合请使用 AdMob / TopOn 官方 Banner API,见第 13 节。

枚举 尺寸
HHBannerAdSize320x50 / .size320x50 320 × 50
HHBannerAdSize320x100 / .size320x100 320 × 100
HHBannerAdSize300x250 / .size300x250 300 × 250
  1. 创建 HHBannerAd(Placement ID + 尺寸)
  2. 设置 delegate,按需设置 refreshInterval(秒;0 表示不自动刷新)
  3. 调用 loadAd
  4. 在 bannerAdDidLoad: 中 addSubview: 到容器(无需手动设 frame,SDK 按尺寸在父视图中居中)
  5. 页面销毁或不再需要时调用 destroy(销毁后不可再 loadAd,需重新创建对象)
@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 加载失败: %@", error.localizedDescription);
}
- (void)bannerAdDidImpression:(HHBannerAd *)bannerAd {
NSLog(@"Banner 曝光");
}
- (void)bannerAdDidClick:(HHBannerAd *)bannerAd {
NSLog(@"Banner 点击");
}
- (void)bannerAdDidClose:(HHBannerAd *)bannerAd {
NSLog(@"Banner 关闭");
}
- (void)dealloc {
[self.bannerAd destroy];
}
@end
class 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 加载失败: \(error.localizedDescription)")
}
deinit {
bannerAd?.destroy()
}
}

以下为 直连 API。聚合请使用 AdMob / TopOn 官方插页 API。

创建 HHInterstitialAd → loadAd → isReady == true → showAdFromViewController:

关闭后如需再次展示,请重新 loadAd。页面退出时可 destroy: 清理对应广告位缓存。

@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(@"插页加载成功");
}
- (void)interstitialAd:(HHInterstitialAd *)interstitialAd didFailWithError:(NSError *)error {
NSLog(@"插页加载失败: %@", error.localizedDescription);
}
- (void)interstitialAdDidClose:(HHInterstitialAd *)interstitialAd {
[self.interstitialAd loadAd]; // 预加载下一次
}
- (void)dealloc {
[self.interstitialAd destroy:@[@"YOUR_PLACEMENT_ID"]];
}
@end
class 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"])
}
}

也可调用 showAdFromRootViewController,在合适窗口根控制器上展示。


以下为 直连 API。聚合请使用各平台官方原生 API(见第 13 节);Adapter 会下载并组装主图 / 图标,业务层勿再直连 HHNativeAdView。

  1. 创建 HHNativeAdView,设置 delegate
  2. 先 addSubview 到页面容器,再 loadAd
  3. 在 nativeAdViewDidLoad: 中读取 adMaterial,在 该 View 内部 搭建子视图
  4. 曝光与点击跳转由 SDK 在容器上自动处理,无需额外注册点击视图
  5. 页面销毁时调用 destroy
属性 说明
title 标题
desc 描述(可选)
iconURL 图标 URL(App 自行下载展示)
imageURL 主图 URL(可选,App 自行下载展示)
ctaText 行动号召文案
rating 评分 0~5;0 表示无评分
- (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; }
// 在 nativeAdView 内搭建标题 / 图标 / 主图 / CTA 等
[self buildNativeContentInAdView:nativeAdView material:material];
}
- (void)nativeAdView:(HHNativeAdView *)nativeAdView didFailWithError:(NSError *)error {
NSLog(@"原生广告加载失败: %@", 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()
}

以下为 直连 API。聚合请使用 AdMob / TopOn 官方激励 API。

创建 HHRewardedAd(placementID + userID + customData?)
→ loadAd → isReady → showAdFromViewController:
→ didRewardWithInfo: / didFailToRewardWithError:
  • userID 必填;为空时 loadAd 会失败
  • customData 可选,会透传到激励结果
  • 展示前请确认 isReady == true
  • 用户完成激励条件后回调 didRewardWithInfo:;未达成则回调 didFailToRewardWithError:
属性 说明
userID 创建时传入的用户 ID
userCustomData 创建时传入的自定义数据(未传则为 nil)
name 奖励名称
amount 奖励数量
serverSideVerify 是否由服务端校验发奖;为 YES 时建议以服务端通知为准
canEarnReward 是否可发奖(成功回调时一般为 YES)
- (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) {
// 向用户发奖;serverSideVerify 为 YES 时建议依赖服务端
NSLog(@"奖励 %@ x %ld", rewardInfo.name, (long)rewardInfo.amount);
}
}
- (void)rewardedAd:(HHRewardedAd *)rewardedAd didFailToRewardWithError:(NSError *)error {
NSLog(@"激励未达成: %@", 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("奖励 \(rewardInfo.name) x \(rewardInfo.amount)")
}
deinit {
rewardedAd?.destroy(["YOUR_REWARDED_PLACEMENT_ID"])
}

在 initSDK 之前设置,并在 HEHE 开发者平台将同一 IDFA 登记为测试设备:

[[HeheAds shareSDK] setTestDeviceIDFA:@"YOUR_DEVICE_IDFA"];
HeheAds.shareSDK().setTestDeviceIDFA("YOUR_DEVICE_IDFA")

传 nil 或空串可清除。

联调可开启,正式包建议关闭:

[[HeheAds shareSDK] setLogEnabled:YES];
HeheAds.shareSDK().setLogEnabled(true)

上线前请逐项确认:

  • 已获取 App Key 与各广告位 Placement ID
  • 已集成 HeheSDK(CocoaPods / SPM / 手动),版本 0.2.10+
  • Other Linker Flags 已加 -ObjC
  • 隐私相关 API 已在 initSDK 前按需设置
  • 初始化成功后再 loadAd
  • 插页 / 激励展示前检查 isReady
  • Banner / 原生页面退出时调用 destroy;插页 / 激励按需 destroy:
  • 激励广告已传入非空 userID
  • 原生广告在 HHNativeAdView 内自渲染,并已加入视图树
  • 真机完成加载、展示、点击全流程验证

回调 触发时机
bannerAdDidLoad: 广告加载成功
bannerAd:didFailWithError: 广告加载失败
bannerAdDidImpression: 广告已曝光
bannerAdDidClick: 用户点击广告
bannerAdDidLeaveApp: 点击后离开 App
bannerAdDidClose: 用户关闭 Banner
回调 触发时机
interstitialAdDidLoad: 广告加载成功
interstitialAd:didFailWithError: 广告加载失败
interstitialAd:displayFailWithError: 广告展示失败
interstitialAdWillLogImpression: 广告已曝光
interstitialAdDidClick: 用户点击广告
interstitialAdWillClose: 广告即将关闭
interstitialAdDidClose: 广告已关闭
回调 触发时机
nativeAdDidLoad: 广告加载成功,可获取 adMaterial
nativeAd:didFailWithError: 广告加载失败
nativeAdDidImpression: 广告已曝光
nativeAdDidClick: 用户点击广告
nativeAdDidLeaveApp: 点击后离开 App
回调 触发时机
rewardedAdDidLoad: 广告加载成功
rewardedAd:didFailWithError: 广告加载失败
rewardedAd:displayFailWithError: 广告展示失败
rewardedAdWillLogImpression: 广告已曝光
rewardedAdDidClick: 用户点击广告
rewardedAdWillClose: 广告即将关闭
rewardedAdDidClose: 广告已关闭
rewardedAd:didRewardWithInfo: 用户获得激励
rewardedAd:didFailToRewardWithError: 激励未达成
类名 说明
HeheAds SDK 全局入口(初始化、隐私配置)
HHBannerAd Banner 广告
HHInterstitialAd 插页广告
HHRewardedAd 激励广告广告
HHNativeAd 原生广告(自渲染)
HHNativeAdMaterial 原生自渲染素材
HHAdRewardInfo 激励结果信息

技术支持:如有接入问题,请联系 HeheBid 技术支持或您的专属运营对接人。