├── .gitignore ├── res └── guide2.jpg ├── README ├── res │ ├── wexinUL.jpg │ ├── android-files.jpg │ ├── android-info.jpg │ ├── android-manifest.jpg │ └── android-properties.jpg ├── Android.md └── iOS.md ├── Android ├── libs │ └── OpenInstall_v2.6.3.jar └── java │ └── io │ └── openinstall │ └── hbuilder │ └── OpenInstallApiManager.java ├── iOS ├── OpenInstallSDK │ ├── libOpenInstallSDK.a │ ├── OpeninstallData.h │ └── OpenInstallSDK.h ├── OpenInstallApiManager.h ├── OpenInstallStorage.h ├── OpenInstallStorage.m └── OpenInstallApiManager.m ├── js └── openinstall.js ├── README.md └── ad-track └── OpenInstallApiManager.m /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /res/guide2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenInstall/openinstall-hbuilder-sdk/HEAD/res/guide2.jpg -------------------------------------------------------------------------------- /README/res/wexinUL.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenInstall/openinstall-hbuilder-sdk/HEAD/README/res/wexinUL.jpg -------------------------------------------------------------------------------- /README/res/android-files.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenInstall/openinstall-hbuilder-sdk/HEAD/README/res/android-files.jpg -------------------------------------------------------------------------------- /README/res/android-info.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenInstall/openinstall-hbuilder-sdk/HEAD/README/res/android-info.jpg -------------------------------------------------------------------------------- /README/res/android-manifest.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenInstall/openinstall-hbuilder-sdk/HEAD/README/res/android-manifest.jpg -------------------------------------------------------------------------------- /README/res/android-properties.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenInstall/openinstall-hbuilder-sdk/HEAD/README/res/android-properties.jpg -------------------------------------------------------------------------------- /Android/libs/OpenInstall_v2.6.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenInstall/openinstall-hbuilder-sdk/HEAD/Android/libs/OpenInstall_v2.6.3.jar -------------------------------------------------------------------------------- /iOS/OpenInstallSDK/libOpenInstallSDK.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenInstall/openinstall-hbuilder-sdk/HEAD/iOS/OpenInstallSDK/libOpenInstallSDK.a -------------------------------------------------------------------------------- /iOS/OpenInstallApiManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // OpenInstallApiManager.h 3 | // HBuilder 4 | // 5 | // Created by cooper on 2018/5/30. 6 | // Copyright © 2018年 DCloud. All rights reserved. 7 | // 8 | 9 | #include "PGPlugin.h" 10 | #include "PGMethod.h" 11 | #import 12 | #import "OpenInstallStorage.h" 13 | 14 | @interface OpenInstallApiManager : PGPlugin 15 | 16 | -(void)registerWakeUpHandler:(PGMethod*)command; 17 | -(void)getInstall:(PGMethod*)command; 18 | -(void)reportRegister:(PGMethod*)command; 19 | -(void)reportEffectPoint:(PGMethod*)command; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /iOS/OpenInstallSDK/OpeninstallData.h: -------------------------------------------------------------------------------- 1 | // 2 | // OpeninstallData.h 3 | // OpenInstallSDK 4 | // 5 | // Created by cooper on 2018/4/17. 6 | // Copyright © 2018年 cooper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern NSString *const OP_Idfa_Id; 12 | extern NSString *const OP_ASA_Token; 13 | extern NSString *const OP_ASA_isDev;//added in v2.5.6 14 | 15 | @interface OpeninstallData : NSObject 16 | 17 | - (instancetype)initWithData:(NSDictionary *)data 18 | channelCode:(NSString *)channelCode; 19 | 20 | 21 | @property (nonatomic,strong) NSDictionary *data;//动态参数 22 | @property (nonatomic,copy) NSString *channelCode;//渠道编号 23 | 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /iOS/OpenInstallStorage.h: -------------------------------------------------------------------------------- 1 | // 2 | // OpenInstallStorage.h 3 | // HBuilder 4 | // 5 | // Created by Mr.Huang on 2021/4/16. 6 | // Copyright © 2021 DCloud. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OpenInstallSDK.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface OpenInstallStorage : NSObject 15 | 16 | @property (nonatomic, strong)NSUserActivity *_Nullable userActivity; 17 | @property (nonatomic, strong)NSURL *_Nullable urlScheme; 18 | @property (nonatomic, assign)BOOL isInit; 19 | 20 | @property (nonatomic, copy)NSString *_Nullable wakeupId; 21 | @property (nonatomic, strong)NSDictionary *_Nullable wakeupDic; 22 | 23 | +(instancetype)share; 24 | 25 | -(void)universalLinkHandler:(NSUserActivity *)activity; 26 | -(void)schemeUrlHandler:(NSURL *)url; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /iOS/OpenInstallStorage.m: -------------------------------------------------------------------------------- 1 | // 2 | // OpenInstallStorage.m 3 | // HBuilder 4 | // 5 | // Created by Mr.Huang on 2021/4/16. 6 | // Copyright © 2021 DCloud. All rights reserved. 7 | // 8 | 9 | #import "OpenInstallStorage.h" 10 | 11 | @implementation OpenInstallStorage 12 | 13 | +(instancetype)share 14 | { 15 | static OpenInstallStorage *storage = nil; 16 | static dispatch_once_t oneToken; 17 | dispatch_once(&oneToken, ^{ 18 | storage = [[OpenInstallStorage alloc]init]; 19 | storage.isInit = NO; 20 | storage.userActivity = nil; 21 | storage.urlScheme = nil; 22 | storage.wakeupDic = [[NSDictionary alloc]init]; 23 | storage.wakeupId = nil; 24 | }); 25 | return storage; 26 | } 27 | 28 | -(void)universalLinkHandler:(NSUserActivity *)activity{ 29 | if (self.isInit) { 30 | [OpenInstallSDK continueUserActivity:activity]; 31 | }else{ 32 | self.userActivity = activity; 33 | } 34 | } 35 | -(void)schemeUrlHandler:(NSURL *)url{ 36 | if (self.isInit) { 37 | [OpenInstallSDK handLinkURL:url]; 38 | }else{ 39 | self.urlScheme = url; 40 | } 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /js/openinstall.js: -------------------------------------------------------------------------------- 1 | document.addEventListener( "plusready", function(){ 2 | var _BARCODE = 'openinstall', 3 | B = window.plus.bridge; 4 | var openinstall = { 5 | 6 | configAndroid : function (options) { 7 | return B.exec(_BARCODE, "config", [options]); 8 | }, 9 | 10 | // 旧版本接口,后续移除 11 | config : function (adEnabled, oaid, gaid) { 12 | var options = {}; 13 | options.adEnabled = adEnabled; 14 | options.oaid = oaid; 15 | options.gaid = gaid; 16 | return B.exec(_BARCODE, "config", [options]); 17 | }, 18 | 19 | // (仅支持Android) 20 | serialEnabled : function(enabled){ 21 | return B.exec(_BARCODE, "serialEnabled", [enabled]); 22 | }, 23 | 24 | // (仅支持Android) 25 | clipBoardEnabled : function(enabled){ 26 | return B.exec(_BARCODE, "clipBoardEnabled", [enabled]); 27 | }, 28 | 29 | // 初始化 30 | init : function () { 31 | return B.exec(_BARCODE, "init", []); 32 | }, 33 | 34 | //注册拉起回调 35 | registerWakeUpHandler: function (successCallback) { 36 | var success = typeof successCallback !== 'function' ? null : function(args) { 37 | successCallback(args); 38 | }, 39 | callbackID = B.callbackId(success, null); 40 | return B.exec(_BARCODE, "registerWakeUpHandler", [callbackID]); 41 | }, 42 | // 获取安装来源数据 43 | getInstall : function (successCallback, timeout) { 44 | var success = typeof successCallback !== 'function' ? null : function(args) { 45 | successCallback(args); 46 | }, 47 | callbackID = B.callbackId(success, null); 48 | return B.exec(_BARCODE, "getInstall", [callbackID, timeout]); 49 | }, 50 | // 获取安装来源数据 (仅支持Android) 51 | getInstallCanRetry : function (successCallback, timeout) { 52 | var success = typeof successCallback !== 'function' ? null : function(args) { 53 | successCallback(args); 54 | }, 55 | callbackID = B.callbackId(success, null); 56 | return B.exec(_BARCODE, "getInstallCanRetry", [callbackID, timeout]); 57 | }, 58 | // 注册上报 59 | reportRegister : function () { 60 | return B.exec(_BARCODE, "reportRegister", []); 61 | }, 62 | // 上报渠道效果 63 | reportEffectPoint : function (pointId, pointValue) { 64 | return B.exec(_BARCODE, "reportEffectPoint", [pointId, pointValue]); 65 | } 66 | }; 67 | window.plus.openinstall = openinstall; 68 | }, true ); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openinstall-hbuilder-sdk 2 | 3 | uni-app集成openinstall请前往DCloud插件市场 https://ext.dcloud.net.cn/plugin?id=692 4 | 5 | 针对使用了移动广告效果监测功能的集成,需要参考 [广告平台接入补充文档](#ad) 6 | 7 | 集成或使用有任何问题,请 [联系我们](https://www.openinstall.io/) 8 | 9 | ## Android 集成指南 10 | 11 | 集成 openinstall SDK 到 Hbuilder Android 项目中,请参考 [Android 集成指南](README/Android.md) 12 | 13 | ## iOS 集成指南 14 | 15 | 集成 openinstall SDK 到 Hbuilder iOS 项目中,请参考 [iOS 集成指南](README/iOS.md) 16 | 17 | ## 插件使用 18 | 19 | 调用openinstall相关api时,需要引入 JS 文件 20 | ``` html 21 | 22 | ``` 23 | 24 | ### 1 初始化 25 | App 启动时,请确保用户同意《隐私政策》之后,再调用初始化;如果用户不同意,则不进行openinstall SDK初始化。参考 [应用合规指南](https://www.openinstall.io/doc/rules.html) 26 | ``` js 27 | plus.openinstall.init(); 28 | ``` 29 | > **注意:** 插件内部不再自动初始化,请开发者在合适的时机主动调用初始化接口;不调用初始化,后续所有api调用都会失败 30 | 31 | ### 2 快速安装和一键拉起 32 | 33 | 在应用启动时,注册拉起回调。这样当 App 被拉起时,会回调传入的方法,并在回调中获取拉起数据 34 | ``` js 35 | document.addEventListener('plusready',function(){ 36 | plus.openinstall.registerWakeUpHandler(function(data){ 37 | console.log("wakeup : channelCode= " + data.channelCode + ", bindData=" + data.bindData); 38 | }); 39 | 40 | }); 41 | ``` 42 | 43 | ### 3 携带参数安装(高级版功能) 44 | 45 | 在应用需要安装参数时,调用以下 api 获取由 SDK 保存的安装参数 46 | ``` js 47 | function getInstall(){ 48 | plus.openinstall.getInstall(function(data){ 49 | console.log("getInstall : channelCode= " + data.channelCode + ", bindData=" + data.bindData); 50 | }, 8); 51 | } 52 | ``` 53 | 54 | ### 4 渠道统计(高级版功能) 55 | 56 | SDK 会自动完成访问量、点击量、安装量、活跃量、留存率等统计工作。其它业务相关统计由开发人员使用 api 上报 57 | 58 | #### 4.1 注册统计 59 | 请确保在用户注册成功后,调用接口上报注册量 60 | ``` js 61 | function reportRegister(){ 62 | plus.openinstall.reportRegister(); 63 | } 64 | ``` 65 | 66 | #### 4.2 效果点统计 67 | 统计终端用户对某些特殊业务的使用效果,如充值金额,分享次数等等。调用接口前,请先进入 openinstall 控制台的 “效果点管理” 中添加对应的效果点,第一个参数对应控制台中的 **效果点ID** 68 | ``` js 69 | function reportEffectPoint(){ 70 | plus.openinstall.reportEffectPoint("effect_test", 1); 71 | } 72 | ``` 73 | 74 | ## 导出apk/ipa包并上传 75 | 集成完毕后,导出iOS/Android安装包上传[openinstall控制台](https://developer.openinstall.io/),openinstal会检查应用的集成配置 76 | ![上传ipa安装包](https://res.cdn.openinstall.io/doc/upload-ipa-jump.png) 77 | 78 | 79 | 上传完成后即可开始在线模拟测试,体验完整的App安装/跳转流程 80 | ![在线测试](https://res.cdn.openinstall.io/doc/js-test.png) 81 | 82 | 83 | --- 84 | 85 | 86 | ## 广告平台接入补充文档 87 | 88 | ### Android 平台 89 | 90 | 1、针对广告平台接入,新增配置接口,在调用 `init` 之前调用。参考 [广告平台对接Android集成指引](https://www.openinstall.io/doc/ad_android.html) 91 | ``` js 92 | var options = { 93 | adEnabled: true, 94 | } 95 | plus.openinstall.configAndroid(options); 96 | ``` 97 | 传入参数说明: 98 | | 参数名| 参数类型 | 描述 | 99 | | --- | --- | --- | 100 | | adEnabled| bool | 广告平台接入开关(必须) | 101 | | macDisabled | bool | 是否禁止 SDK 获取 mac 地址 | 102 | | imeiDisabled | bool | 是否禁止 SDK 获取 imei | 103 | | gaid | string | 通过 google api 获取到的 advertisingId,SDK 将不再获取gaid | 104 | | oaid | string | 通过移动安全联盟获取到的 oaid,SDK 将不再获取oaid | 105 | 106 | 2、为了精准地匹配到渠道,需要获取设备唯一标识码(IMEI),因此需要在 `AndroidManifest.xml` 中添加权限声明 107 | ``` xml 108 | 109 | ``` 110 | 3、在权限申请成功后,再进行openinstall初始化 111 | > **注意:** 插件内部不再提供权限申请功能,并且 `init(permission)` 接口已移除,请开发者自行进行权限申请 112 | 113 | ### iOS 平台 114 | 115 | 1、将 `iOS/OpenInstallApiManager.m` 文件替换为 `ad-track/OpenInstallApiManager.m ` 文件 116 | 117 | 2、需要在Info.plist文件中配置权限 118 | ``` xml 119 | NSUserTrackingUsageDescription 120 | 请允许,以获取和使用您的IDFA 121 | ``` 122 | 123 | > **备注:** 2021年,iOS14.5苹果公司将正式启用idfa新隐私政策,详情可参考:[广告平台对接iOS集成指引](https://www.openinstall.io/doc/ad_ios.html) 124 | 125 | 3、ASA渠道相关详细文档参考:[ASA渠道使用指南](https://www.openinstall.io/doc/asa.html) 126 | -------------------------------------------------------------------------------- /README/Android.md: -------------------------------------------------------------------------------- 1 | ## Android 集成指南 2 | 3 | #### 离线打包 4 | 如果要集成使用非基座包下的第三方 SDK,就必须使用离线打包。可以参考 [官方文档](http://ask.dcloud.net.cn/article/508) 进行离线打包,如果觉得官方文档太难理解,可以查看其他技术人员的教程,例如 [DCloud技术与androidstudio打包](https://blog.csdn.net/qq_33785670/article/details/75042714) 5 | 6 | #### 拷贝相关文件 7 | - 将 `Android/libs` 文件夹下的 openinstall SDK 拷贝到项目的 `app/libs` 文件夹下 8 | - 将 `Android/java` 目录下的文件夹拷贝到项目的 `app/src/main/java` 目录下 9 | - 将 `js` 目录下的 `openinstall.js` 拷贝到项目工程 `app/src/main/assets/` 目录中的 `www` 资源的 js 文件目录下 10 | 11 | > **注意:** 请开发者在进行升级时,重新拷贝并覆盖旧的文件,删除低版本SDK 12 | 13 | 拷贝完所有文件后,最终的项目结构如下图 14 | ![项目结构](./res/android-files.jpg) 15 | 16 | #### 关联 JS 插件名和 Android 原生类 17 | 修改项目的 `app/src/main/assets/data/` 目录下的 `dcloud_properties.xml`文件,指定 JS 对象名称和 Android 的类名对应关系,以便 H5+ SDK 根据对应的 JS 名查找并生成相应的 Native 对象执行对应的逻辑 18 | ``` xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ``` 28 | ![关联js](./res/android-properties.jpg) 29 | #### 添加插件使用权限 30 | 修改 `app/src/main/assets/`目录中的 `www` 目录下的 `manifest.json`文件,添加扩展插件openinstall的应用使用权限 31 | ``` json 32 | { 33 | "@platforms": [ 34 | "android", 35 | "iPhone", 36 | "iPad" 37 | ], 38 | "id": "H5E1BA598", 39 | "name": "OpenInstallPlugin", 40 | 41 | "permissions": { 42 | "Console": { 43 | "description": "跟踪调试输出日志" 44 | }, 45 | "Events": { 46 | "description": "应用扩展事件" 47 | }, 48 | 49 | 50 | "openinstall": { 51 | "description": "openinstall插件" 52 | } 53 | }, 54 | 55 | } 56 | ``` 57 | ![使用权限](./res/android-manifest.jpg) 58 | 59 | #### 声明权限 60 | 在 `AndroidManifest.xml` 中添加基本的权限声明 61 | ``` xml 62 | 63 | 64 | ``` 65 | #### 配置 AppKey 和 scheme 66 | 前往 [openinstall控制台](https://www.openinstall.io/) ,进入应用,选择 67 | “Android集成”,切换到“Android应用配置”,获取应用的 `AppKey` 和 `scheme`。 68 | ![获取appkey](./res/android-info.jpg) 69 | 70 | 在 `AndroidManifest.xml` 中配置 AppKey 和 scheme,示例如下: 71 | ``` xml 72 | 79 | 80 | 83 | 84 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | ``` 109 | > 注意:将openinstall控制台获取的`AppKey` 和 `scheme`替换到相应位置 。 110 | 111 | 112 | -------------------------------------------------------------------------------- /README/iOS.md: -------------------------------------------------------------------------------- 1 | ## iOS 集成指南 2 | 3 | #### 离线打包 4 | 如果要集成使用非基座包下的第三方 SDK,就必须使用离线打包。可以参考 [官方文档](http://ask.dcloud.net.cn/article/41) 进行离线打包 5 | 6 | #### 拷贝相关文件 7 | 8 | 拷贝Openinstall官方SDK(libOpenInstallSDK.a,OpeninstallSDK.h,OpeninstallData.h)和插件类(OpenInstallApiManager.h,OpenInstallApiManager.m,OpenInstallStorage.h,OpenInstallStorage.m)到项目工程主目录下 9 | 10 | 注意:老版本5+SDK环境下,在iOS中过早的调用openinstall.js下的方法(plus.openinstall.xxxxx),例如在首页窗口未加载完就调用的话,有用户出现过TypeError:undefined is not an object的错误,具体情况以实际测试为准 11 | 12 | #### 关联 JS 插件名和 iOS 原生类 13 | 修改 `PandoraAPI.bundle` 中 `feature.plist` 文件,在其中添加JS插件别名和Native插件类的对应关系,SDK基座会根据对应关系查找并生成相应的Native对象并执行对应的方法。 14 | ``` xml 15 | 16 | openinstall 17 | 18 | autostart 19 | 20 | global 21 | 22 | class 23 | OpenInstallApiManager 24 | 25 | 26 | ``` 27 | 28 | 在应用的 `manifest.json` 文件中还需要添加扩展插件的应用使用权限 29 | ``` json 30 | { 31 | "@platforms": [ 32 | "android", 33 | "iPhone", 34 | "iPad" 35 | ], 36 | "id": "H5E1BA598", 37 | "name": "OpenInstallPlugin", 38 | 39 | "permissions": { 40 | "Console": { 41 | "description": "跟踪调试输出日志" 42 | }, 43 | "Events": { 44 | "description": "应用扩展事件" 45 | }, 46 | 47 | "openinstall": { 48 | "description": "openinstall插件" 49 | } 50 | }, 51 | 52 | } 53 | ``` 54 | 55 | #### openinstall 的配置 56 | 57 | ##### 初始化配置 58 | 根据 `openinstall` 官方文档,在 `Info.plist` 文件中配置 `appKey` 键值对,如下: 59 | 60 | ``` xml 61 | com.openinstall.APP_KEY 62 | “从openinstall官网后台获取应用的appkey” 63 | ``` 64 | 65 | #### 以下为 `一键拉起` 功能的相关配置和代码 66 | ##### universal links配置 67 | 68 | 对于 iOS,为确保能正常跳转,AppID 必须开启 Associated Domains 功能,请到 [苹果开发者网站](https://developer.apple.com),选择 Certificate, Identifiers & Profiles,选择相应的 AppID,开启 Associated Domains。注意:当 AppID 重新编辑过之后,需要更新相应的 mobileprovision 证书。 69 | 70 | ![associatedDev](https://res.cdn.openinstall.io/doc/assciationDev.png) 71 | 72 | 在 Xcode 中配置 openinstall 为当前应用生成的关联域名(Associated Domains): 73 | 74 | ![添加associatedDomains](https://res.cdn.openinstall.io/doc/ios-associated-domains.png) 75 | 76 | 在AppDelegate中引入头文件,并添加通用链接(Universal Link)回调方法,委托openinstall插件来处理 77 | 78 | ``` objc 79 | #import "OpenInstallStorage.h" 80 | 81 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ 82 | 83 | //app在杀死的情况下,一键跳转的参数处理方法 84 | NSDictionary *optionsDic = [launchOptions valueForKey:UIApplicationLaunchOptionsUserActivityDictionaryKey]; 85 | [optionsDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { 86 | if ([key isEqualToString:@"UIApplicationLaunchOptionsUserActivityKey"]) { 87 | [[OpenInstallStorage share] universalLinkHandler:(NSUserActivity *)obj]; 88 | *stop = YES; 89 | } 90 | }]; 91 | } 92 | 93 | -(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{ 94 | //app在启动并退到后台时,一键跳转的参数处理方法 95 | [[OpenInstallStorage share] universalLinkHandler:userActivity]; 96 | //其他第三方回调; 97 | return YES; 98 | } 99 | 100 | ``` 101 | 102 | ##### scheme配置 103 | 104 | 在 `Info.plist` 文件中,在 `CFBundleURLTypes` 数组中添加应用对应的 scheme,或者在工程“TARGETS-Info-URL Types”里快速添加 105 | (scheme的值详细获取位置:openinstall应用控制台->iOS集成->iOS应用配置) 106 | 107 | ``` xml 108 | CFBundleURLTypes 109 | 110 | 111 | CFBundleTypeRole 112 | Editor 113 | CFBundleURLName 114 | openinstall 115 | CFBundleURLSchemes 116 | 117 | "从openinstall官网后台获取应用的scheme" 118 | 119 | 120 | 121 | ``` 122 | 123 | ![scheme配置](https://res.cdn.openinstall.io/doc/ios-scheme.png) 124 | 125 | 126 | 在 `AppDelegate` 中引入头文件,并添加 `scheme` 的回调方法,委托 openinstall 插件来处理 127 | 128 | ``` objc 129 | //适用目前所有iOS版本 130 | - (BOOL)application:(UIApplication *)application 131 | openURL:(NSURL *)url 132 | sourceApplication:(NSString *)sourceApplication 133 | annotation:(id)annotation { 134 | 135 | [[OpenInstallStorage share] schemeUrlHandler:url]; 136 | 137 | [self application:application handleOpenURL:url]; 138 | return YES; 139 | } 140 | 141 | //iOS9以上,会优先走这个方法 142 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(nonnull NSDictionary *)options{ 143 | 144 | [[OpenInstallStorage share] schemeUrlHandler:url]; 145 | //其他第三方回调; 146 | return YES; 147 | } 148 | ``` 149 | 150 | -------------------------------------------------------------------------------- /iOS/OpenInstallApiManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // OpenInstallApiManager.m 3 | // HBuilder 4 | // 5 | // Created by cooper on 2018/5/30. 6 | // Copyright © 2018年 DCloud. All rights reserved. 7 | // 8 | 9 | #import "OpenInstallApiManager.h" 10 | 11 | 12 | @implementation OpenInstallApiManager 13 | 14 | 15 | 16 | #pragma mark 这个方法在使用WebApp方式集成时触发,WebView集成方式不触发 17 | 18 | /* 19 | * WebApp启动时触发 20 | * 需要在PandoraApi.bundle/feature.plist/注册插件里添加autostart值为true,global项的值设置为true 21 | */ 22 | - (void) onAppStarted:(NSDictionary*)options{ 23 | NSLog(@"5+ WebApp启动时触发"); 24 | // 可以在这个方法里向Core注册扩展插件的JS 25 | 26 | [OpenInstallSDK initWithDelegate:self]; 27 | [OpenInstallStorage share].isInit = YES; 28 | } 29 | 30 | -(void)registerWakeUpHandler:(PGMethod*)command{ 31 | 32 | NSString* cbId = [command.arguments objectAtIndex:0]; 33 | OpenInstallStorage *storage = [OpenInstallStorage share]; 34 | storage.wakeupId = cbId; 35 | if (storage.wakeupDic.count != 0) { 36 | PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:storage.wakeupDic]; 37 | result.keepCallback = YES; 38 | [self toCallback:storage.wakeupId withReslut:[result toJSONString]]; 39 | storage.wakeupDic = nil; 40 | }else{ 41 | 42 | [OpenInstallSDK initWithDelegate:self]; 43 | 44 | if (storage.userActivity) { 45 | [OpenInstallSDK continueUserActivity:storage.userActivity]; 46 | storage.userActivity = nil; 47 | } 48 | if (storage.urlScheme) { 49 | [OpenInstallSDK handLinkURL:storage.urlScheme]; 50 | storage.urlScheme = nil; 51 | } 52 | } 53 | 54 | } 55 | -(void)getInstall:(PGMethod*)command{ 56 | 57 | NSString* cbId = [command.arguments objectAtIndex:0]; 58 | float outtime = 10.0f; 59 | 60 | if (command.arguments.count > 2) { 61 | if([[command.arguments objectAtIndex:1] isKindOfClass:[NSNumber class]]){ 62 | NSNumber *timeResult = (NSNumber *)[command.arguments objectAtIndex:1]; 63 | outtime = [timeResult floatValue]; 64 | } 65 | } 66 | 67 | [[OpenInstallSDK defaultManager] getInstallParmsWithTimeoutInterval:outtime completed:^(OpeninstallData * _Nullable appData) { 68 | NSLog(@"OpenInstall安装参数返回值:bindData:%@,channelCode:%@",appData.data,appData.channelCode); 69 | 70 | NSString *channelID = @""; 71 | NSString *datas = @""; 72 | if (appData.data) { 73 | datas = [self jsonStringWithObject:appData.data]; 74 | } 75 | if (appData.channelCode) { 76 | channelID = appData.channelCode; 77 | } 78 | NSDictionary *installDicResult = @{@"channelCode":channelID,@"bindData":datas}; 79 | 80 | PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:installDicResult]; 81 | [self toCallback:cbId withReslut:[result toJSONString]]; 82 | 83 | }]; 84 | } 85 | -(void)reportRegister:(PGMethod*)command{ 86 | 87 | [OpenInstallSDK reportRegister]; 88 | 89 | } 90 | -(void)reportEffectPoint:(PGMethod*)command{ 91 | 92 | NSString* pointId = [command.arguments objectAtIndex:0]; 93 | NSNumber* value = [command.arguments objectAtIndex:1]; 94 | long pointValue = [value longValue]; 95 | [[OpenInstallSDK defaultManager] reportEffectPoint:pointId effectValue:pointValue]; 96 | } 97 | 98 | -(void)getWakeUpParams:(OpeninstallData *)appData{ 99 | NSLog(@"OpenInstall拉起参数返回值:bindData:%@,channelCode:%@",appData.data,appData.channelCode); 100 | NSString *channelID = @""; 101 | NSString *datas = @""; 102 | if (appData.data) { 103 | datas = [self jsonStringWithObject:appData.data]; 104 | } 105 | if (appData.channelCode) { 106 | channelID = appData.channelCode; 107 | } 108 | NSDictionary *wakeUpDicResult = @{@"channelCode":channelID,@"bindData":datas}; 109 | 110 | PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:wakeUpDicResult]; 111 | result.keepCallback = YES; 112 | OpenInstallStorage *storage = [OpenInstallStorage share]; 113 | if (storage.wakeupId) { 114 | [self toCallback:storage.wakeupId withReslut:[result toJSONString]]; 115 | }else{ 116 | storage.wakeupDic = wakeUpDicResult; 117 | } 118 | } 119 | 120 | 121 | - (NSString *)jsonStringWithObject:(id)jsonObject{ 122 | 123 | id arguments = (jsonObject == nil ? [NSNull null] : jsonObject); 124 | 125 | NSArray* argumentsWrappedInArr = [NSArray arrayWithObject:arguments]; 126 | 127 | NSString* argumentsJSON = [self cp_JSONString:argumentsWrappedInArr]; 128 | 129 | if (argumentsJSON.length>2) {argumentsJSON = [argumentsJSON substringWithRange:NSMakeRange(1, [argumentsJSON length] - 2)];} 130 | 131 | return argumentsJSON; 132 | } 133 | - (NSString *)cp_JSONString:(NSArray *)array{ 134 | NSError *error = nil; 135 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:array 136 | options:0 137 | error:&error]; 138 | 139 | NSString *jsonString = [[NSString alloc] initWithData:jsonData 140 | encoding:NSUTF8StringEncoding]; 141 | 142 | if ([jsonString length] > 0 && error == nil){ 143 | return jsonString; 144 | }else{ 145 | return @""; 146 | } 147 | } 148 | 149 | @end 150 | -------------------------------------------------------------------------------- /ad-track/OpenInstallApiManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // OpenInstallApiManager.m 3 | // HBuilder 4 | // 5 | // Created by cooper on 2018/5/30. 6 | // Copyright © 2018年 DCloud. All rights reserved. 7 | // 8 | 9 | #import "OpenInstallApiManager.h" 10 | #import 11 | #import //适配iOS14 12 | #import 13 | 14 | @implementation OpenInstallApiManager 15 | 16 | 17 | 18 | #pragma mark 这个方法在使用WebApp方式集成时触发,WebView集成方式不触发 19 | 20 | /* 21 | * WebApp启动时触发 22 | * 需要在PandoraApi.bundle/feature.plist/注册插件里添加autostart值为true,global项的值设置为true 23 | */ 24 | - (void) onAppStarted:(NSDictionary*)options{ 25 | NSLog(@"5+ WebApp启动时触发"); 26 | // 可以在这个方法里向Core注册扩展插件的JS 27 | [self openinstallInit]; 28 | } 29 | 30 | - (void)openinstallInit{ 31 | if (@available(iOS 14, *)) { 32 | [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { 33 | [self OpInit]; 34 | }]; 35 | }else{ 36 | [self OpInit]; 37 | } 38 | } 39 | 40 | - (void)OpInit{ 41 | 42 | //ASA广告归因 43 | NSMutableDictionary *config = [[NSMutableDictionary alloc]init]; 44 | if (@available(iOS 14.3, *)) { 45 | NSError *error; 46 | NSString *token = [AAAttribution attributionTokenWithError:&error]; 47 | [config setValue:token forKey:OP_ASA_Token]; 48 | } 49 | 50 | //第三方广告平台统计代码 51 | NSString *idfaStr = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; 52 | [config setValue:idfaStr forKey:OP_Idfa_Id]; 53 | 54 | [OpenInstallSDK initWithDelegate:self adsAttribution:config];//初始化API 55 | 56 | [OpenInstallStorage share].isInit = YES; 57 | } 58 | 59 | -(void)registerWakeUpHandler:(PGMethod*)command{ 60 | 61 | NSString* cbId = [command.arguments objectAtIndex:0]; 62 | OpenInstallStorage *storage = [OpenInstallStorage share]; 63 | storage.wakeupId = cbId; 64 | if (storage.wakeupDic.count != 0) { 65 | PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:storage.wakeupDic]; 66 | result.keepCallback = YES; 67 | [self toCallback:storage.wakeupId withReslut:[result toJSONString]]; 68 | storage.wakeupDic = nil; 69 | }else{ 70 | 71 | [self openinstallInit]; 72 | 73 | if (storage.userActivity) { 74 | [OpenInstallSDK continueUserActivity:storage.userActivity]; 75 | storage.userActivity = nil; 76 | } 77 | if (storage.urlScheme) { 78 | [OpenInstallSDK handLinkURL:storage.urlScheme]; 79 | storage.urlScheme = nil; 80 | } 81 | } 82 | 83 | } 84 | -(void)getInstall:(PGMethod*)command{ 85 | 86 | NSString* cbId = [command.arguments objectAtIndex:0]; 87 | float outtime = 15.0f; 88 | 89 | if (command.arguments.count > 2) { 90 | if([[command.arguments objectAtIndex:1] isKindOfClass:[NSNumber class]]){ 91 | NSNumber *timeResult = (NSNumber *)[command.arguments objectAtIndex:1]; 92 | outtime = [timeResult floatValue]; 93 | } 94 | } 95 | 96 | [[OpenInstallSDK defaultManager] getInstallParmsWithTimeoutInterval:outtime completed:^(OpeninstallData * _Nullable appData) { 97 | NSLog(@"OpenInstall安装参数返回值:bindData:%@,channelCode:%@",appData.data,appData.channelCode); 98 | 99 | NSString *channelID = @""; 100 | NSString *datas = @""; 101 | if (appData.data) { 102 | datas = [self jsonStringWithObject:appData.data]; 103 | } 104 | if (appData.channelCode) { 105 | channelID = appData.channelCode; 106 | } 107 | NSDictionary *installDicResult = @{@"channelCode":channelID,@"bindData":datas}; 108 | 109 | PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:installDicResult]; 110 | [self toCallback:cbId withReslut:[result toJSONString]]; 111 | 112 | }]; 113 | } 114 | -(void)reportRegister:(PGMethod*)command{ 115 | 116 | [OpenInstallSDK reportRegister]; 117 | 118 | } 119 | -(void)reportEffectPoint:(PGMethod*)command{ 120 | 121 | NSString* pointId = [command.arguments objectAtIndex:0]; 122 | NSNumber* value = [command.arguments objectAtIndex:1]; 123 | long pointValue = [value longValue]; 124 | [[OpenInstallSDK defaultManager] reportEffectPoint:pointId effectValue:pointValue]; 125 | } 126 | 127 | -(void)getWakeUpParams:(OpeninstallData *)appData{ 128 | NSLog(@"OpenInstall拉起参数返回值:bindData:%@,channelCode:%@",appData.data,appData.channelCode); 129 | NSString *channelID = @""; 130 | NSString *datas = @""; 131 | if (appData.data) { 132 | datas = [self jsonStringWithObject:appData.data]; 133 | } 134 | if (appData.channelCode) { 135 | channelID = appData.channelCode; 136 | } 137 | NSDictionary *wakeUpDicResult = @{@"channelCode":channelID,@"bindData":datas}; 138 | 139 | PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:wakeUpDicResult]; 140 | result.keepCallback = YES; 141 | OpenInstallStorage *storage = [OpenInstallStorage share]; 142 | if (storage.wakeupId) { 143 | [self toCallback:storage.wakeupId withReslut:[result toJSONString]]; 144 | }else{ 145 | storage.wakeupDic = wakeUpDicResult; 146 | } 147 | } 148 | 149 | 150 | - (NSString *)jsonStringWithObject:(id)jsonObject{ 151 | 152 | id arguments = (jsonObject == nil ? [NSNull null] : jsonObject); 153 | 154 | NSArray* argumentsWrappedInArr = [NSArray arrayWithObject:arguments]; 155 | 156 | NSString* argumentsJSON = [self cp_JSONString:argumentsWrappedInArr]; 157 | 158 | if (argumentsJSON.length>2) {argumentsJSON = [argumentsJSON substringWithRange:NSMakeRange(1, [argumentsJSON length] - 2)];} 159 | 160 | return argumentsJSON; 161 | } 162 | - (NSString *)cp_JSONString:(NSArray *)array{ 163 | NSError *error = nil; 164 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:array 165 | options:0 166 | error:&error]; 167 | 168 | NSString *jsonString = [[NSString alloc] initWithData:jsonData 169 | encoding:NSUTF8StringEncoding]; 170 | 171 | if ([jsonString length] > 0 && error == nil){ 172 | return jsonString; 173 | }else{ 174 | return @""; 175 | } 176 | } 177 | 178 | @end 179 | -------------------------------------------------------------------------------- /iOS/OpenInstallSDK/OpenInstallSDK.h: -------------------------------------------------------------------------------- 1 | // 2 | // OpenInstallSDK.h 3 | // OpenInstallSDK 4 | // 5 | // Created by toby on 16/8/11. 6 | // Copyright © 2016年 toby. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OpeninstallData.h" 11 | 12 | @protocol OpenInstallDelegate 13 | 14 | @optional 15 | 16 | #pragma mark - 推荐使用最新API:getInstallParmsCompleted 17 | /** 18 | * 安装时获取h5页面动态参数(如果是渠道链接,渠道编号会一起返回) 19 | * @param params 动态参数 20 | * @param error 错误回调 21 | * @discussion 老版本sdk升级过来可延用该api 22 | */ 23 | - (void)getInstallParamsFromOpenInstall:(nullable NSDictionary *)params withError:(nullable NSError *)error __deprecated_msg("Deprecated func,请使用方法getInstallParmsCompleted"); 24 | 25 | 26 | ///---------------------- 27 | /// @name 一键拉起的回调方法 28 | ///---------------------- 29 | 30 | #pragma mark - 推荐使用最新API:getWakeUpParams 31 | /** 32 | * 唤醒时获取h5页面动态参数(如果是渠道链接,渠道编号会一起返回) 33 | * @param params 动态参数 34 | * @param error 错误回调 35 | * @discussion 老版本sdk升级过来可延用该api 36 | */ 37 | - (void)getWakeUpParamsFromOpenInstall:(nullable NSDictionary *)params withError:(nullable NSError *)error __deprecated_msg("Deprecated func,请使用方法getWakeUpParams"); 38 | 39 | 40 | #pragma mark - add in v2.2.0 41 | /** 42 | * 唤醒时获取h5页面动态参数(如果是渠道链接,渠道编号会一起返回) 43 | * @param appData 动态参数对象 44 | */ 45 | - (void)getWakeUpParams:(nullable OpeninstallData *)appData; 46 | 47 | @end 48 | 49 | @interface OpenInstallSDK : NSObject 50 | 51 | /** 52 | * 获取sdk当前版本号,add in v2.2.1 53 | */ 54 | + (NSString *_Nullable)sdkVersion; 55 | 56 | 57 | /** 58 | * SDK单例,returns a previously instantiated singleton instance of the API. 59 | */ 60 | +(instancetype _Nullable)defaultManager; 61 | 62 | 63 | ///------------- 64 | /// @name 初始化 65 | ///------------- 66 | 67 | #pragma mark - added in v2.2.0 请在Info.plist中配置应用的appkey 68 | 69 | /** 70 | * 初始化OpenInstall SDK 71 | * ***调用该方法前,需在Info.plist文件中配置键值对,键为com.openinstall.APP_KEY不能修改,值为相应的应用的appKey,可在openinstall官方后台查看*** 72 | 73 | com.openinstall.APP_KEY 74 | 你的appKey 75 | 76 | * @param delegate 委托方法所在的类的对象 77 | */ 78 | +(void)initWithDelegate:(id _Nonnull)delegate; 79 | 80 | 81 | #pragma mark - added in v2.4.0 82 | /** 83 | * 初始化sdk并传入广告标识符id(可选) 84 | * ***调用该方法前,需在Info.plist文件中配置键值对,键为com.openinstall.APP_KEY不能修改,值为相应的应用的appKey,可在openinstall官方后台查看*** 85 | * 86 | * @param adid 广告标识符,需用户自己获取并传入,默认为空,传入nil则与初始化方法 initwithDelegate: 一致 87 | * @param delegate 委托方法所在的类的对象 88 | * @discussion 1、只有需要使用“广告平台渠道”进行广告效果监测的用户才需调用,2、需开启后台开关,位置:"iOS集成"->"iOS应用配置"->"广告平台对接" 89 | * ***详细文档请查看:https://www.openinstall.io/doc/ad_ios.html*** 90 | */ 91 | + (void)initWithDelegate:(nullable id)delegate advertisingId:(NSString *_Nullable)adid; 92 | 93 | 94 | #pragma mark - added in v2.5.4 95 | 96 | /** 97 | * 初始化sdk,并传入广告相关参数 98 | * 详细参考官网文档 99 | * 100 | * @param delegate 委托方法所在的类的对象 101 | * @param attribution 广告相关参数,如ASA token,idfa等,@{OP_ASA_Token:@"your ASA Token"} 102 | * 参考文档 https://www.openinstall.io/doc/asa.html 103 | */ 104 | + (void)initWithDelegate:(nullable id)delegate adsAttribution:(NSDictionary *_Nullable)attribution; 105 | 106 | 107 | #pragma mark - Deprecated in v2.2.0(已废弃) 108 | 109 | /** 110 | * 初始化OpenInstall SDK (已废弃,请参考方法 initwithDelegate: 已使用该初始化方法的用户也可继续使用) 111 | * 112 | * @param appKey 控制中心创建应用获取appKey 113 | * @param delegate 委托方法(getWakeUpParams)所在的类的对象 114 | * @discussion 老版本sdk升级过来可延用该api 115 | */ 116 | +(void)setAppKey:(nonnull NSString *)appKey withDelegate:(nullable id)delegate __deprecated_msg("Deprecated in v2.2.0,请参考方法initwithDelegate"); 117 | 118 | 119 | ///---------------------- 120 | /// @name 获取安装的动态参数 121 | ///---------------------- 122 | 123 | #pragma mark - added in v2.2.0 124 | 125 | /** 126 | * 开发者在需要获取用户安装app后由web网页传递过来的”动态参数“(如邀请码、游戏房间号,渠道编号,ASA渠道编号等)时调用该方法,可第一时间返回数据,可在任意位置调用 127 | * 128 | * v2.2.1后默认回调超时时长由5秒(s)修改为为8秒(s),如无特殊需求,请用此方法,否则可使用高级API 129 | * 130 | * @param completedBlock 回调block,在主线程(UI线程)回调 131 | * 132 | * @discussion 133 | 1、不要自己保存动态安装参数,在每次需要用到参数时,请调用该方法去获取; 134 | 2、该方法默认超时为8秒,尽量写在业务场景需要参数的位置调用(在业务场景时,网络一般都是畅通的),例如,可以选择在用户注册成功后调用该方法获取参数,对用户进行奖励。原因是iOS首次安装、首次启动的app,会询问用户获取网络权限,用户允许后SDK才能正常联网去获取参数。如果调用过早,可能导致网络权限还未允许就被调用,导致参数无法及时拿到,误以为参数不存在(此时getInstallParmsCompleted法已超时,回调返回空); 135 | 3. 如果是业务需要,必须在application:didFinishLaunchingWithOptions方法中获取参数,可调用下面高级API,修改超时时长,比如15秒或更长,如果只是拿参数在后台“悄悄地”进行数据统计的情况,超时时长设置为半个小时或更长都是ok的,根据需要来。 136 | 137 | * ***该方法可重复获取参数,如需在首次安装才获取安装参数,请自行判断,参考https://www.openinstall.io/doc/ios_sdk_faq.html*** 138 | */ 139 | -(void)getInstallParmsCompleted:(void (^_Nullable)(OpeninstallData*_Nullable appData))completedBlock; 140 | 141 | 142 | /** 143 | * 开发者在需要获取用户安装app后由web网页传递过来的”动态参数“(如邀请码、游戏房间号,渠道编号,ASA渠道编号等)时调用该方法,可第一时间返回数据,可在任意位置调用 144 | * 145 | * @param timeoutInterval 可设置回调超时时长,单位秒(s) 146 | * @param completedBlock 回调block,在主线程(UI线程)回调 147 | * 148 | * @discussion 149 | * ***开发者不要自行保存参数!!!如果获取动态参数成功,SDK会把参数保存在本地*** 150 | * ***该方法可重复获取参数,如需在首次安装才获取安装参数,请自行判断,参考https://www.openinstall.io/doc/ios_sdk_faq.html*** 151 | */ 152 | -(void)getInstallParmsWithTimeoutInterval:(NSTimeInterval)timeoutInterval 153 | completed:(void (^_Nullable)(OpeninstallData*_Nullable appData))completedBlock; 154 | 155 | 156 | 157 | #pragma mark - Deprecated in v2.1.1(已废弃) 158 | /** 159 | * 开发者直接获取动态参数,初始化之后调用(参数的正常获取时间1-2秒内) 160 | * @return NSDictionary 161 | */ 162 | +(NSDictionary *_Nullable)getOpenInstallParams __deprecated_msg("Deprecated in v2.1.1,请参考方法getInstallParmsCompleted"); 163 | 164 | 165 | ///--------------------- 166 | /// @name 一键拉起回调处理 167 | ///--------------------- 168 | 169 | /** 170 | * 处理 URI schemes 171 | * @param URL 系统回调传回的URL 172 | * @return bool URL是否被OpenInstall识别 173 | */ 174 | +(BOOL)handLinkURL:(NSURL *_Nullable)URL; 175 | 176 | 177 | /** 178 | * 处理 通用链接 179 | * @param userActivity 存储了页面信息,包括url 180 | * @return bool URL是否被OpenInstall识别 181 | */ 182 | +(BOOL)continueUserActivity:(NSUserActivity *_Nullable)userActivity; 183 | 184 | 185 | 186 | ///-------------- 187 | /// @name 统计相关 188 | ///-------------- 189 | 190 | 191 | /** 192 | * 注册量统计 193 | * 194 | * 使用openinstall 控制中心提供的渠道统计时,在App用户注册完成后调用,可以统计渠道注册量。 195 | * 必须在注册成功的时再调用该方法,避免重复调用,否则可能导致注册统计不准 196 | */ 197 | +(void)reportRegister; 198 | 199 | 200 | #pragma mark - added in v2.2.0 201 | /** 202 | * 渠道效果统计 203 | * 204 | * 目前SDK采用定时上报策略,时间间隔由服务器控制 205 | * e.g.可统计用户支付消费情况,点击次数等 206 | * 207 | * @param effectID 效果点ID 208 | * @param effectValue 效果点值(如果是人民币金额,请以分为计量单位) 209 | */ 210 | -(void)reportEffectPoint:(NSString *_Nonnull)effectID effectValue:(long)effectValue; 211 | 212 | 213 | /** 214 | * 上报广告相关参数 215 | * 216 | * e.g.ASA相关token等 217 | * 218 | * @param attribution 广告相关参数配置 219 | */ 220 | -(void)reportAdsAttribution:(NSDictionary *)attribution __deprecated_msg("Deprecated,请参考方法initWithDelegate:adsAttribution:");; 221 | 222 | 223 | @end 224 | 225 | -------------------------------------------------------------------------------- /Android/java/io/openinstall/hbuilder/OpenInstallApiManager.java: -------------------------------------------------------------------------------- 1 | package io.openinstall.hbuilder; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.text.TextUtils; 8 | import android.util.Log; 9 | 10 | import com.fm.openinstall.Configuration; 11 | import com.fm.openinstall.OpenInstall; 12 | import com.fm.openinstall.listener.AppInstallAdapter; 13 | import com.fm.openinstall.listener.AppInstallRetryAdapter; 14 | import com.fm.openinstall.listener.AppWakeUpListener; 15 | import com.fm.openinstall.model.AppData; 16 | import com.fm.openinstall.model.Error; 17 | 18 | import org.json.JSONArray; 19 | import org.json.JSONException; 20 | import org.json.JSONObject; 21 | 22 | import io.dcloud.common.DHInterface.ISysEventListener; 23 | import io.dcloud.common.DHInterface.IWebview; 24 | import io.dcloud.common.DHInterface.StandardFeature; 25 | import io.dcloud.common.util.JSUtil; 26 | 27 | public class OpenInstallApiManager extends StandardFeature { 28 | 29 | private static final String TAG = "OpenInstallApiManager"; 30 | private IWebview webview = null; 31 | private String wakeupCallBackID = null; 32 | private Intent wakeupIntent = null; 33 | private volatile boolean initialized = false; 34 | private Configuration configuration = null; 35 | 36 | @Override 37 | public void onStart(Context context, Bundle bundle, String[] strings) { 38 | super.onStart(context, bundle, strings); 39 | } 40 | 41 | public void config(IWebview pWebview, JSONArray array) { 42 | JSONObject options = array.optJSONObject(0); 43 | if (options != null) { 44 | Configuration.Builder builder = new Configuration.Builder(); 45 | boolean adEnabled = options.optBoolean("adEnabled", false); 46 | builder.adEnabled(adEnabled); 47 | String oaid = options.optString("oaid", null); 48 | builder.oaid(setNull(oaid)); 49 | String gaid = options.optString("gaid", null); 50 | builder.gaid(setNull(gaid)); 51 | boolean macDisabled = options.optBoolean("macDisabled", false); 52 | if (macDisabled) { 53 | builder.macDisabled(); 54 | } 55 | boolean imeiDisabled = options.optBoolean("imeiDisabled", false); 56 | if (imeiDisabled) { 57 | builder.imeiDisabled(); 58 | } 59 | configuration = builder.build(); 60 | 61 | Log.d(TAG, String.format("config adEnabled=%s, oaid=%s, gaid=%s, macDisabled=%s, imeiDisabled= %s", 62 | configuration.isAdEnabled(), configuration.getOaid(), configuration.getGaid(), 63 | configuration.isMacDisabled(), configuration.isImeiDisabled())); 64 | 65 | } else { 66 | Log.e(TAG, "options is null"); 67 | } 68 | } 69 | 70 | public void clipBoardEnabled(IWebview pWebview, JSONArray array){ 71 | boolean enabled = array.optBoolean(0, true); 72 | OpenInstall.clipBoardEnabled(enabled); 73 | } 74 | 75 | public void serialEnabled(IWebview pWebview, JSONArray array){ 76 | boolean enabled = array.optBoolean(0, true); 77 | OpenInstall.serialEnabled(enabled); 78 | } 79 | 80 | public void init(IWebview pWebview, JSONArray array) { 81 | initialized(pWebview); 82 | } 83 | 84 | private String setNull(String res) { 85 | // 传入 null 或者 未定义,设置为 null 86 | if (res == null || res.equalsIgnoreCase("null") 87 | || res.equalsIgnoreCase("undefined")) { 88 | return null; 89 | } 90 | return res; 91 | } 92 | 93 | private void initialized(final IWebview pWebview) { 94 | OpenInstall.init(pWebview.getContext(), configuration); 95 | initialized = true; 96 | if (wakeupIntent != null) { 97 | getWakeUp(wakeupIntent, pWebview, wakeupCallBackID); 98 | wakeupIntent = null; 99 | } 100 | } 101 | 102 | public void registerWakeUpHandler(final IWebview pWebview, JSONArray array) { 103 | Log.d(TAG, "registerWakeUpHandler"); 104 | String callBackID = array.optString(0); 105 | 106 | webview = pWebview; 107 | wakeupCallBackID = callBackID; 108 | // 自己注册了监听并处理 onNewIntent 事件 109 | pWebview.obtainApp().registerSysEventListener(new ISysEventListener() { 110 | @Override 111 | public boolean onExecute(SysEventType sysEventType, Object o) { 112 | if (sysEventType == SysEventType.onNewIntent) { 113 | String dataString = (String) o; 114 | // OpenInstall 原生 SDK 有判断了是否是 android.intent.action.VIEW 115 | Intent intent = new Intent(Intent.ACTION_VIEW); 116 | intent.setData(Uri.parse(dataString)); 117 | if (webview != null && wakeupCallBackID != null) { 118 | getWakeUp(intent, webview, wakeupCallBackID); 119 | } 120 | } 121 | return false; 122 | } 123 | }, SysEventType.onNewIntent); 124 | 125 | Intent intent = pWebview.getActivity().getIntent(); 126 | if (intent == null) { 127 | return; 128 | } 129 | getWakeUp(intent, pWebview, callBackID); 130 | } 131 | 132 | private void getWakeUp(Intent intent, final IWebview pWebview, final String callBackID) { 133 | if (initialized) { 134 | OpenInstall.getWakeUpAlwaysCallback(intent, new AppWakeUpListener() { 135 | @Override 136 | public void onWakeUpFinish(AppData appData, Error error) { 137 | JSONObject dataJson = parseData(appData); 138 | // 最后一个参数 boolean 表示 keepCallback 139 | JSUtil.execCallback(pWebview, callBackID, dataJson, JSUtil.OK, true); 140 | } 141 | }); 142 | } else { 143 | wakeupIntent = intent; 144 | } 145 | } 146 | 147 | public void getInstall(final IWebview pWebview, JSONArray array) { 148 | Log.d(TAG, "getInstall"); 149 | final String callBackID = array.optString(0); 150 | int timeout = 10; 151 | if (!array.isNull(1)) { 152 | timeout = array.optInt(1); 153 | } 154 | OpenInstall.getInstall(new AppInstallAdapter() { 155 | @Override 156 | public void onInstall(AppData appData) { 157 | JSONObject dataJson = parseData(appData); 158 | JSUtil.execCallback(pWebview, callBackID, dataJson, JSUtil.OK, false); 159 | } 160 | }, timeout); 161 | } 162 | 163 | public void getInstallCanRetry(final IWebview pWebview, JSONArray array) { 164 | Log.d(TAG, "getInstallCanRetry"); 165 | final String callBackID = array.optString(0); 166 | int timeout = 3; 167 | if (!array.isNull(1)) { 168 | timeout = array.optInt(1); 169 | } 170 | OpenInstall.getInstallCanRetry(new AppInstallRetryAdapter() { 171 | @Override 172 | public void onInstall(AppData appData, boolean retry) { 173 | JSONObject dataJson = parseData(appData); 174 | try { 175 | dataJson.put("retry", retry); 176 | } catch (JSONException e) { 177 | e.printStackTrace(); 178 | } 179 | JSUtil.execCallback(pWebview, callBackID, dataJson, JSUtil.OK, false); 180 | } 181 | }, timeout); 182 | } 183 | 184 | public void reportRegister(IWebview pWebview, JSONArray array) { 185 | OpenInstall.reportRegister(); 186 | } 187 | 188 | public void reportEffectPoint(IWebview pWebview, JSONArray array) { 189 | String pointId = array.optString(0); 190 | long pointValue = array.optLong(1); 191 | if (TextUtils.isEmpty(pointId)) { 192 | Log.d(TAG, "reportEffectPoint pointId is empty"); 193 | } else { 194 | Log.d(TAG, String.format("reportEffectPoint(%s, %d)", pointId, pointValue)); 195 | OpenInstall.reportEffectPoint(pointId, pointValue); 196 | } 197 | } 198 | 199 | private JSONObject parseData(AppData appData) { 200 | JSONObject dataJson = new JSONObject(); 201 | if (appData != null) { 202 | try { 203 | dataJson.put("channelCode", appData.getChannel()); 204 | dataJson.put("bindData", appData.getData()); 205 | } catch (JSONException e) { 206 | e.printStackTrace(); 207 | } 208 | } 209 | return dataJson; 210 | } 211 | 212 | } 213 | --------------------------------------------------------------------------------