企业App Store开发指南

概述

移动应用商店(AppStore)是企业服务的一个增值功能,通过创建移动应用商店可以对平台开发的移动应用进行集中管控,包括版本、升级、上线/下线等,并可以支持和其他移动端产品进行配合使用,打造企业融合应用平台,为移动应用的分发、集中管理和运营提供便利。

本文档分为四部分:

  • 第一部分介绍创建和配置App Store应用。
  • 第二部分针对于开发者,帮助开发者了解这个项目,从而熟悉代码进行二次开发。
  • 第三部分写给后台管理者的,帮助管理者了解平台的使用方法。
  • 第四部分是App Store的接口文档,详细展示了返回的数据列表。

App Store创建文档

App Store应用是一个应用管理的APP,与创建普通应用不同的是,创建后会开放控制台权限,即在企业服务中,会有一个应用管理的后台,可以对应用和权限进行管理。

企业App Store开发指南 - 图1

创建应用

企业App Store开发指南 - 图2

  • 在首页创建应用

企业App Store开发指南 - 图3

  • 选择APPStore,进行创建

企业App Store开发指南 - 图4

  • 在应用信息中记录应用ID和appKey

修改代码配置文件

企业App Store开发指南 - 图5

  • 用Studio2将代码同步到本地,将res路径下的key.xml中appKey和appId修改为刚才创建的id和appKey,host修改为云服务器的地址
  • Studio2使用教程参考:APICloud Studio2 使用教程

企业App Store开发指南 - 图6

  • 如有需要,可以在script路径中修改service.js中的云端数据库的名称,保证与云端数据库中的表名相同。

企业App Store开发指南 - 图7

编译应用

提交代码,进行云编译。

开发者文档

为了方便开发者更快的熟悉本项目,能够很好的熟悉代码逻辑和对项目进行二次开发,本文档将按照物理.html 文件进行分析,从而制定本文档。文档中会大致讲解项目主体思想,细节还是需要开发者自行理解。

App Store 项目概述

该项目代码层面的功能主要有全局( appkey、appid、host等 )字段的获取、 子应用下载、子应用更新、子应用解压、子应用命名、打开子应用、 删除子应用、展示子应用等功能。

项目结构目录

企业App Store开发指南 - 图8

企业App Store开发指南 - 图9

index.html

根目录中的index.html是项目的入口文件,该页面只是做了基本的布局显示,没有什么逻辑。布局它包括 首页头部布局、$api.fixStatusBar 兼容沉浸式、全局值 appkeyappidhost 获取、开启main.html页面、双击返回退出应用等。

html路径

main.html

这个文件是index.html通过api.openFrame()方法启动的。

  • 初始化了APP信息,通过getDefaulItems()方法获取后台配置的应用信息,并且创建本地数据库,存到本地作为缓存。注意,getDefaulItems()方法只有在第一次应用安装后启动的时候才会从网络获取应用列表,第二次直接从本地数据库中读取数据。
  • 初始化banner图,从网络数据库获取banner表中的数据,如果banner表中没有数据,则默认显示一张默认图片,有数据的话从数据库读取网络图片进行展示。
  • 通过isNative字段来判断应用类型来打开不同的应用。(0:平台应用,1:原生应用,2:H5应用)
  • 注册监听事件,每当数据改变的时候,通过发送时间refreshHomeApps刷新APP列表。
edit-app-win.html

这个文件是index.html右上角编辑按钮通过api.openWin()方法启动的。只是初始化了头部布局,打开子页面frame。

edit-app-frame.html

这个文件是edit.html通过api.openFrame()方法启动的。

  • initSortable()初始化拖动组件,设置监听Touch事件,来实现排序功能。
  • removeItem()方法是用来移除一个APP的
  • 如果数据发生变动,返回到首页的时候会把新数据保存到数据库中,如果没有变化,则不保存,直接返回。
install-app-win.html

这个文件是index.html左上角添加按钮通过api.openWin()方法启动的。只是初始化了头部布局,通过api.openFrameGroup()方法打开了install-app-all-frame.htmlinstall-app-add-frame.htmlinstall-app-update-frame.html三个页面。

install-app-all-frame.html

这个是全部应用的frame

  • 通过getAppsList()方法获取网络数据库中的应用列表,实现了分页加载,一页10条数据,可以通过修改itemNum来自定义每页展示APP数量。
  • 通过filterAppStatus()来过滤应用的安装更新状态。
  • 判断不同应用类型来下载、安装、打开应用,可参考代码注释理解。
install-app-add-frame.html

这个是添加应用的frame

  • 通过getAppsList()方法获取网络数据库中的应用列表,实现了分页加载,一页10条数据,可以通过修改itemNum来自定义每页展示APP数量。
  • 通过filterInstallApp()来过滤首页已经展示的应用。
  • 判断不同应用类型来下载、安装、打开应用,可参考代码注释理解。
install-app-update-frame.html

这个是更新应用的frame

  • 通过getApps()方法来获取应用更新,安装、下载、启动请参考代码及注释。
  • 操作后,对首页中的数量提示进行修改。
search-win.html

这个是搜索页面,通过应用管理右上角的搜索图标进入的,初始化页面页头,通过api.openFrame打开frame页面。

search-frame.html

这个页面展示了搜索的结果。

  • 通过getAppsList()方法获取网络数据库中的应用列表。
  • 通过filterAppStatus()来过滤首页已经展示的应用。
  • 判断不同应用类型来下载、安装、打开应用,可参考代码注释理解。
h5.html

这个页面是为了打开H5应用的Win,直接通过api.openFrame()来启动H5应用的。

script路径

service.js

定义了各种开发时可能需要用到的参数,以及对数据库操作的封装,其中包括预定义参数UI类 API辅助类 API业务逻辑操作API,开发者只需要根据自己的需求调用对应的方法即可,也可以自定义方法,添加到该文件的下方。

doT.min.js

精巧快速的JavaScript模板引擎 更多使用介绍参考:doT使用文档

Sortable.js

拖动组件,具体使用方法参考官方文档。 Sortable.js官方文档

common.js

这里面整合了平台应用、原生应用的启动更新等公共方法,可以在任意界面进入使用。

res路径

key.xml
  1. <security>
  2. <item name="appKey" value="AC57D32D-D095-9755-D439-894084E1EA09"/>
  3. <!-- 应用ID -->
  4. <item name="appId" value="A6055161489142"/>
  5. <!-- 云服务器根路径 -->
  6. <item name="host" value="https://d.apicloud.com/"/>
  7. </security>

企业App Store开发指南 - 图10

  • appKey 为创建的应用的应用appKey
  • appId 为应用下方的ID值
  • host 云服务器根路径,这里填写服务器地址

功能模块图

企业App Store开发指南 - 图11

模块介绍

创建App Store应用的时候默认添加下述8个模块,推荐开发者在开发过程中添加常用的模块到App Store中,来支持打开平台应用中引用的模块,避免平台应用中使用到的模块在App Store中没有而不能使用的问题。

arcProgress模块

arcProgress是一个弧形进度条,包括环形、扇形、类月牙形三种样式,开发者可以自定义进度色和背景色。此模块动画流畅,原生实现效果炫酷,有效的解决了网页画圆会有锯齿的问题 更多使用参考:arcProgress详细使用文档

UIPullRefreshFlash模块

UIPullRefreshFlash 模块对引擎新推出的下拉刷新接口进行了一层封装,App 可以通过此模块来实现带炫酷动画效果的下拉刷新功能。使用此模块,在用户下拉时本模块会随用户下拉高度而放大缩小下拉出的提示图标,同时会随用户下拉高度播放一组关键帧图片,该图片数组是通过 api.setCustomRefreshHeaderInfo 接口以图片数组的形式传给模块的,每下拉一定距离(阈值/图片数量),播放一帧图片;当下拉高度达到一定阈值后触发加载事件:进入加载状态时,刷新提示图标开始播放加载关键帧图片数组,此时图片每帧间隔为 50 毫秒,同时将下拉刷新事件回发给前端。前端得到下拉刷新事件后开始加载数据;数据加载完毕,调用接口 api.refreshHeaderLoadDone 以停止加载状态。 更多使用参考:UIPullRefreshFlash详细使用文档

UIScrollPicture模块

UIScrollPicture 是一个图片轮播模块,只需传入一组图片地址,即可实现图片轮播效果。 更多使用参考:UIScrollPicture详细使用文档

zip模块

zip 模块封装了 zip 文件解压缩的相关操作,开发者只需简单地调用相关接口,即可实现对 zip 文件的操作,易学简单易掌握。 更多使用参考:zip详细使用文档

signature模块

signature 是一个加密模块,可以把指定字符串按照 MD5、AES、BASE64、sha1方式加密,本模块的每个接口都实现了两套方法,同步和异步。开发者可按需求自行选择接口调用。 更多使用介绍参考:signature详细使用文档

db模块

db 模块封装了手机常用数据库 sqlite 的增删改查语句,可实现数据的本地存储,极大的简化了数据持久化问题,本模块已支持同步接口。 更多使用介绍参考:db详细使用文档

mam模块

默认平台会自动检测版本更新,用户也可以在config.xml里配置autoUpdate为false,然后使用mam模块来检测更新,mam模块还提供自定义事件功能。 更多使用介绍参考:mam详细使用文档

二次开发

根据模板再开发

开发者可以根据生成的代码,进行修改后二次开发功能,根据上面描述的文件项目内容,来定制自己的开发需求。

原生应用集成App Store

Android或者iOS原生应用来集成App Store的功能,可以通过使用superWebView的方式实现原生混合集成App Store。 具体集成文档可以参考: SuperWebview开发指南Android SuperWebview开发指南iOS

平台应用集成App Store

平台创建的Native应用,通过把App Store的widget集成到应用中,调用api.openWidget()方法来打开App Store,同样可以实现集成。

后台管理者文档

APICloud控制台管理

企业App Store开发指南 - 图12

  • 登录APICloud控制台首页,在左侧选择要管理的App Store应用

企业App Store开发指南 - 图13

  • 在应用的后台选择最左侧的企业服务appStore选项,进入应用控制台

企业App Store开发指南 - 图14

  • 在APP列表中,查看已经添加的应用信息,如图所示,添加APP按钮来添加新的应用APP

企业App Store开发指南 - 图15

平台应用

  • 默认显示 这个选项对应的是APP上首页默认显示的应用,选择就会在APP上首页显示,只在添加应用的列表中显示。
  • 所属分类 选定APP所属分类,后期可以根据分类查看APP列表。
  • 显示序号 创建应用之后,会根据这个字段排序,从小到大,依次排序。PS:平台应用 原生应用 H5应用 共用这一个字段。
  • APP版本号 规定平台应用的应用版本号。
  • 应用文件 在APICloud平台创建的Native应用,将Widget包压缩为zip格式,上传。

企业App Store开发指南 - 图16

原生应用

特有字段说明,共有字段同上

  • android 包名填Android原生应用的应用包名,APP下载地址,应用大小。
  • iPhone 包名填iOS原生应用包名,下载地址填写苹果商店的地址或者plist下载地址,PS:plist地址需要企业证书认证才可使用。
  • iPad iOS对iPad适配的版本,填写的信息同iPhone

企业App Store开发指南 - 图17

H5应用

特有字段说明,共有字段同上

  • webapp地址 填写webapp链接地址,注意要以http://https://开头才可使用。

移动APP

IMG_0527

  • 首页展示在后台中添加的默认显示的应用,上方banner图可以自定义
  • 通过选择应用来下载、安装、启动的操作

IMG_0529

  • 首页左上角点击添加进入此页面,列表分为三栏
  • 全部中展示所有的应用列表
  • 添加中展示的是后台添加的所有应用的列表,除去在首页已经展示的应用
  • 更新中展示的是本地已经安装的,并且需要更新的APP列表

IMG_0528

  • 在首页点击右上角的编辑进入此页面
  • 在这个页面可以通过长按拖动图标,来对应用展示排序,点击图标右上方的-来删除应用,返回时会保存修改,并且首页会根据修改后的顺序加载显示

接口文档

获取应用信息

  1. url: http://qyservice.apicloud.com/mcm/api/testapp?filter={params}
  2. method: GET
  3. headers: {
  4. "X-APICloud-AppId": "A6940041047405",
  5. "X-APICloud-AppKey": "b8319d480e09bef85ac5b579a12afd6b8ee7b66e.1496200248939"
  6. }
  7. params: {
  8. "fields": {
  9. "createdAt": false,
  10. "updatedAt": false,
  11. "push(uz*R*id)": false
  12. },
  13. "where": {
  14. "or": [
  15. {
  16. "widgetUrl": {
  17. "ne": ""
  18. }
  19. },
  20. {
  21. "webaddress": {
  22. "ne": ""
  23. }
  24. },
  25. {
  26. "androidUrl": {
  27. "ne": ""
  28. }
  29. }
  30. ],
  31. "and": [
  32. {
  33. "isDefault": "1"
  34. }
  35. ]
  36. },
  37. "order": "orderNum ASC",
  38. "skip": 0
  39. }

返回数据:成功后,返回json格式数据,包含应用信息

  1. [{
  2. "id": "592659ff7d46357b3a856eb9",
  3. "name": "微信",
  4. "version": "",
  5. "appPic": "http://qyservice.apicloud.com:5000/A6940041047405/abcc15ca436af1f43b1f7b9b179a8deb.png",
  6. "widgetId": null,
  7. "isDefault": "0",
  8. "isfolder": "0",
  9. "isNative": "1",
  10. "type": "无分类",
  11. "androidpkg": "com.tencent.mm",
  12. "androidUrl": "http://gdown.baidu.com/data/wisegame/2d5bf81de4e0ca42/weixin_1041.apk",
  13. "androidSize": "50",
  14. "iphonepkg": "com.tencent.xin",
  15. "iphoneUrl": "https://itunes.apple.com/cn/app/微信/id414478124?mt=8",
  16. "iphoneSize": "50",
  17. "ipadpkg": "com.tencent.xin",
  18. "ipadUrl": "https://itunes.apple.com/cn/app/微信/id414478124?mt=8",
  19. "ipadSize": "50",
  20. "widgetUrl": null,
  21. "webaddress": "",
  22. "loadnum": null,
  23. "orderNum": 1
  24. }, {
  25. "id": "59265aff7d46357b3a856ebb",
  26. "name": "QQHD(iOS)",
  27. "version": "",
  28. "appPic": "http://qyservice.apicloud.com:5000/A6940041047405/5b81b2bb92d907b7c2372d286133dac0.png",
  29. "widgetId": null,
  30. "isDefault": "0",
  31. "isfolder": "0",
  32. "isNative": "1",
  33. "type": "无分类",
  34. "androidpkg": "com.tencent.mobileqq",
  35. "androidUrl": "http://gdown.baidu.com/data/wisegame/0852f6d39ee2e213/QQ_676.apk",
  36. "androidSize": "70",
  37. "iphonepkg": "com.tencent.mipadqq",
  38. "iphoneUrl": "https://itunes.apple.com/cn/app/qq-hd/id453718989?mt=8",
  39. "iphoneSize": "70",
  40. "ipadpkg": "com.tencent.mipadqq",
  41. "ipadUrl": "https://itunes.apple.com/cn/app/qq-hd/id453718989?mt=8",
  42. "ipadSize": "100",
  43. "widgetUrl": null,
  44. "webaddress": "",
  45. "loadnum": null,
  46. "orderNum": 2
  47. }, {
  48. "id": "592519757d46357b3a856e91",
  49. "name": "400",
  50. "version": "4",
  51. "appPic": "http://qyservice.apicloud.com:5000/A6940041047405/8af2838498280a5db0ab42cee04954ca.jpg",
  52. "widgetId": "4",
  53. "isDefault": "1",
  54. "isfolder": "0",
  55. "isNative": "0",
  56. "type": "系统",
  57. "androidpkg": "",
  58. "androidUrl": "",
  59. "androidSize": "",
  60. "iphonepkg": "",
  61. "iphoneUrl": "",
  62. "iphoneSize": "",
  63. "ipadpkg": "",
  64. "ipadUrl": "",
  65. "ipadSize": "",
  66. "widgetUrl": "http://qyservice.apicloud.com:5000/A6940041047405/3adae3159572dd7be2b85153701843c3.zip",
  67. "webaddress": "",
  68. "loadnum": null,
  69. "orderNum": 3
  70. }, {
  71. "id": "592518147d46357b3a856e8e",
  72. "name": "360",
  73. "version": "3",
  74. "appPic": "http://qyservice.apicloud.com:5000/A6940041047405/9a4a3eb02da008fe43fde689e3f68949.jpg",
  75. "widgetId": "3",
  76. "isDefault": "1",
  77. "isfolder": "0",
  78. "isNative": "0",
  79. "type": "系统",
  80. "androidpkg": "",
  81. "androidUrl": "",
  82. "androidSize": "",
  83. "iphonepkg": "",
  84. "iphoneUrl": "",
  85. "iphoneSize": "",
  86. "ipadpkg": "",
  87. "ipadUrl": "",
  88. "ipadSize": "",
  89. "widgetUrl": "http://qyservice.apicloud.com:5000/A6940041047405/3adae3159572dd7be2b85153701843c3.zip",
  90. "webaddress": "",
  91. "loadnum": null,
  92. "orderNum": 4
  93. }]

获取更新应用列表

  1. url: http://qyservice.apicloud.com/mcm/api/testapp?filter={params}
  2. method: GET
  3. headers: {
  4. "X-APICloud-AppId": "A6940041047405",
  5. "X-APICloud-AppKey": "b8319d480e09bef85ac5b579a12afd6b8ee7b66e.1496200248939"
  6. }
  7. params:{
  8. "fields": {
  9. "createdAt": false,
  10. "updatedAt": false,
  11. "push(uz*R*id)": false
  12. },
  13. "where": {
  14. "or": [
  15. {
  16. "id": "592519757d46357b3a856e91",
  17. "version": {
  18. "gt": "4"
  19. }
  20. },
  21. {
  22. "id": "592518147d46357b3a856e8e",
  23. "version": {
  24. "gt": "3"
  25. }
  26. },
  27. {
  28. "id": "59265b377d46357b3a856ebd",
  29. "version": {
  30. "gt": ""
  31. }
  32. },
  33. {
  34. "id": "592517a77d46357b3a856e8b",
  35. "version": {
  36. "gt": "2"
  37. }
  38. },
  39. {
  40. "id": "592520297d46357b3a856e96",
  41. "version": {
  42. "gt": "5"
  43. }
  44. },
  45. {
  46. "id": "59256cba7d46357b3a856ea4",
  47. "version": {
  48. "gt": "1.0"
  49. }
  50. },
  51. {
  52. "id": "59258d3b7d46357b3a856eab",
  53. "version": {
  54. "gt": "1"
  55. }
  56. },
  57. {
  58. "id": "592642747d46357b3a856eb7",
  59. "version": {
  60. "gt": ""
  61. }
  62. },
  63. {
  64. "id": "59268f347d46357b3a856ec1",
  65. "version": {
  66. "gt": ""
  67. }
  68. }
  69. ]
  70. }
  71. }

返回数据:成功后,返回json格式数据,包含需要更新的应用信息

  1. [{
  2. "id": "592659ff7d46357b3a856eb9",
  3. "name": "微信",
  4. "version": "",
  5. "appPic": "http://qyservice.apicloud.com:5000/A6940041047405/abcc15ca436af1f43b1f7b9b179a8deb.png",
  6. "widgetId": null,
  7. "isDefault": "0",
  8. "isfolder": "0",
  9. "isNative": "1",
  10. "type": "无分类",
  11. "androidpkg": "com.tencent.mm",
  12. "androidUrl": "http://gdown.baidu.com/data/wisegame/2d5bf81de4e0ca42/weixin_1041.apk",
  13. "androidSize": "50",
  14. "iphonepkg": "com.tencent.xin",
  15. "iphoneUrl": "https://itunes.apple.com/cn/app/微信/id414478124?mt=8",
  16. "iphoneSize": "50",
  17. "ipadpkg": "com.tencent.xin",
  18. "ipadUrl": "https://itunes.apple.com/cn/app/微信/id414478124?mt=8",
  19. "ipadSize": "50",
  20. "widgetUrl": null,
  21. "webaddress": "",
  22. "loadnum": null,
  23. "orderNum": 1
  24. }, {
  25. "id": "59265aff7d46357b3a856ebb",
  26. "name": "QQHD(iOS)",
  27. "version": "",
  28. "appPic": "http://qyservice.apicloud.com:5000/A6940041047405/5b81b2bb92d907b7c2372d286133dac0.png",
  29. "widgetId": null,
  30. "isDefault": "0",
  31. "isfolder": "0",
  32. "isNative": "1",
  33. "type": "无分类",
  34. "androidpkg": "com.tencent.mobileqq",
  35. "androidUrl": "http://gdown.baidu.com/data/wisegame/0852f6d39ee2e213/QQ_676.apk",
  36. "androidSize": "70",
  37. "iphonepkg": "com.tencent.mipadqq",
  38. "iphoneUrl": "https://itunes.apple.com/cn/app/qq-hd/id453718989?mt=8",
  39. "iphoneSize": "70",
  40. "ipadpkg": "com.tencent.mipadqq",
  41. "ipadUrl": "https://itunes.apple.com/cn/app/qq-hd/id453718989?mt=8",
  42. "ipadSize": "100",
  43. "widgetUrl": null,
  44. "webaddress": "",
  45. "loadnum": null,
  46. "orderNum": 2
  47. }, {
  48. "id": "592519757d46357b3a856e91",
  49. "name": "400",
  50. "version": "4",
  51. "appPic": "http://qyservice.apicloud.com:5000/A6940041047405/8af2838498280a5db0ab42cee04954ca.jpg",
  52. "widgetId": "4",
  53. "isDefault": "1",
  54. "isfolder": "0",
  55. "isNative": "0",
  56. "type": "系统",
  57. "androidpkg": "",
  58. "androidUrl": "",
  59. "androidSize": "",
  60. "iphonepkg": "",
  61. "iphoneUrl": "",
  62. "iphoneSize": "",
  63. "ipadpkg": "",
  64. "ipadUrl": "",
  65. "ipadSize": "",
  66. "widgetUrl": "http://qyservice.apicloud.com:5000/A6940041047405/3adae3159572dd7be2b85153701843c3.zip",
  67. "webaddress": "",
  68. "loadnum": null,
  69. "orderNum": 3
  70. }, {
  71. "id": "592518147d46357b3a856e8e",
  72. "name": "360",
  73. "version": "3",
  74. "appPic": "http://qyservice.apicloud.com:5000/A6940041047405/9a4a3eb02da008fe43fde689e3f68949.jpg",
  75. "widgetId": "3",
  76. "isDefault": "1",
  77. "isfolder": "0",
  78. "isNative": "0",
  79. "type": "系统",
  80. "androidpkg": "",
  81. "androidUrl": "",
  82. "androidSize": "",
  83. "iphonepkg": "",
  84. "iphoneUrl": "",
  85. "iphoneSize": "",
  86. "ipadpkg": "",
  87. "ipadUrl": "",
  88. "ipadSize": "",
  89. "widgetUrl": "http://qyservice.apicloud.com:5000/A6940041047405/3adae3159572dd7be2b85153701843c3.zip",
  90. "webaddress": "",
  91. "loadnum": null,
  92. "orderNum": 4
  93. }]