说在前面

  • 这篇文字想要表达什么?
    分享一些cordova-plugin-janalytics的开发过程, 为cordova和极光新手提供帮助。
  • 出于什么目的开发了cordova-plugin-janalytics?
    主要是为了技术储备,在今后的项目中能更方便的使用极光统计服务。
  • 为什么选择极光统计?
    简单、免费、极光的名号。ps.极光的商务部记得给我一些广告费啊:)

使用cordova极光统计插件

  • 安装 cordova plugin install cordova-plugin-janalytics --variable API_KEY=极光KEY --variable CHANNEL=渠道名
  • 项目中调用极光统计 Janalytics.onPageStart("登陆页面", function(){}, function(err){});

更多更详细的用法请移步到cordova-plugin-janalytics

开发过程记录

准备工作

  • android和ios的原生janalytics-sdk
  • cordova和plugman

创建并初始化cordova插件项目

  • 创建插件项目
    plugman create --name jcore --plugin_id cordova-plugin-jcore --plugin_version 0.0.1
  • 向项目中添加android和ios平台
    plugman platform add -platform_name android
    plugman platform add -platform_name ios

编写plugin.xml

通过官方文档得知,极光统计SDK需要两个配置参数APP_KEY和CHANNEL
其中APP_KEY极光分配的应用标示,CHANNEL是作为渠道标示
为了插件在多个项目中复用,故将APP_KEY和CHANNEL作为变量

<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-janalytics" version="1.0.4" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <name>JAnalytics</name>
    <description>JAnalytics for cordova plugin</description>
    <author>WilhanTian</author>
    <keywords>JAnalytics,analytics</keywords>
    <license>MIT License</license>

    <preference name="APP_KEY"/><!--应用ID-->
    <preference name="CHANNEL" default="DEFAULT_CHANNEL"/><!--渠道字符串 注意!禁止为纯数字-->

    <dependency id="cordova-plugin-jcore" version="1.0.1"/>

    <!--cordova引擎版本限制-->
    <engines>
        <engine name="cordova" version=">=3.0" />
    </engines>

    <js-module name="JAnalytics" src="www/JAnalytics.js">
        <clobbers target="JAnalytics" />
    </js-module>

    <!--IOS-->
    <platform name="ios">
        <config-file parent="/*" target="config.xml">
            <feature name="JAnalytics">
                <param name="ios-package" value="JAnalytics" />
            </feature>
        </config-file>

        <config-file parent="JAnalytics" target="*-Info.plist">
            <dict>
                <key>APP_KEY</key>
                <string>$APP_KEY</string>
                <key>CHANNEL</key>
                <string>$CHANNEL</string>
            </dict>
        </config-file>

        <!--库依赖-->
        <framework src="UIKit.framework" weak="true" />
        <framework src="SystemConfiguration.framework" weak="true" />
        <framework src="CoreTelephony.framework" weak="true" />
        <framework src="CoreGraphics.framework" weak="true" />
        <framework src="Security.framework" weak="true" />
        <framework src="Foundation.framework" weak="true" />
        <framework src="CoreLocation.framework" weak="true" />
        <framework src="CoreFoundation.framework" weak="true" />
        <framework src="CFNetwork.framework" weak="true" />
        <framework src="libz.tbd" weak="true" />
        <framework src="libresolv.tbd" weak="true" />

        <!--库文件-->
        <header-file src="src/ios/libs/JANALYTICSService.h" />
        <header-file src="src/ios/libs/JANALYTICSEventObject.h" />
        <source-file src="src/ios/libs/janalytics-ios-1.0.0.a" framework="true" />
        <!--IOS插件源码-->
        <header-file src="src/ios/JAnalytics.h" />
        <source-file src="src/ios/JAnalytics.m" />
    </platform>

    <!--Android-->
    <platform name="android">
        <config-file parent="/*" target="res/xml/config.xml">
            <feature name="JAnalytics">
                <param name="android-package" value="org.cordova.plugin.janalytics.JAnalytics" />
            </feature>
        </config-file>
        <config-file parent="/*" target="AndroidManifest.xml"/>

        <!--权限-->
        <config-file parent="/manifest" target="AndroidManifest.xml">
            <uses-permission android:name="android.permission.RECEIVER_USER_PRESENT" />
            <uses-permission android:name="android.permission.INTERNET" />
            <uses-permission android:name="android.permission.READ_PHONE_STATE" />
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
            <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
            <uses-permission android:name="android.permission.WRITE_SETTINGS" />
            <uses-permission android:name="android.permission.VIBRATE" />
            <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
            <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
            <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
            <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
            <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
            <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
            <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
            <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
            <uses-permission android:name="android.permission.GET_TASKS" />
            <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
        </config-file>

        <!--基础配置-->
        <config-file parent="/manifest/application" target="AndroidManifest.xml">
            <meta-data android:name="JPUSH_APPKEY" android:value="$APP_KEY"/>
            <meta-data android:name="JPUSH_CHANNEL" android:value="$CHANNEL"/>
        </config-file>

        <!--jar包-->
        <source-file src="src/android/libs/janalytics-android_v1.0.0.jar" target-dir="libs" />
        <!--java源码-->
        <source-file src="src/android/JAnalytics.java" target-dir="src/org/cordova/plugin/janalytics" />
    </platform>
</plugin>

标签解析:

  • preference: 用于声明变量定义。可以在安装时plugin plugin install 插件名 --variable 变量名=变量注入变量。
  • dependency: 从属/依赖插件。当一个插件需要使用另外一个插件时使用。
  • framework: 用于引入IOS平台静态/动态库。
  • header-file: 引入.h文件,主要用在IOS平台下。
  • source-file: 引入插件源码。.mm .m .cpp .java.jar等文件都可以使用此标签引入。
  • uses-permission: 声明Andorid平台APP所需权限。
  • js-module: 插件js模块定义。
    这些标签都可以在cordova文档中找到

让js调用原生janalytics

使用plugman创建工程后,已经默认帮你创建了一个java和oc类,只需要两个类中撰写相关业务即可。

Android示例

public class JAnalytics extends CordovaPlugin {

    @Override
    protected void pluginInitialize() {
        //初始化极光统计服务
        JAnalyticsInterface.init(this.cordova.getActivity().getApplication());
    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
        if(action.equals("onPageStart")){//判断动作名
            String pageName = args.getString(0);//从json数组中取出第一个参数
            JAnalyticsInterface.onPageStart(this.cordova.getActivity(), pageName);//向统计一个页面进入事件
            callbackContext.success();//反馈给js回调函数
        }
        return true;
    }
}

IOS实例

@implementation JAnalytics

- (void)pluginInitialize
{
    // 从plist中读取变量
    NSDictionary *plistDic = [[NSBundle mainBundle] infoDictionary];
    NSString* APP_KEY = [[plistDic objectForKey:@"JAnalytics"] objectForKey:@"APP_KEY"];
    NSString* CHANNEL = [[plistDic objectForKey:@"JAnalytics"] objectForKey:@"CHANNEL"];

    // 初始化极光统计服务
    JANALYTICSLaunchConfig * config = [[JANALYTICSLaunchConfig alloc] init];
    config.appKey = APP_KEY;
    config.channel = CHANNEL;
    [JANALYTICSService setupWithConfig:config];
}

// js的动作名会自动映射到oc方法名上
- (void)onPageStart:(CDVInvokedUrlCommand *)command
{
    NSString* pageName = [command.arguments objectAtIndex:0];//从字典中取出第一个参数
    [JANALYTICSService startLogPageView:pageName];//向统计一个页面进入事件

    //反馈给js回调函数
    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

@end

编写插件API

www/JAnalytics.js

示例

var exec = require('cordova/exec');

// 页面启动接口
exports.onPageStart = function(pageName, success, error) {
    pageName = pageName || "";
    exec(success, error, "JAnalytics", "onPageStart", [pageName]);
};

后续

在插件第一个版本发布到github后,极光的开源工程师和客服联系到俺,希望这个插件能给更多开发者提供帮助
然后我就来了,正好赶上有个征文活动~


至此感谢

@Pikachu 极光开源工程师: 帮俺完善了代码、文档以及测试工作。
@IrisJay 萌妹客服: 宽容俺调戏。

enjoy

如果cordova-plugin-janalytics帮助了你,那就请给个Star吧;如果发现有bug或者有意见,欢迎再github中PR和issues。