吐槽:weex 文档真心太少,特别是自定义插件,几乎为零,希望这篇文档对你有帮助
1.修改plugin模板文件
找到 weex plugin 命令执行代码
~/.xtoolkit/node_modules/weexpack/bin/weexpack-plugin.js
会发现最终模板文件在 generator-weex-plugin 里面
node_modules/generator-weex-plugin/../templates 下面js upperCamelCaseName 都改为 lowerCamelCaseName
package.json里面的copy:examples 改为
"rm -rf ./playground/android/app/src/main/assets/* && cp -vrf ./examples/build/* ./playground/android/app/src/main/assets/ &&rm -rf ./playground/ios/bundlejs/* && cp -vrf ./examples/build/* ./playground/ios/bundlejs/"
playground/android/gradle-wrapper.properties 改为4.1.
-
android/libary下面的build.gradle defaultConfig 新增
defaultConfig { ... javaCompileOptions { annotationProcessorOptions { includeCompileClasspath true } } ... }
-
playground/android/setting.gradle 将libary改成module名称
include ":getuipush" project (':getuipush').projectDir = new File("../../android/library")
app/build.gradle文件中修改为:
compile project(path: ':getuipush')
2. weex plugin create getui-push
-
生成的目录结构如下
├── android(Android插件工程) │ ├── buid.gradle(android发布文件) ├── ios(ios插件工程) ├── js(h5插件工程) ├── examples(例子,开发者用来测试问题) │ ├── build │ └── index.we ├── playground(测试实例,写好的module在各端做测试使用) │ ├── android(demo) │ ├── ios(demo) │ └── browser(demo) ├── ****.podspec(ios发布文件) ├── package.json(js发布文件) ├── README.md
最终js代码 (几行js代码 ios和android的推送就轻轻松松搞定)
const plugin = weex.requireModule('getuiPush'); plugin.initPush({ appId:'appId', appKey:'appKey', appSecret:'appSecret', }); plugin.onRegisterClient(function (clientId) { console.log('js 收到' + clientId); }); plugin.onReceivePayloadData(function (payloadData) { console.log('js 收到' + JSON.stringify(payloadData)); });
3.编写ios插件 代码 (以weex-getui-push 为例)
weex 会自动在ios/Sources目录下生成两个GetuiPushModule.h(头文件) GetuiPushModule.m(源文件)
-
配置个推sdk
- 在 根目录下的 GetuiPush.podspec 加入
s.dependency "GTSDK"
- 在 ios目录下的 Podfile 加入
pod 'GTSDK', '2.0.0.0-noidfa'
- 切入到playground/ios 目录 执行
pod update
- 在 根目录下的 GetuiPush.podspec 加入
-
初始化个推
-
js结构为:initPush(options)
我们需要现在 GetuiPushModule.h 头文件里面声明 initGeTui这个方法
//添加宏WX_EXPORT_METHOD, 它可以被weex识别 WX_EXPORT_METHOD(@selector(initPush:)) //js 初始化个推 - (void)initPush:(NSDictionary *)options { [self startSdkWith:options[@"appId"] appKey:options[@"appKey"] appSecret:options[@"appSecret"]]; //[2]:注册APNS [self registerRemoteNotification]; //打开app时候,消除掉badge [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { // iOS8以后 本地通知必须注册(获取权限) UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; } //[2-EXT]: 获取启动时收到的APN数据 }
-
-
当个推推送消息到客户端的时候需要告诉到js代码
js结构为:
plugin.onReceivePayloadData(callback)
-
声明变量来接收callback
@interface GetuiPushModule() @property(nonatomic,copy)WXModuleKeepAliveCallback onRegisterClientCallBack; @property(nonatomic,copy)WXModuleKeepAliveCallback onReceivePayloadDataCallBack; @end
-
同样在 GetuiPushModule.h声明 onReceivePayloadData这个方法
- (void)onRegisterClient:(WXModuleKeepAliveCallback)callback { self.onRegisterClientCallBack = callback; } - (void)onReceivePayloadData:(WXModuleKeepAliveCallback)callback { self.onReceivePayloadDataCallBack = callback; }
-
当个推推送消息到客户端,ios会执行GeTuiSdkDidReceivePayloadData,我们可以在该方法里通过以下代码回调js代码
-(void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId { NSDictionary *msgDict = [NSJSONSerialization JSONObjectWithData:payloadData options:NSJSONReadingAllowFragments error:nil]; self.onReceivePayloadDataCallBack(msgDict,true); }
如此,我们就能亲切的在看到js代码console.log(推送的消息)了
3.编写android插件 代码
weex 会自动生成GetuiPushModule.java
-
配置个推sdk
-
添加Maven库地址,在以项目名为命名的顶层build.gradle文件中,添加个推maven库地址
allprojects { repositories { jcenter() mavenCentral() //个推Maven URL地址 maven { url "http://mvn.gt.igexin.com/nexus/content/repositories/releases/" } } }
2.在libary/build.gradle文件中引用个推SDK依赖库
dependencies { compile 'com.getui:sdk:2.11.1.0' }
3.配置个推应用参数
在app/build.gradle文件中的android.defaultConfig下添加manifestPlaceholders,配置个推相关的应用参数
android { ... defaultConfig { ... manifestPlaceholders = [ GETUI_APP_ID : "APP_ID", GETUI_APP_KEY : "APP_KEY", GETUI_APP_SECRET : "APP_SECRET" ] } }
4.按照个推文档配置自定义推送服务、接收推送服务事件的service
5.在GetuiPushModule.java 里面添加initPush方法(正式开始了~)
@JSMethod public void initPush(Map param) { Log.d("param",param.toString()); PushManager.getInstance().initialize(this.mWXSDKInstance.getContext(), DemoPushService.class); PushManager.getInstance().registerPushIntentService(this.mWXSDKInstance.getContext(), PushIntentService.class); }
6.添加 clientId回调和消息回调方法
@JSMethod(uiThread = true) public void onRegisterClient(JSCallback callback){ GetuiPushModule.onRegisterClientCallBack = callback; } @JSMethod(uiThread = true) public void onReceivePayloadData(JSCallback callback){ GetuiPushModule.onReceivePayloadDataCallBack = callback; }
上面的callback 使用了一个静态变量存储,方便在PushIntentService 服务里面 执行回调方法给js
7.在PushIntentService 服务里回调js
@Override public void onReceiveClientId(Context context, String clientid) { GetuiPushModule.onRegisterClientCallBack.invoke(clientid); Log.e(TAG, "onReceiveClientId -> " + "clientid = " + clientid); } @Override public void onReceiveMessageData(Context context, GTTransmitMessage msg) { Log.e("onReceiveMessageData", "onReceiveMessageData"); byte[] payload = msg.getPayload(); Map json = (Map) JSON.parse(new String(payload)); GetuiPushModule.onReceivePayloadDataCallBack.invokeAndKeepAlive(json); }
可以看到 上面使用两个回调的方式 invoke 和 invokeAndKeepAlive
invoke适用于一次回调,invokeAndKeepAlive会保持连接,多次回调js
-
4.调试
npm run build & npm run copy:examples
ios 使用 xcode 打开 playground/ios (没有pod install 的话 先 pod update 下载依赖文件)
android 使用 android studio 打开 playground/android
weex 打包 module
1. 打包上传到weex market 和 js npm
weex plugin login
weex plugin publish
2. 发布iOS pod包
将源代码上传到github,并tag版本号
添加到本地仓库 git add ./*
提交commit到目的仓库 git commit -m "first commit"
提交到github git push -u origin master
给本地仓库打标签 git tag -a 0.0.1 -m "Relase version 0.0.1"
提交标签到远程仓库 git push origin --tags
注解:就像git push origin master 把本地修改提交到远程仓库一样,-tags可以把本地的打的标签全部提交到远程仓库。
验证.podspec
pod spec lint GetuiPush.podspec --verbose --use-libraries --allow-warnings
发布到CocoaPods
- 注册trunk,首先需要使用如下命令注册自己的电脑。这很简单,只要你指明你的邮箱地址(spec文件中的)和名称即可。CocoaPods 会给你填写的邮箱发送验证邮件,点击邮件中的链接就可通过验证。
pod trunk register scholar-ink@163.com "scholar-ink"
- 然后就可以发布你的 Pod 了。
pod trunk push GetuiPush.podspec --use-libraries --allow-warnings
发布成功后,需要等待pod团队审核(貌似1~2小时,还是npm好,不需要审核,这也是为什么npm一大堆的第三方包😁😁),审核成功后就可以使用pod search GetuiPush
搜索到你的 Pod 了!如果没有找到 可以使用pod setup
更新本地pod依赖库后再执行pod search
版本升级
当需要更新 Pod 版本的时候,修改 .podspec 中的 s.version 为更高的版本号,并修改 s.source 中对应的 Git 版本。提交到Git,并打上对应tag。然后再次执行pod trunk push GetuiPush.podspec
将新的 .podspec 发布到 CocoaPods。
为了更新更加方便,版本控制更加清晰,s.source 建议采用如下写法:
s.source = { :git => "https://github.com/scholar-ink/weex-plugin-getui-push.git", :tag => s.version}
3.打包android代码
可参考http://blog.csdn.net/jiankeufo/article/details/71191865
贴出我修改的重要几个地方:
1.在你modul的build.gradle文件中配置插件
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
-
在你Project的build.gradle文件中加入Maven和Jfrog Bintray的依赖插件:
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
-
重要配置 有注释的配置特别关注
def siteUrl = 'https://github.com/scholar-ink/weex-plugin-getui-push' // 项目的主页 def gitUrl = 'https://github.com/scholar-ink/weex-plugin-getui-push.git' // Git仓库的url version = "0.0.1" //这个是版本号,必须填写 group = "org.weex.plugin" // Maven Group ID for the artifact,一般填你唯一的包名 install{ repositories.mavenInstaller { // This generates POM.xml with proper parameters pom { project { packaging 'aar' // Add your description here name 'getui-push extend for weex' //项目描述 url siteUrl // Set your license licenses { license { name 'The Apache Software License, Version 2.0' url 'http://www.apache.org/licenses/LICENSE-2.0.txt' } } developers { developer { id 'zhouink' //填写bintray或者github的用户名 name 'zhouchao' //姓名 email 'zhouc1120@gmail.com'//邮箱 } } scm { connection gitUrl developerConnection gitUrl url siteUrl } } } } } task sourcesJar(type: Jar) { from android.sourceSets.main.java.srcDirs classifier = 'sources' } task javadoc(type: Javadoc) { source = android.sourceSets.main.java.srcDirs classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from javadoc.destinationDir } artifacts { archives javadocJar archives sourcesJar } Properties properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) bintray { user = properties.getProperty("bintray.user") //账号和apiKey key = properties.getProperty("bintray.apikey") configurations = ['archives'] pkg { repo = "maven" //仓库名,注意不是项目名 name = "getuipush" //发布到JCenter上的项目名字 websiteUrl = siteUrl vcsUrl = gitUrl licenses = ["Apache-2.0"] publish = true } }
值得提到的一点是 addPackageToJCenter 是需要审核的,而且审核时间还不短,郁闷中~完全没有js 的npm php的composer来的实在~