概述
OpenApp+ 一個小程式容器,配置簡單、功能完善、介面流暢、開箱即用!使用OpenApp+可以快速擴充套件你的APP,使其擁有與微信一樣的功能擴充套件可能,讓App的所有的功能都通過小程式來實現,動態更新,更快的響應使用者需求。其擁有的管理具備版本管理功能,讓功能釋出更加隨心。
整合SDK
獲得 AppKey
在平臺上註冊帳號,可以任意新增新 App,每一個 App 都有一個唯一的 AppKey 作為標識,平臺提供客戶端的AppKey、Appsecret和服務端的AppKey、Appsecret以便接入
iOS整合
Cocoapods 安裝
推薦使用 CocoaPods 的方式安裝使用。
CocoaPods 是一個廣泛適用於Objective-C依賴管理工具,能夠自動配置專案,簡化你配置Openapp+的過程,使用以下命令列安裝
$ gem install cocoapods
OpenApplus 安裝
使用CocosPods整合Openapp+到Xcode,需要編寫/podspec/OpenApplus.podspec檔案
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
在Podfile檔案加入
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
在工程中Info.plist檔案中新增如下項
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
執行
在 AppDelegate.m 裡按順序呼叫三個方法:
1、呼叫 +startWithAppKey: ,引數為第一步獲得的 AppKey。
2、呼叫 +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 包,不需要等使用者下次啟動。
Android整合
Android Studio整合
下載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.** {*;}
新增Activty入口
在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();
小程式 API
授權登入流程
一、App接入
第一步:獲取服務端的AppKey、AppSecret、AppKey、JsAppsecret
在進行OpenApp+ OAuth2授權登入接入之前,在開放平臺註冊【http://www.openapplus.com/】開發者帳號,並擁有一個已稽核通過的網站應用, 獲取應用的AppKey、AppSecret,並獲得相應的服務端的JsAppKey、JsAppsecret,申請OpenApp+登入且通過稽核後,可開始接入流程。
第二步:配置App的授權介面
[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的過期時間 |
二、小程式接入
第一步:獲取小程式的JsAppKey、JsAppsecret
在進行OpenApp+ OAuth2授權登入接入之前,在開放平臺註冊【http://www.openapplus.com/】開發者帳號,並擁有一個已稽核通過的小程式專案,並獲得相應的服務端的JsAppKey、JsAppsecret,將其授權到應用後,可開始接入流程。
第二步:前端呼叫登入API
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失敗!");
}
}
});
第三步:通過jsToken獲取獲取後臺session
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的過期時間 |
第五步:通過session呼叫介面
能呼叫的介面有以下:
| 介面|介面URL|介面說明|
| :——| ——: | ——: |
| /auth/jsapp/getUser| http://www.openapplus.com/aut… | 獲取使用者個人資訊 |
客戶端
my. getAuthCode(OBJECT)
呼叫介面獲取登入憑證(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,
});
},
});
my. navigateToMiniProgram(OBJECT)
開放小程式容器操作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) {
// 開啟成功
}
})
wx.navigateBackMiniProgram(OBJECT)
返回到上一個小程式,只有在當前小程式是被其他小程式開啟時可以呼叫成功
OBJECT引數說明:
引數 | 型別 | 必填 | 說明 |
---|---|---|---|
extraData | String | 否 | 需要返回給上一個小程式的資料,上一個小程式可在 App.onShow(e) 中獲取到這份資料。引數e格式為:{path: “”, query: query},其中query 為extraData,僅支援一層字典 |
success | function | 否 | 呼叫成功的回撥函式 |
fail | function | 否 | 呼叫失敗的回撥函式 |
complete | function | 否 | 呼叫結束的回撥函式(呼叫成功、失敗都會執行) |
my.alert(OBJECT)
alert 警告框。
OBJECT引數說明:
引數 | 型別 | 必填 | 說明 |
---|---|---|---|
title | String | 否 | alert框的標題 |
content | function | 否 | alert框的內容 |
buttonText | function | 否 | 按鈕文字,預設確定 |
success | function | 否 | 呼叫成功的回撥函式 |
fail | function | 否 | 呼叫失敗的回撥函式 |
complete | function | 否 | 呼叫結束的回撥函式(呼叫成功、失敗都會執行) |
my.confirm(OBJECT)
confirm 確認框。
OBJECT引數說明:
引數 | 型別 | 必填 | 說明 |
---|---|---|---|
title | String | 否 | alert框的標題 |
content | function | 否 | alert框的內容 |
confirmButtonText | function | 否 | 確認按鈕文字,預設‘確定’ |
cancelButtonText | function | 否 | 確認按鈕文字,預設‘取消’ |
success | function | 否 | 呼叫成功的回撥函式 |
fail | function | 否 | 呼叫失敗的回撥函式 |
complete | function | 否 | 呼叫結束的回撥函式(呼叫成功、失敗都會執行) |
my. showToast(OBJECT)
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()
隱藏弱提示。
示例程式碼:
my.hideToast()
my. showLoading()
顯示載入提示。
OBJECT引數說明:
引數 | 型別 | 必填 | 說明 |
---|---|---|---|
content | String | 否 | alert框的標題 |
delay | Integer | 否 | 延遲顯示,單位 ms,預設 0。如果在此時間之前呼叫了 my.hideLoading 則不會顯示 |
success | function | 否 | 呼叫成功的回撥函式 |
fail | function | 否 | 呼叫失敗的回撥函式 |
complete | function | 否 | 呼叫結束的回撥函式(呼叫成功、失敗都會執行) |
示例程式碼:
my.showLoading({
content: `載入中...`,
delay: 1000,
});
my. hideLoading()
隱藏載入提示。
示例程式碼:
my.hideLoading();
my. datePicker(OBJECT)
開啟日期選擇列表。
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()
隱藏鍵盤。
示例程式碼:
my. hideKeyboard();
SDK API
+startWithAppKey:
傳入在平臺申請的 appKey,啟動 JSPatch SDK。同時會自動執行已下載到本地的 patch 指令碼。建議在 -application:didFinishLaunchingWithOptions: 開頭處呼叫。
+sync
與 OpenApplus 平臺後臺同步,詢問是否有包更新,如果有更新會自動下載並執行。
!!注意 +startWithAppKey: 並不會詢問後臺包更新,必須呼叫 +sync 方法。
每呼叫一次 +sync 就會請求一次後臺,對於實時性要求不高的 APP,只需在 -application:didFinishLaunchingWithOptions: 處呼叫一次,這樣使用者會在啟動時去同步 patch 資訊。對於實時性要求高的 APP,可以在 -applicationDidBecomeActive: 處呼叫這個介面,這樣會在每次使用者喚醒 APP 時去同步一次後臺,請求次數會增多,但有包更新時使用者會及時收到。