OpenApp+ 一個小程序容器,配置簡單、功能完善、界面流暢、開箱即用!使用OpenApp+能夠快速擴展你的APP,使其擁有與微信同樣的功能擴展可能,讓App的全部的功能都經過小程序來實現,動態更新,更快的響應用戶需求。其擁有的管理具有版本管理功能,讓功能發佈更加隨心。前端
在平臺上註冊賬號,能夠任意添加新 App,每個 App 都有一個惟一的 AppKey 做爲標識,平臺提供客戶端的AppKey、Appsecret和服務端的AppKey、Appsecret以便接入android
推薦使用 CocoaPods 的方式安裝使用。ios
CocoaPods 是一個普遍適用於Objective-C依賴管理工具,可以自動配置項目,簡化你配置Openapp+的過程,使用如下命令行安裝git
$ gem install cocoapodsgithub
使用CocosPods集成Openapp+到Xcode,須要編寫/podspec/OpenApplus.podspec文件shell
Pod::Spec.new do |s| s.name = "OpenApplus" s.version = "1.0.0" s.summary = "OpenApplus framework" s.homepage = "http://github.com/linwaiwai/openapplus" s.license = { :type => 'OpenApplus License, Version 1.0.0', :text => <<-LICENSE Licensed under the OpenApplus License, Version 1.0.0 (the "License"); you may not use this file except in compliance with the License. LICENSE } s.author = "linwaiwai" s.platform = :ios, "6.0.0" s.source = { :git => "https://github.com/linwaiwai/openapplus.git", :branch => "master"} s.frameworks = "UIKit" s.requires_arc = true s.dependency 'SDWebImage', '3.7.5' s.dependency 'SSZipArchive', '1.6.2' s.dependency 'SVProgressHUD', '2.1.2' s.dependency 'Masonry', '1.0.2' s.dependency 'UMengUShare/Social/WeChat', '6.3.0' s.dependency 'MJRefresh', '3.1.12' s.dependency 'libextobjc', '~> 0.4.1' s.dependency 'AFNetworking' s.dependency 'OpenUDID' s.subspec 'OpenApplus' do |ss| ss.vendored_frameworks = '*.framework' ss.vendored_libraries = '*.a' ss.source_files = '*.h' ss.resource = '*.bundle' end end
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' #忽略引入庫的警告 inhibit_all_warnings! target 'openapplus-ios-demo' do pod 'OpenApplus', :podspec => './podspec/OpenApplus.podspec' end
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
在 AppDelegate.m 裏按順序調用三個方法:小程序
一、調用 +startWithAppKey: ,參數爲第一步得到的 AppKey。api
二、調用 +sync 方法檢查包更新。安全
在AppDelegate.m或ViewController.m中調用 navigateToMiniProgram: 加載小程序項目,參數爲在平臺中建立的項目的名稱。服務器
#import <"openapplus/openapplus.h"> @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:testViewController]; self.window.rootViewController = navigationController; [self.window makeKeyAndVisible]; [OpenApplus startWithAppKey:@"test"]; [OpenApplus sync]; [OpenApplus setNavigationController:navigationController]; // JS_APPID 爲小程序的APP_ID [OpenApplus navigateToMiniProgram:@"openapplus://jsApp/#JS_APPID#" completion:^{ }]; ... } @end
上述例子是把 Openapplus 同步放在 -application:didFinishLaunchingWithOptions: 裏,若但願包能及時推送,能夠把 [OpenApplus sync] 放在 -applicationDidBecomeActive: 裏,每次喚醒都能同步更新 OpenApplus 包,不須要等用戶下次啓動。
下載SDK功能組件,解壓.zip文件獲得相應組件包(openapplus-release.aar),在Android Studio的項目工程libs目錄中拷入相關組件jar包。
右鍵Android Studio的項目工程—>選擇Open Module Settings —>在 Project Structure彈出框中 —>選擇 Dependencies選項卡 —>點擊左下「+」—>選擇組件包類型—>引入相應的組件包。
在項目工程的自定義application中的onCreate方法中添加如下兩個方法:
注意:必定要在主進程進行該項操做
OpenApplus.registerApp(this, SampleContants.APPID, SampleContants.APP_SECRET); OpenApplus.sync(); OpenApplus.setCallback(new OpenApplusCallback() { @Override public void invoke(OACallbackType type, JSONObject data, OpenApplusNotify notify) { if (type == OACallbackType.OACallbackTypeAuthUser){ // 該接口僅供測試使用,請使用服務端發送給受權請求 OARequestWrapper requestWrapper = OpenApplus.makeRequestWrapper(SampleContants.SERVER_APPID, SampleContants.SERVER_APP_SECRET); OAAuthDtoWrapper dto = new OAAuthDtoWrapper(); dto.setUid("1"); try { dto.setCode(data.getString("code")); } catch (JSONException e) { e.printStackTrace(); } String deviceID = Settings.Secure.getString(WXEnvironment.sApplication.getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID); dto.setDeviceid(deviceID); requestWrapper.sendObject(dto, notify); } } });
注意:
參數1:上下文,必須的參數,不能爲空
參數2:OpenApplus app key,必須參數。
參數3:OpenApplus app secret,必須參數。
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.READ_LOGS"/> <!-- 這個權限用於進行網絡定位 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <!-- 這個權限用於訪問GPS定位 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_GPS"/> <uses-feature android:name="android.hardware.camera"/> <uses-feature android:name="android.hardware.camera.autofocus"/> <uses-permission android:name="getui.permission.GetuiService.com.bmdoctor.jyt"/> <!--amap額外權限--> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
若是您的應用使用了混淆, 請添加
-keep class com.openapplus.** {*;}
在AndroidManifest.xml中添加
<activity android:name="com.openapplus.activity.OATinyProgramActivity"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="com.benmu.weex.example.categoty.page"/> <data android:scheme="http"/> <data android:scheme="https"/> </intent-filter> </activity>
Intent intent = new Intent(SplashActivity.this, OATinyProgramActivity.class); intent.putExtra("tiny","openapplus://jsApp/xxxxx"); startActivity(intent); finish();
在進行OpenApp+ OAuth2受權登陸接入以前,在開放平臺註冊【http://www.openapplus.com/】開發者賬號,並擁有一個已審覈經過的網站應用, 獲取應用的AppKey、AppSecret,並得到相應的服務端的JsAppKey、JsAppsecret,申請OpenApp+登陸且經過審覈後,可開始接入流程。
[OpenApplus startWithAppKey:@"AppKey" andSecret:@"AppSecret"]; NSString *uid = @"111"; [OAConfiguration setUserIdentify:uid]; [OpenApplus setupCallback:^(OACallbackType type, id data, OpenApplusNotify notify, NSError *error) { switch (type) { case OACallbackTypeAuthUser: { // http://www.openapplus.com/auth/auth,請求該接口獲取token和超時時間 OAContainerAuthObject *containerAuthObject = [[OAContainerAuthObject alloc] init]; containerAuthObject.token = @""; containerAuthObject.expired = @""; notify(containerAuthObject, nil); // 使用App服務端的AppKey和AppSecret,如下注釋代碼由於使用簡易方式,沒有通過服務端的驗證,而且將AppServerKey,AppServerSecret暴露在客戶端,屬於不安全的簡易方式,僅供測試或者沒有服務器的app的使用,再次申請,該方式不安全。 // OARequestWrapper *requestWrapper = [OpenApplus requestWithAppKey:@"AppServerKey" andSecret:@"AppServerSecret"]; // OAAuthDtoWrapper *dto = [[OAAuthDtoWrapper alloc] init]; // dto.code = [data performSelector:@selector(code)]; // dto.deviceid = [OpenUDID value]; // dto.uid = uid; // [requestWrapper sendObject:dto thenNotify:notify]; } }]
用戶認證接口
http://www.openapplus.com/auth/auth
請求方式:
POST, ContentType:x-www-form-urlencode
參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
appKey | String | 是 | 應用appServerKey |
code | String | 是 | 受權code |
deviceid | String | 是 | 設備deviceid |
uid | String | 是 | 用戶標識 |
timestamp | String | 是 | 當前時間戳 |
signature | String | 是 | 使用簽名規則生成的簽名sha1(toquery(sort(params))) , 參數中密鑰爲:appSecret=appSecret |
返回說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
code | String | 是 | 狀態編碼 |
data | String | 是 | 返回數據 |
message | String | 是 | 錯誤信息 |
data參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
token | String | 是 | 受權token |
expired | String | 是 | 爲session的過時時間 |
在進行OpenApp+ OAuth2受權登陸接入以前,在開放平臺註冊【http://www.openapplus.com/】開發者賬號,並擁有一個已審覈經過的小程序項目,並得到相應的服務端的JsAppKey、JsAppsecret,將其受權到應用後,可開始接入流程。
my.getAuthCode({ jsAppKey: 'jsAppKey', success: (loginResponse) => { if (!loginResponse.error){ let sessionData = { token: loginResponse.authCode, jsAppKey: that.config.jsAppKey } let qs = require('qs') my.httpRequest({ url: 'http://httpbin.org/post', method: 'POST', data: sessionData, success: function(res) { if (parseInt(respData.data.code) === 1) { console.debug("獲取jsToken成功!jsToken爲:" + respData.data.jsToken); } }, fail: function(res) { console.debug("獲取authCode失敗!"); }, complete: function(res) { } }); } else { console.debug("獲取jsToken失敗!"); } } });
http://www.openapplus.com/auth/jsapp/code2session
請求方式:
POST, ContentType:x-www-form-urlencode
參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
jsAppKey | String | 是 | 該應用的jsAppKey |
token | String | 是 | 前端獲取的jsToken |
timestamp | String | 是 | 當前時間戳 |
signature | String | 是 | 使用簽名規則生成的簽名sha1(toquery(sort(params))) , 參數中密鑰爲:appSecret=jsAppSecret |
返回說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
code | String | 是 | 狀態編碼 |
data | String | 是 | 響應數據 |
message | String | 是 | 錯誤信息 |
data參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
session | String | 是 | 受權會話 |
expired | String | 是 | 爲session的過時時間 |
能調用的接口有如下:
| 接口|接口URL|接口說明|
| :------| ------: | ------: |
| /auth/jsapp/getUser| http://www.openapplus.com/aut... | 獲取用戶我的信息 |
調用接口獲取登陸憑證(jsAppToken)進而換取用戶登陸態信息,包括用戶的惟一標識(openid) 及本次登陸的 會話密鑰(session_key)。用戶數據的加解密通信須要依賴會話密鑰完成。
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
jsAppKey | String | 是 | 小程序應用AppKey |
success | function | 否 | 調用成功的回調函數 |
fail | function | 否 | 調用失敗的回調函數 |
complete | function | 否 | 調用結束的回調函數(調用成功、失敗都會執行) |
CALLBACK返回參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
authCode | String | 是 | 受權碼,用戶容許登陸後,回調內容會帶上 authCode(有效期五分鐘),開發者須要將 authCode 發送到開發者服務器後臺,使用code 換取 session_key api,將 authCode 換成 openid 和 session_key |
expired | Timestamp | 是 | 過時時間 |
示例代碼:
my.getAuthCode({ jsAppKey: 'jsAppKey', success: (res) => { my.alert({ content: res.authCode, }); }, });
開放小程序容器操做API,打開同一App下關聯的另外一個小程序。
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
appId | String | 是 | 要打開的小程序 jsAppKey |
path | String | 否 | 打開的頁面路徑,若是爲空則打開首頁 |
extraData | String | 否 | 須要傳遞給目標小程序的數據,目標小程序可在 App.onLaunch(e),App.onShow(e) 中獲取到這份數據。參數e格式爲:{path: "", query: query},其中query 爲extraData,僅支持一層字典 |
url | String | 是 | 和appId兩者選擇一個,打開小程序的URL,格式爲:openapplus://jsApp/e03f37ba425a47e6aafd8170eee6be52/param1=value1¶m2=value2, 若是參數中提供了instancId,會嘗試打開已有頁面 |
success | function | 否 | 調用成功的回調函數 |
fail | function | 否 | 調用失敗的回調函數 |
complete | function | 否 | 調用結束的回調函數(調用成功、失敗都會執行) |
示例代碼:
my.navigateToMiniProgram({ appId: '', path: 'pages/index/index', extraData: { foo: 'bar' }, envVersion: 'develop', success(res) { // 打開成功 } })
返回到上一個小程序,只有在當前小程序是被其餘小程序打開時能夠調用成功
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
extraData | String | 否 | 須要返回給上一個小程序的數據,上一個小程序可在 App.onShow(e) 中獲取到這份數據。參數e格式爲:{path: "", query: query},其中query 爲extraData,僅支持一層字典 |
success | function | 否 | 調用成功的回調函數 |
fail | function | 否 | 調用失敗的回調函數 |
complete | function | 否 | 調用結束的回調函數(調用成功、失敗都會執行) |
alert 警告框。
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
title | String | 否 | alert框的標題 |
content | function | 否 | alert框的內容 |
buttonText | function | 否 | 按鈕文字,默認肯定 |
success | function | 否 | 調用成功的回調函數 |
fail | function | 否 | 調用失敗的回調函數 |
complete | function | 否 | 調用結束的回調函數(調用成功、失敗都會執行) |
confirm 確認框。
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
title | String | 否 | alert框的標題 |
content | function | 否 | alert框的內容 |
confirmButtonText | function | 否 | 確認按鈕文字,默認‘肯定’ |
cancelButtonText | function | 否 | 確認按鈕文字,默認‘取消’ |
success | function | 否 | 調用成功的回調函數 |
fail | function | 否 | 調用失敗的回調函數 |
complete | function | 否 | 調用結束的回調函數(調用成功、失敗都會執行) |
confirm 確認框。
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
content | String | 否 | alert框的標題 |
type | function | 否 | alert框的內容 |
success | function | 否 | 調用成功的回調函數 |
fail | function | 否 | 調用失敗的回調函數 |
complete | function | 否 | 調用結束的回調函數(調用成功、失敗都會執行) |
示例代碼:
my.showToast({ type: 'success', content: '操做成功', duration: 3000, success: () => { my.alert({ title: 'toast 消失了', }); }, });
隱藏弱提示。
示例代碼:
my.hideToast()
顯示加載提示。
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
content | String | 否 | alert框的標題 |
delay | Integer | 否 | 延遲顯示,單位 ms,默認 0。若是在此時間以前調用了 my.hideLoading 則不會顯示 |
success | function | 否 | 調用成功的回調函數 |
fail | function | 否 | 調用失敗的回調函數 |
complete | function | 否 | 調用結束的回調函數(調用成功、失敗都會執行) |
示例代碼:
my.showLoading({ content: '加載中...', delay: 1000, });
隱藏加載提示。
示例代碼:
my.hideLoading();
打開日期選擇列表。
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
format | String | 否 | 返回的日期格式,yyyy-MM-dd(默認)HH:mm yyyy-MM-dd HH:mm yyyy-MM yyyy |
currentDate | String | 否 | 初始選擇的日期時間,默認當前時間 |
startDate | String | 否 | 最小日期時間 |
endDate | String | 否 | 最大日期時間 |
success | function | 否 | 調用成功的回調函數 |
fail | function | 否 | 調用失敗的回調函數 |
complete | function | 否 | 調用結束的回調函數(調用成功、失敗都會執行) |
success返回參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
date | String | 是 | 選擇的日期 |
示例代碼:
my.datePicker({ format: 'yyyy-MM-dd', currentDate: '2012-12-12', startDate: '2012-12-10', endDate: '2012-12-15', success: (res) => { my.alert({ content: res.date, }); }, });
隱藏鍵盤。
示例代碼:
my. hideKeyboard();
傳入在平臺申請的 appKey,啓動 JSPatch SDK。同時會自動執行已下載到本地的 patch 腳本。建議在 -application:didFinishLaunchingWithOptions: 開頭處調用。
與 OpenApplus 平臺後臺同步,詢問是否有包更新,若是有更新會自動下載並執行。
!!注意 +startWithAppKey: 並不會詢問後臺包更新,必須調用 +sync 方法。
每調用一次 +sync 就會請求一次後臺,對於實時性要求不高的 APP,只需在 -application:didFinishLaunchingWithOptions: 處調用一次,這樣用戶會在啓動時去同步 patch 信息。對於實時性要求高的 APP,能夠在 -applicationDidBecomeActive: 處調用這個接口,這樣會在每次用戶喚醒 APP 時去同步一次後臺,請求次數會增多,但有包更新時用戶會及時收到。