npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-topon

v0.1.7

Published

topon sdk

Downloads

19

Readme

react-native-topon

React Native TurboModule 封装的 TopOn (Anythink) SDK 接入方案,支持激励视频、插屏、Banner、开屏、原生等广告能力。

环境要求

  • Node.js ≥ 20(示例工程使用 Yarn 3)
  • React Native ≥ 0.81(TurboModule 新架构)
  • Android:AGP 8.7.x、compileSdk 36、minSdk 24

安装

yarn add react-native-topon

安装后需要运行一次 Codegen 生成 TurboModule 绑定:

yarn react-native codegen

快速开始

TopOn 模块分为两个层面:

  • SDK:负责初始化、GDPR、日志开关等全局配置。
  • RewardedVideo / Interstitial / Banner / Splash / Native:提供各广告位的加载、展示、状态查询方法。
import Topon, {
  SDK,
  RewardedVideo,
  Interstitial,
  Banner,
  Splash,
  Native,
  NativeAdView,
  ToponEvents,
} from 'react-native-topon';
import { NativeEventEmitter } from 'react-native';

// SDK 初始化
SDK.init('your-app-id', 'your-app-key');

// 订阅事件
const emitter = new NativeEventEmitter(Topon.NativeModule);
const subscription = emitter.addListener(ToponEvents.RewardedVideo.Loaded, payload => {
  console.log('Rewarded loaded', payload.placementId);
});

// 激励广告示例
RewardedVideo.loadAd('placement-id', { userID: 'user-1' });
const isReady = await RewardedVideo.hasAdReady('placement-id');
if (isReady) {
  RewardedVideo.showAd('placement-id');
}

const status = await RewardedVideo.checkAdStatus('placement-id');
console.log('Rewarded status', status?.isReady);

// 组件卸载时移除监听
subscription.remove();

详细 API 请查看 src/index.tsx 中的导出定义,或参考下方表格。

支持的广告类型与平台

| 广告类型 | 目标平台 | 说明 | | --- | --- | --- | | RewardedVideo | Android / iOS | 激励视频,标准激励流程 | | Interstitial | Android / iOS | 插屏广告 | | Banner | Android / iOS | 横幅广告 | | Splash | Android / iOS | 开屏广告 | | Native | Android / iOS | 原生自渲染广告,需要自定义布局 |

各广告模块在 JS 侧的 API 形式保持一致(loadAd / hasAdReady / showAd / checkAdStatus),便于横向复用。

开屏广告接入(Splash)

目标平台:Android / iOS

  1. 按照本 README 的 Android / iOS 集成说明,引入 AnyThinkSplash(iOS)或 splash-tpn(Android)依赖。
  2. JS 侧调用方式与其他广告一致:先 loadAd,再判断 hasAdReady,最后 showAd
import { Splash } from 'react-native-topon';

Splash.loadAd('splash-placement-id', {
  tolerateTimeout: 5000,
});

const isReady = await Splash.hasAdReady('splash-placement-id');
if (isReady) {
  Splash.showAd('splash-placement-id');
}
  1. 事件回调使用 ToponEvents.Splash.*Loaded / LoadFail / Timeout / Show / Click / Close),可按需监听首屏展示与超时等状态。

原生广告接入(Native)

目标平台:Android / iOS

  1. 按照本 README 的 Android / iOS 集成说明,引入 AnyThinkNative(iOS)或 nativead-tpn(Android)依赖。
  2. 原生广告采用 自渲染布局:用 NativeAdView 作为容器,自定义 RN 组件布局。
  3. 布局完成后,将各子组件的 viewTag 传给 Native.showAd 进行绑定。
import React, { useRef } from 'react';
import { findNodeHandle, Image, Text } from 'react-native';
import { Native, NativeAdView } from 'react-native-topon';

const nativeViewRef = useRef<NativeAdView>(null);
const titleRef = useRef<Text>(null);
const descRef = useRef<Text>(null);
const iconRef = useRef<Image>(null);
const ctaRef = useRef<Text>(null);

Native.loadAd('native-placement-id', { width: 320, height: 250 });

const bindNativeAd = () => {
  const viewRefs = {
    parent: findNodeHandle(nativeViewRef.current) ?? 0,
    title: findNodeHandle(titleRef.current) ?? 0,
    desc: findNodeHandle(descRef.current) ?? 0,
    icon: findNodeHandle(iconRef.current) ?? 0,
    cta: findNodeHandle(ctaRef.current) ?? 0,
  };
  Native.showAd('native-placement-id', viewRefs);
};

return (
  <NativeAdView ref={nativeViewRef} onLayout={bindNativeAd}>
    <Image ref={iconRef} />
    <Text ref={titleRef} />
    <Text ref={descRef} />
    <Text ref={ctaRef} />
  </NativeAdView>
);
  1. 若需要素材数据,可调用 Native.getAdMaterial,或监听 ToponEvents.Native.Show 回调中的 adMaterial 字段。
  2. 组件卸载时调用 Native.removeAd 释放绑定。

API 总览

SDK

| 方法 | 说明 | | --- | --- | | init(appId, appKey) | 初始化 SDK,必须在所有广告调用前执行一次 | | setLogDebug(isDebug) | 打开/关闭原生日志输出,便于调试 | | getSDKVersionName() | 返回当前 TopOn SDK 版本号 | | isCnSDK() | 判断是否为国内 SDK | | setExcludeMyOfferPkgList(packages) | 排除 MyOffer 包名黑名单 | | initCustomMap(customMap) / setPlacementCustomMap(placementId, map) | 设置全局或广告位级别的扩展参数 | | setGDPRLevel(level) / getGDPRLevel() / getUserLocation() / showGDPRAuth() / showGDPRConsentDialog(appId) / showGDPRConsentSecondDialog(appId) / setUMPTestDeviceId(deviceId) | GDPR 相关 API | | deniedUploadDeviceInfo(keys) | 拒绝上传指定设备信息字段 |

RewardedVideo / Interstitial

| 方法 | 说明 | | --- | --- | | loadAd(placementId, settings?) | 加载广告,settings 可包含 userIDmedia_extcustom_rule 等 TopOn 字段 | | showAd(placementId) / showAdInScenario(placementId, scenario) | 展示广告,可按需指定 scenario | | hasAdReady(placementId) | 返回该广告位当前是否可播放 | | checkAdStatus(placementId) | 返回 ToponAdStatusisLoadingisReadyadInfo),便于诊断 |

建议在收到 Loaded 事件后再调用 hasAdReadycheckAdStatus,避免频繁轮询。

Banner

| 方法 | 说明 | | --- | --- | | loadAd(placementId, settings?) | 加载 Banner;settings 支持 widthheightadaptive_type 等键 | | showAdInRectangle(placementId, rect) | 以 { x, y, width, height } 指定展示区域 | | showAdInPosition(placementId, position) | position 取值 top/bottom | | showAdInRectangleAndScenario / showAdInPositionAndScenario | 在指定场景中展示 | | hideAd / reShowAd / removeAd | 控制 Banner 显示、隐藏与彻底移除 | | hasAdReady / checkAdStatus | 查询加载状态信息 |

Splash

| 方法 | 说明 | | --- | --- | | loadAd(placementId, settings?) | 加载开屏;settings 支持 tolerateTimeout(毫秒)等字段 | | showAd / showAdInScenario | 展示开屏,可按需指定 scenario | | hasAdReady / checkAdStatus | 查询加载状态信息 |

Native

| 方法 | 说明 | | --- | --- | | loadAd(placementId, settings?) | 加载原生;settings 支持 widthheightadaptive_height 等 | | showAd(placementId, viewRefs) / showAdInScenario | 绑定自渲染布局并展示(viewRefs 见下文) | | hasAdReady / checkAdStatus | 查询加载状态信息 | | getAdMaterial | 获取原生素材信息(JSON) | | removeAd | 从容器中移除原生广告 |

Native viewRefs 说明

viewRefs 用于把原生广告素材绑定到你自定义的 RN 组件上:

  • parent必填NativeAdView 容器的 viewTag
  • title / desc / cta / icon / mainImage / adLogo / dislike:可选,对应素材展示控件

建议在布局完成后再调用 Native.showAd,例如在 onLayoutrequestAnimationFrame 中获取 viewTag。

事件监听

TopOn 模块通过 ToponEvents 常量暴露所有回调,配合 NativeEventEmitter 使用即可:

import { NativeEventEmitter } from 'react-native';
import Topon, { ToponEvents } from 'react-native-topon';

const emitter = new NativeEventEmitter(Topon.NativeModule);
const subscriptions = [
  emitter.addListener(ToponEvents.RewardedVideo.Loaded, payload => {
    console.log('激励加载成功', payload.placementId);
  }),
  emitter.addListener(ToponEvents.RewardedVideo.LoadFail, payload => {
    console.warn('激励加载失败', payload.errorMsg);
  }),
  emitter.addListener(ToponEvents.RewardedVideo.Close, payload => {
    console.log('激励关闭', payload.placementId);
  }),
];

// 组件卸载时清理
return () => subscriptions.forEach(sub => sub.remove());

可监听的事件名称:

  • RewardedVideoLoadedLoadFailPlayStartPlayEndPlayFailCloseClickReward
  • InterstitialLoadedLoadFailPlayStartPlayEndPlayFailCloseClickShow
  • BannerLoadedLoadFailCloseClickShowRefreshRefreshFail
  • SplashLoadedLoadFailTimeoutShowClickClose
  • NativeLoadedLoadFailShowClickCloseVideoStartVideoEndVideoProgress

事件回调默认携带 { placementId, adCallbackInfo? };失败类事件额外包含 errorMsg,原生 Show 回调额外包含 adMaterial(素材 JSON),具体类型定义请参考 ToponRewardedEventPayload 等 TypeScript 类型。

示例工程

仓库提供了一个最小示例(example workspace)。运行前先在 example/src/App.tsx 填写自身的 AppId / AppKey 以及广告位 ID:

SDK.init('your-app-id', 'your-app-key');

RewardedVideo.loadAd('reward-placement-id', {
  userID: 'demo-user',
  media_ext: 'demo',
});

Banner.loadAd('banner-placement-id', {
  width: 320,
  height: 50,
  adaptive_type: 0,
});

Splash.loadAd('splash-placement-id', {
  tolerateTimeout: 5000,
});

// 原生广告:先加载,再在自定义布局中绑定 viewRefs
Native.loadAd('native-placement-id', {
  width: 320,
  height: 250,
});

// 插屏广告需要真实的插屏位 ID
// Interstitial.loadAd('interstitial-placement-id');

原生广告绑定自渲染布局示例:

import React, { useMemo, useRef } from 'react';
import { findNodeHandle, Image, Text } from 'react-native';
import { Native, NativeAdView } from 'react-native-topon';

const nativeViewRef = useRef<NativeAdView>(null);
const titleRef = useRef<Text>(null);
const descRef = useRef<Text>(null);
const iconRef = useRef<Image>(null);
const ctaRef = useRef<Text>(null);

const viewRefs = useMemo(() => ({
  parent: findNodeHandle(nativeViewRef.current) ?? 0,
  title: findNodeHandle(titleRef.current) ?? 0,
  desc: findNodeHandle(descRef.current) ?? 0,
  icon: findNodeHandle(iconRef.current) ?? 0,
  cta: findNodeHandle(ctaRef.current) ?? 0,
}), []);

Native.showAd('native-placement-id', viewRefs);

return (
  <NativeAdView ref={nativeViewRef}>
    <Image ref={iconRef} />
    <Text ref={titleRef} />
    <Text ref={descRef} />
    <Text ref={ctaRef} />
  </NativeAdView>
);

然后依次执行:

yarn install
yarn example              # 启动 Metro
yarn run android --port=4321

应用会在界面上输出各广告位的事件日志。若出现 Invalid placement,请检查后台状态与参数是否一致。

Android 集成说明

1. 仓库地址

TopOn 官方依赖托管在 overseas_sdk 仓库,宿主 App 的 android/build.gradle(Project 级)需要额外声明:

allprojects {
  repositories {
    maven { url "https://jfrog.anythinktech.com/artifactory/overseas_sdk" }
    maven { url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" } // 如使用 Mintegral
    flatDir { dirs "$rootDir/libs" } // 若需手动放置本地 AAR
  }
}

2. 依赖管理

由于仓库样例处于离线环境,库模块默认引用了 reactnative_sdk_output/Android/bridge_android/library/anythink_reactnativejs_bridge.aar。在真实项目中请改为使用 TopOn 官方 Maven 依赖,例如:

dependencies {
  implementation "com.anythink.sdk:core-tpn:6.5.10"
  implementation "com.anythink.sdk:banner-tpn:6.5.10"
  implementation "com.anythink.sdk:interstitial-tpn:6.5.10"
  implementation "com.anythink.sdk:rewardedvideo-tpn:6.5.10"
  implementation "com.anythink.sdk:nativead-tpn:6.5.10"
  implementation "com.anythink.sdk:splash-tpn:6.5.10"
  implementation "com.anythink.sdk:tramini-plugin-tpn:6.5.10"

  // 广告网络适配器(示例)
  implementation "com.anythink.sdk:adapter-tpn-admob:6.5.10"
  implementation "com.google.android.gms:play-services-ads:24.4.0"
  implementation "com.anythink.sdk:adapter-tpn-facebook:6.5.10"
  implementation "com.facebook.android:audience-network-sdk:6.20.0"
  // ... 根据后台配置决定
}

⚠️ 请严格与 TopOn 后台配置保持一致;离线开发时,可将官方 SDK AAR 放入 android/libs 并通过 implementation files('libs/xxx.aar') 引用。

如果集成 AdMob,请为宿主应用添加 com.google.android.gms.ads.APPLICATION_ID 元信息。调试阶段可使用 Google 提供的测试 ID:

<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-3940256099942544~3347511713" />

生产包请务必替换为自己的 AdMob App ID。

3. Manifest 配置

库模块会自动合并以下节点,如宿主 App 有自定义 application,请确保未被覆盖:

<uses-library
    android:name="org.apache.http.legacy"
    android:required="false" />

<meta-data
    android:name="com.google.android.gms.ads.AD_MANAGER_APP"
    android:value="true" />

若还有其他渠道所需权限、provideractivity 等,请根据 TopOn 官方文档 合并到宿主工程。

4. 混淆与权限

TopOn 要求保留大量类与字段,请在宿主 App 的 proguard-rules.pro 中加入官方提供的 keep 配置,并在 AndroidManifest.xml 中声明网络、设备信息等必要权限,同样参考 TopOn 文档补全。

5. GDPR / UMP(Android)

如需对接 Google UMP,请完成以下步骤并确保网络可访问 Google 服务器:

  1. 引入 UMP 依赖
dependencies {
  implementation("com.google.android.ump:user-messaging-platform:3.1.0")
}
  1. 配置 AdMob App ID
<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" />
  1. 混淆配置
-keep public class com.google.android.ump.*
  1. 弹窗同意后再初始化
import { SDK } from 'react-native-topon';

await SDK.showGDPRConsentDialog('your-admob-app-id');
SDK.init('your-topon-app-id', 'your-topon-app-key');

若需提供“撤消同意”的入口,可调用 SDK.showGDPRConsentSecondDialog(appId) 重新征求意见。

如果未集成 UMP SDK,showGDPRConsentDialog 会自动回退到 TopOn 自带 GDPR 弹窗。 若 TopOn SDK 未提供带回调的 GDPR 弹窗接口,调用会立即返回,此时不要依赖 await 等待用户操作。

调试弹窗

调试阶段可调用 SDK.setUMPTestDeviceId(deviceId)(仅 Android),设备 ID 可通过 logcat 里 addTestDeviceHashedId 获取:

SDK.setUMPTestDeviceId('your-device-id');
await SDK.showGDPRConsentDialog('your-admob-app-id');

发布前请移除调试代码。

使用技巧

  • ADMOB_APP_ID(代码里传入)需要与 AndroidManifest.xmlcom.google.android.gms.ads.APPLICATION_ID 保持一致,否则可能不弹窗。
  • 如未在 EEA/UK,且没有测试设备配置,UMP 会直接回调不弹窗属正常现象;建议先设置测试设备 ID 并重装应用。
  • 已经同意过的设备可能不会再次弹窗,可清理应用数据或卸载重装测试。
  • 若需强制 EEA 流程,可在宿主 App 的原生侧使用 UMP 调试地理位置配置(当前 RN 封装未提供该入口)。
  • showGDPRConsentDialog 回调后再 SDK.init,避免同意流程未完成就请求广告。

iOS 集成说明

  1. 进入示例或宿主 App 的 ios 目录执行 RCT_NEW_ARCH_ENABLED=1 pod install(或直接 pod install),Topon.podspec 会自动拉取 AnyThinkSDKAnyThinkRewardedVideoAnyThinkInterstitialAnyThinkBanner 等依赖;如启用原生/开屏,请确认工程已包含 AnyThinkNative / AnyThinkSplash 相关 Pod。
  2. 在 JS 侧调用 SDK.init(appId, appKey) 与 Android 保持一致,其他 API 亦共享同一套定义。
  3. 确保 Info.plist 中包含 NSUserTrackingUsageDescription(请求 IDFA 必须)以及宿主业务所需的权限、SKAdNetworkItems 等配置,具体以 TopOn iOS 接入文档 为准。
  4. 若工程启用 use_frameworks!,请保持与 React Native 新架构兼容的配置(use_frameworks! :linkage => :static),避免 Pod 链接方式冲突。

iOS 与 Android 在事件名、回调入参上保持一致,所有广告能力均通过同一个 TurboModule 导出,示例应用可直接在 iOS 端运行验证。

开发与贡献

常用脚本:

yarn typecheck
yarn lint
yarn test

License

MIT