吐槽:weex 文檔真心太少旱幼,特別是自定義插件查描,幾乎為零,希望這篇文檔對(duì)你有幫助
1.修改plugin模板文件
找到 weex plugin 命令執(zhí)行代碼
~/.xtoolkit/node_modules/weexpack/bin/weexpack-plugin.js
會(huì)發(fā)現(xiàn)最終模板文件在 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
-
生成的目錄結(jié)構(gòu)如下
├── android(Android插件工程) │ ├── buid.gradle(android發(fā)布文件) ├── ios(ios插件工程) ├── js(h5插件工程) ├── examples(例子,開(kāi)發(fā)者用來(lái)測(cè)試問(wèn)題) │ ├── build │ └── index.we ├── playground(測(cè)試實(shí)例,寫(xiě)好的module在各端做測(cè)試使用) │ ├── android(demo) │ ├── ios(demo) │ └── browser(demo) ├── ****.podspec(ios發(fā)布文件) ├── package.json(js發(fā)布文件) ├── 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.編寫(xiě)ios插件 代碼 (以weex-getui-push 為例)
weex 會(huì)自動(dòng)在ios/Sources目錄下生成兩個(gè)GetuiPushModule.h(頭文件) GetuiPushModule.m(源文件)
-
配置個(gè)推sdk
- 在 根目錄下的 GetuiPush.podspec 加入
s.dependency "GTSDK"
- 在 ios目錄下的 Podfile 加入
pod 'GTSDK', '2.0.0.0-noidfa'
- 切入到playground/ios 目錄 執(zhí)行
pod update
- 在 根目錄下的 GetuiPush.podspec 加入
-
初始化個(gè)推
-
js結(jié)構(gòu)為:initPush(options)
我們需要現(xiàn)在 GetuiPushModule.h 頭文件里面聲明 initGeTui這個(gè)方法
//添加宏WX_EXPORT_METHOD, 它可以被weex識(shí)別 WX_EXPORT_METHOD(@selector(initPush:)) //js 初始化個(gè)推 - (void)initPush:(NSDictionary *)options { [self startSdkWith:options[@"appId"] appKey:options[@"appKey"] appSecret:options[@"appSecret"]]; //[2]:注冊(cè)APNS [self registerRemoteNotification]; //打開(kāi)app時(shí)候,消除掉badge [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { // iOS8以后 本地通知必須注冊(cè)(獲取權(quán)限) UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; } //[2-EXT]: 獲取啟動(dòng)時(shí)收到的APN數(shù)據(jù) }
-
-
當(dāng)個(gè)推推送消息到客戶端的時(shí)候需要告訴到j(luò)s代碼
js結(jié)構(gòu)為:
plugin.onReceivePayloadData(callback)
-
聲明變量來(lái)接收callback
@interface GetuiPushModule() @property(nonatomic,copy)WXModuleKeepAliveCallback onRegisterClientCallBack; @property(nonatomic,copy)WXModuleKeepAliveCallback onReceivePayloadDataCallBack; @end
-
同樣在 GetuiPushModule.h聲明 onReceivePayloadData這個(gè)方法
- (void)onRegisterClient:(WXModuleKeepAliveCallback)callback { self.onRegisterClientCallBack = callback; } - (void)onReceivePayloadData:(WXModuleKeepAliveCallback)callback { self.onReceivePayloadDataCallBack = callback; }
-
當(dāng)個(gè)推推送消息到客戶端,ios會(huì)執(zhí)行GeTuiSdkDidReceivePayloadData,我們可以在該方法里通過(guò)以下代碼回調(diào)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); }
如此螺句,我們就能親切的在看到j(luò)s代碼console.log(推送的消息)了
3.編寫(xiě)android插件 代碼
weex 會(huì)自動(dòng)生成GetuiPushModule.java
-
配置個(gè)推sdk
-
添加Maven庫(kù)地址阿宅,在以項(xiàng)目名為命名的頂層build.gradle文件中,添加個(gè)推maven庫(kù)地址
allprojects { repositories { jcenter() mavenCentral() //個(gè)推Maven URL地址 maven { url "http://mvn.gt.igexin.com/nexus/content/repositories/releases/" } } }
2.在libary/build.gradle文件中引用個(gè)推SDK依賴庫(kù)
dependencies { compile 'com.getui:sdk:2.11.1.0' }
3.配置個(gè)推應(yīng)用參數(shù)
在app/build.gradle文件中的android.defaultConfig下添加manifestPlaceholders桥滨,配置個(gè)推相關(guān)的應(yīng)用參數(shù)
android { ... defaultConfig { ... manifestPlaceholders = [ GETUI_APP_ID : "APP_ID", GETUI_APP_KEY : "APP_KEY", GETUI_APP_SECRET : "APP_SECRET" ] } }
4.按照個(gè)推文檔配置自定義推送服務(wù)窝爪、接收推送服務(wù)事件的service
5.在GetuiPushModule.java 里面添加initPush方法(正式開(kāi)始了~)
@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回調(diào)和消息回調(diào)方法
@JSMethod(uiThread = true) public void onRegisterClient(JSCallback callback){ GetuiPushModule.onRegisterClientCallBack = callback; } @JSMethod(uiThread = true) public void onReceivePayloadData(JSCallback callback){ GetuiPushModule.onReceivePayloadDataCallBack = callback; }
上面的callback 使用了一個(gè)靜態(tài)變量存儲(chǔ),方便在PushIntentService 服務(wù)里面 執(zhí)行回調(diào)方法給js
7.在PushIntentService 服務(wù)里回調(diào)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); }
可以看到 上面使用兩個(gè)回調(diào)的方式 invoke 和 invokeAndKeepAlive
invoke適用于一次回調(diào)齐媒,invokeAndKeepAlive會(huì)保持連接蒲每,多次回調(diào)js
-
4.調(diào)試
npm run build & npm run copy:examples
ios 使用 xcode 打開(kāi) playground/ios (沒(méi)有pod install 的話 先 pod update 下載依賴文件)
android 使用 android studio 打開(kāi) playground/android
weex 打包 module
1. 打包上傳到weex market 和 js npm
weex plugin login
weex plugin publish
2. 發(fā)布iOS pod包
將源代碼上傳到github,并tag版本號(hào)
添加到本地倉(cāng)庫(kù) git add ./*
提交commit到目的倉(cāng)庫(kù) git commit -m "first commit"
提交到github git push -u origin master
給本地倉(cāng)庫(kù)打標(biāo)簽 git tag -a 0.0.1 -m "Relase version 0.0.1"
提交標(biāo)簽到遠(yuǎn)程倉(cāng)庫(kù) git push origin --tags
注解:就像git push origin master 把本地修改提交到遠(yuǎn)程倉(cāng)庫(kù)一樣喻括,-tags可以把本地的打的標(biāo)簽全部提交到遠(yuǎn)程倉(cāng)庫(kù)邀杏。
驗(yàn)證.podspec
pod spec lint GetuiPush.podspec --verbose --use-libraries --allow-warnings
發(fā)布到CocoaPods
- 注冊(cè)trunk,首先需要使用如下命令注冊(cè)自己的電腦唬血。這很簡(jiǎn)單望蜡,只要你指明你的郵箱地址(spec文件中的)和名稱即可。CocoaPods 會(huì)給你填寫(xiě)的郵箱發(fā)送驗(yàn)證郵件刁品,點(diǎn)擊郵件中的鏈接就可通過(guò)驗(yàn)證泣特。
pod trunk register scholar-ink@163.com "scholar-ink"
- 然后就可以發(fā)布你的 Pod 了。
pod trunk push GetuiPush.podspec --use-libraries --allow-warnings
發(fā)布成功后挑随,需要等待pod團(tuán)隊(duì)審核(貌似1~2小時(shí)状您,還是npm好,不需要審核兜挨,這也是為什么npm一大堆的第三方包????)膏孟,審核成功后就可以使用pod search GetuiPush
搜索到你的 Pod 了!如果沒(méi)有找到 可以使用pod setup
更新本地pod依賴庫(kù)后再執(zhí)行pod search
版本升級(jí)
當(dāng)需要更新 Pod 版本的時(shí)候拌汇,修改 .podspec 中的 s.version 為更高的版本號(hào)柒桑,并修改 s.source 中對(duì)應(yīng)的 Git 版本。提交到Git噪舀,并打上對(duì)應(yīng)tag魁淳。然后再次執(zhí)行pod trunk push GetuiPush.podspec
將新的 .podspec 發(fā)布到 CocoaPods飘诗。
為了更新更加方便,版本控制更加清晰界逛,s.source 建議采用如下寫(xiě)法:
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
貼出我修改的重要幾個(gè)地方:
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'
-
重要配置 有注釋的配置特別關(guān)注
def siteUrl = 'https://github.com/scholar-ink/weex-plugin-getui-push' // 項(xiàng)目的主頁(yè) def gitUrl = 'https://github.com/scholar-ink/weex-plugin-getui-push.git' // Git倉(cāng)庫(kù)的url version = "0.0.1" //這個(gè)是版本號(hào)昆稿,必須填寫(xiě) 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' //項(xiàng)目描述 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' //填寫(xiě)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") //賬號(hào)和apiKey key = properties.getProperty("bintray.apikey") configurations = ['archives'] pkg { repo = "maven" //倉(cāng)庫(kù)名息拜,注意不是項(xiàng)目名 name = "getuipush" //發(fā)布到JCenter上的項(xiàng)目名字 websiteUrl = siteUrl vcsUrl = gitUrl licenses = ["Apache-2.0"] publish = true } }
值得提到的一點(diǎn)是 addPackageToJCenter 是需要審核的溉潭,而且審核時(shí)間還不短,郁悶中~完全沒(méi)有js 的npm php的composer來(lái)的實(shí)在~