前言

相信越来越多小伙伴发现不少超级APP的页面都采用小程序开发了。例如支付宝客户端,首页有一个小程序中心的入口,支付宝上很多页面都是小程序了。

图1 支付宝小程序入口

第一次打开的一个新功能时,会出现一个短暂的loading过程。小程序右上角有查看详情和关闭的按钮,例如中国体育小程序。

图2 支付宝“中国体育”小程序截图

那么为什么越多越多大厂的app采用了小程序容器化开发呢?博主将在本博客简要说明小程序容器化的趋势、优点,以及如何基于uni-app在iOS端开发自己的小程序。本文提纲如下:

图3 博客提纲

一. 小程序趋势

回到前言提到的问题——那么为什么越多越多大厂的app采用了小程序容器化开发呢?这是大前端发展的趋势。博主认为主要有以下几个原因:

1.1多端一致性

Android/iOS双端一致性,一直是移动端致力解决的问题。一些热门产品,通常还有PC端、公众号、H5页面等门户产品。在博主的项目中就要求四端:Android、iOS、PC端、H5提供交易功能。同样的功能,实现了四遍,测试四遍。跨平台技术是保证多端一致性的重要手段。

1.2 动态化

动态化,不仅可以满足千人千面的需求,通过后台配置模版实现页面动态化,不需要客户端coding大量的代码;还可以减少app发版的次数和降低上架时间,日渐严格的苹果市场审核机制让开发者意识到动态化的重要性,尤其是出现BUG时需要紧急发版。对于强监管业务,app也是需要具备随时下架某个功能的能力。

1.3 低代码,提升开发效率

low- code——低代码,这在业界已经流行好多年了。low- code可以大幅度减少代码量,通过模版代码就能快速满足功能开发或支持第三方接入的需求。同一套模版代码还可以复用到各个端,开发量减少了,测试时间也减少了,开发效率得到极大的提升。

1.4 安装包控制

大厂的超级app通常包罗很多功能,还是拿支付宝来说,支付宝上面的多功多得数不清。如果用纯原生的代码来实现,想想app安装包会大到什么程序?这对app推广非常不利的。所以,控制 app安装包大小,web或小程序化就变成非常重要了 。

二. 为什么选择uni-app

市面上能满足开发并集成自己的小程序的技术还挺多的,例如AntBuilder、FinClip、uni-app等。没有最好的技术,只有适合自己团队和业务场景的技术才是最佳的技术,所以博主不会展开讨论它们的区别,而是从自身的角度谈谈为什么选择uni-app。

2.1 技术栈

uni-app技术栈还是基于vue.js + weex的,比较符合我们团队的技术储备的情况,学习成本非常低,团队能快速上手。

2.2 uni-app的特点

uni-app从2018年发布第一个版本以来,一直保持快速迭代的趋势[1] 。官方github上star数量为:32.7K[2]。uni-app在开发者数量、案例、跨端抹平度、扩展灵活性、性能体验、周边生态、学习成本、开发成本等关键指标上拥有更强的优势[3]。

1)开发者/案例数量更多:数百万应用、uni统计月活12亿、70+微信/qq群、更高的百度指数,跨端完善度高。

2)平台能力不受限:在跨端的同时,通过条件编译+平台特有API调用,可以优雅的为某平台写个性化代码,调用专有能力而不影响其他平台。支持原生代码混写和原生sdk集成。

3)性能体验优秀:加载新页面速度更快、自动diff更新数据。App端支持原生渲染,可支撑更流畅的用户体验。小程序端的性能优于市场其他框架。

4)周边生态丰富:插件市场数千款插件。支持NPM、支持小程序组件和SDK。微信生态的各种sdk可直接用于跨平台App。

5)学习成本低:基于通用的前端技术栈,采用vue语法+微信小程序api,无额外学习成本。

6)开发成本低: HBuilderX是高效开发神器,熟练掌握后研发效率至少翻倍。

三. 集成uni-app

3.1 安装环境

环境安装参考官网[4],uni-app支持通过可视化界面、vue-cli命令行两种方式快速创建项目。推荐大家使用可视化界面。可视化的方式比较简单,HBuilderX内置相关环境,开箱即用,无需配置nodejs。

开始之前,开发者需先下载安装HBuilderX IDE工具:

  • 安装HBuilderX:官方IDE下载地址

HBuilderX是通用的前端开发工具,但为uni-app做了特别强化。分两个版本:1)App开发版,可开箱即用;2)标准版,在运行或发行uni-app时,会提示安装uni-app插件,插件下载完成后方可使用。推荐下载App开发版,博主安装的MacOS 开发版。

图3.1 HBuilderX安装包
  • 下载SDK:从官网下载最新版本的SDK[5], 下载链接。如下图所示:

图3.2 下载SDK

3.2 集成 SDK

  • 添加依赖

1)在主工程下面创建一个group: Uniapp,然后把SDK的Core下面的Headers、Resources、Libs这三个文件夹拷贝到Uniapp group。

2)右键Uniapp,add files到工程。

图3.1 添加SDK的Core文件到工程

图3.2 添加文件

3)在Build phases中添加以下 lib:

图3.3 添加依赖库

4)Build Settings -> Other Linker Flags,添加-ObjC。

图3.4 Build Settings添加Other Linker Flags
  • SDK初始化:

1)在AppDelegate中添加uni-app初始化代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];self.window.rootViewController = [[UniappViewController alloc]init];self.window.backgroundColor = [UIColor whiteColor];[self.window makeKeyAndVisible];[self initUniappSDK:launchOptions];return YES;
}-(void) initUniappSDK:(NSDictionary *)launchOptions {// 配置参数NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:launchOptions];// 设置 debug YES 会在控制台输出 js log,默认不输出 log,注:需要引入 liblibLog.a 库[options setObject:[NSNumber numberWithBool:YES] forKey:@"debug"];// 初始化引擎[DCUniMPSDKEngine initSDKEnvironmentWithLaunchOptions:options];
}

2)监听App 生命周期方法

#pragma mark - App 生命周期方法
- (void)applicationDidBecomeActive:(UIApplication *)application {[DCUniMPSDKEngine applicationDidBecomeActive:application];
}- (void)applicationWillResignActive:(UIApplication *)application {[DCUniMPSDKEngine applicationWillResignActive:application];
}- (void)applicationDidEnterBackground:(UIApplication *)application {[DCUniMPSDKEngine applicationDidEnterBackground:application];
}- (void)applicationWillEnterForeground:(UIApplication *)application {[DCUniMPSDKEngine applicationWillEnterForeground:application];
}- (void)applicationWillTerminate:(UIApplication *)application {[DCUniMPSDKEngine destory];
}

3)可选,非必须:如果用到以下AppDelegate的回调,则实现对应的方法。没用到则不需要实现。

#pragma mark - 如果需要使用 URL Scheme 或 通用链接相关功能,请实现以下方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {// 通过 url scheme 唤起 App[DCUniMPSDKEngine application:app openURL:url options:options];return YES;
}- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {// 通过通用链接唤起 App[DCUniMPSDKEngine application:application continueUserActivity:userActivity];return YES;
}#pragma mark - 如需使用远程推送相关功能,请实现以下方法
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {// 远程通知注册成功,收到 deviceToken 调用sdk方法,传入 deviceToken[DCUniMPSDKEngine application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {// 远程通知注册失败[DCUniMPSDKEngine application:application didFailToRegisterForRemoteNotificationsWithError:error];
}- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {// 收到远程推送消息[DCUniMPSDKEngine application:application didReceiveRemoteNotification:userInfo];completionHandler(UIBackgroundFetchResultNewData);
}#pragma mark - 如需使用本地推送通知功能,请实现以下方法
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {// 收到本地推送消息[DCUniMPSDKEngine application:application didReceiveLocalNotification:notification];
}
  • 加载测试小程序:

1)在Uniapp下创建一个group: apps,sdk解压缩包HelloUniMPDemo/UniMP/Apps拷贝一个wgt到apps下面。

图3.5 添加app group及拷贝wgt测试包

2)添加加载测试小程序逻辑。

/// 启动小程序
- (void)openUniMP {// 获取配置信息DCUniMPConfiguration *configuration = [self getUniMPConfiguration];// 配置启动小程序时传递的参数(参数可以在小程序中通过 plus.runtime.arguments 获取此参数)configuration.arguments = @{ @"arguments":@"Hello uni microprogram" };__weak __typeof(self)weakSelf = self;// 打开小程序[DCUniMPSDKEngine openUniMP:k_AppId configuration:configuration completed:^(DCUniMPInstance * _Nullable uniMPInstance, NSError * _Nullable error) {if (uniMPInstance) {weakSelf.uniMPInstance = uniMPInstance;} else {NSLog(@"打开小程序出错:%@",error);}}];
}

3) 实现DCUniMPSDKEngineDelegate的方法。

完整的代码如下:

#import "UniappViewController.h"
#import "DCUniMP.h"#define k_AppId @"__UNI__11E9B73" // 小程序名称@interface UniappViewController ()<DCUniMPSDKEngineDelegate>@property (nonatomic, weak) DCUniMPInstance *uniMPInstance; // 声明DCUniMPInstance@end@implementation UniappViewController- (void)viewDidLoad {[super viewDidLoad];UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTouchUpInside:)];UILabel *lable = [[UILabel alloc] initWithFrame:CGRectMake(100,100, 100,100)];lable.text = @"打开小程序";lable.textColor = [UIColor redColor];lable.userInteractionEnabled = YES;[lable addGestureRecognizer:tap];[self.view addSubview:lable];[self checkUniMPResource];
}-(void) labelTouchUpInside:(UITapGestureRecognizer *)recognizer{UILabel *label=(UILabel*)recognizer.view;NSLog(@"%@被点击了",label.text);[self openUniMP];
}
/// 小程序配置信息
- (DCUniMPConfiguration *)getUniMPConfiguration {/// 初始化小程序的配置信息DCUniMPConfiguration *configuration = [[DCUniMPConfiguration alloc] init];// 开启后台运行configuration.enableBackground = YES;// 设置 push 打开方式configuration.openMode = DCUniMPOpenModePush;// 启用侧滑手势关闭小程序configuration.enableGestureClose = YES;return configuration;
}/// 检查运行目录是否存在应用资源,不存在将应用资源部署到运行目录
- (void)checkUniMPResource {if (![DCUniMPSDKEngine isExistsApp:k_AppId]) {// 读取导入到工程中的wgt应用资源NSString *appResourcePath = [[NSBundle mainBundle] pathForResource:k_AppId ofType:@"wgt"];if (!appResourcePath) {NSLog(@"资源路径不正确,请检查");return;}// 将应用资源部署到运行路径中if ([DCUniMPSDKEngine releaseAppResourceToRunPathWithAppid:k_AppId resourceFilePath:appResourcePath]) {NSLog(@"小程序 %@ 应用资源文件部署成功",k_AppId);}// 设置 delegate[DCUniMPSDKEngine setDelegate:self];}
}/// 启动小程序
- (void)openUniMP {// 获取配置信息DCUniMPConfiguration *configuration = [self getUniMPConfiguration];// 配置启动小程序时传递的参数(参数可以在小程序中通过 plus.runtime.arguments 获取此参数)configuration.arguments = @{ @"arguments":@"Hello uni microprogram" };__weak __typeof(self)weakSelf = self;// 打开小程序[DCUniMPSDKEngine openUniMP:k_AppId configuration:configuration completed:^(DCUniMPInstance * _Nullable uniMPInstance, NSError * _Nullable error) {if (uniMPInstance) {weakSelf.uniMPInstance = uniMPInstance;} else {NSLog(@"打开小程序出错:%@",error);}}];
}#pragma mark - DCUniMPSDKEngineDelegate
/// DCUniMPMenuActionSheetItem 点击触发回调方法
- (void)defaultMenuItemClicked:(NSString *)identifier {NSLog(@"标识为 %@ 的 item 被点击了", identifier);// 将小程序隐藏到后台if ([identifier isEqualToString:@"enterBackground"]) {__weak __typeof(self)weakSelf = self;[self.uniMPInstance hideWithCompletion:^(BOOL success, NSError * _Nullable error) {if (success) {NSLog(@"小程序 %@ 进入后台",weakSelf.uniMPInstance.appid);} else {NSLog(@"hide 小程序出错:%@",error);}}];}// 关闭小程序else if ([identifier isEqualToString:@"closeUniMP"]) {[self.uniMPInstance closeWithCompletion:^(BOOL success, NSError * _Nullable error) {if (success) {NSLog(@"小程序 closed");} else {NSLog(@"close 小程序出错:%@",error);}}];}// 向小程序发送消息else if ([identifier isEqualToString:@"SendUniMPEvent"]) {[DCUniMPSDKEngine sendUniMPEvent:@"NativeEvent" data:@{@"msg":@"native message"}];}
}/// 返回打开小程序时的自定义闪屏视图
- (UIView *)splashViewForApp:(NSString *)appid {UIView *splashView = [[[NSBundle mainBundle] loadNibNamed:@"SplashView" owner:self options:nil] lastObject];return splashView;
}/// 小程序关闭回调方法
- (void)uniMPOnClose:(NSString *)appid {NSLog(@"小程序 %@ 被关闭了",appid);self.uniMPInstance = nil;
}/// 监听小程序发送的事件回调方法
/// @param event 事件
/// @param data 参数
/// @param callback 回调方法,回传数据给小程序
- (void)onUniMPEventReceive:(NSString *)event data:(id)data callback:(DCUniMPKeepAliveCallback)callback {NSLog(@"Receive UniMP event: %@ data: %@",event,data);// 回传数据给小程序// DCUniMPKeepAliveCallback 用法请查看定义说明if (callback) {callback(@"native callback message",NO);}
}@end

在Xcode中运行代码,看到测试小程序被正常调起了,说明uni-app集成OK了。

图3.6 测试小程序加载图

四. 编写并运行自己的小程序

4.1 编写小程序

  • 打开HBuilderX,文件->新建->项目,项目信息如下:

图4.1 HBuilderX创建项目界面

创建好目录之后,我们来看看工程的代码结构。

图4.2 工程的代码结构

1)pages:页面布局写在这下面;

2)manifest.json:小程序的配置文件,选择性配置一些信息,如下图所示。前提:你需要到dcloud开发者中心官网注册一个账号,注册地址。在后台创建一个应用,如下图所示。

图3.7 dcloud开发者中心后台应用列表截图

图4.3 manifest.json配置图

3)pages.json:页面路由配置及全局样式。例如:

{
    "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
        {
            "path": "pages/about/about",
            "style": {
                "navigationBarTitleText": "关于"
            }
        }
    ],
    "globalStyle": {
        "navigationBarTextStyle": "black",
        "navigationBarTitleText": "关于",
        "navigationBarBackgroundColor": "#F8F8F8",
        "backgroundColor": "#F8F8F8"
    }
}

4.2 运行小程序

点击HBuilderX左上角的运行按钮,选择编译设备,例如chrome浏览器。

图4.4 HBuilderX编译选择界面

4.3 打包小程序

  • 代码运行没有问题,就可以打包了。打开HBuilderX,点击左上角的发行按钮,生成wgt包 。

图4.5 HBuilderX打包界面

4.4 集成小程序

将生成的wgt包拷贝到Uniapp/apps下。

图4.6 将小程序包拷贝到apps

4.5 运行小程序

在调起小程序的入口,将名字改为我们的小程序名称即可。

#define k_AppId @"__UNI__C0C0F45" // 小程序名称

在Xcode中代码,看到我们的小程序被加载进来了。

图4.7 小程序加载页面

5.Demo代码

demo代码上传到github,如果需要,请小伙伴自行下载。下载地址。

6.参考链接

[1] https://uniapp.dcloud.io/release?id=_014520180728-alpha

[2] https://github.com/dcloudio/uni-app

[3] https://uniapp.dcloud.io/README

[4] https://uniapp.dcloud.io/quickstart-hx

[5]https://nativesupport.dcloud.net.cn/UniMPDocs/SDKDownload/ios

小程序容器化:基于uni-app的iOS小程序开发相关推荐

  1. ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(一)

    上个月15日,上海MVP做了一次线下的技术分享活动,我分享的主题是<快速构建容器化的ASP.NET Core应用程序>,有关这次活动的简报,可以参考这里.另外,我的主题分享的PPT也可以点 ...

  2. ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(二)

    在上文中我介绍了ASP.NET Core应用程序容器化时需要注意的几个问题,并给出了一个案例应用程序:tasklist.今天接着上文的内容,继续了解一下如何使用Azure DevOps进行ASP.NE ...

  3. ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(三

    在上文ASP.NET Core应用程序容器化.持续集成与Kubernetes集群部署(二)中,我介绍了如何使用Azure DevOps为ASP.NET Core应用程序案例:tasklist搭建持续集 ...

  4. 使用Docker和Azure Kubernetes服务将ASP.NET核心应用程序容器化

    目录 介绍 应用概述 容器化ASP.NET核心应用程序 部署在本地Kubernetes集群上 Docker镜像和Azure容器注册表(ACR) 部署Azure Kubernetes服务(AKS)群集 ...

  5. 跑鸭”微信小程序-一款基于校园跑步的社交小程序

    跑鸭:这是我的毕业设计,"跑鸭"微信小程序-一款基于校园跑步的社交小程序(实时里程配速.运动路径.整公里提醒.周榜月榜.打卡分享.热门推荐.线上活动.勋章墙.隐私设置),技术栈:V ...

  6. netcore更新dll要停止_使 .NET Core 应用程序容器化

    在本教程中,你将了解如何使用 Docker 容器化 .NET Core 应用. 容器具有很多特性和优点,如具有不可变的基础结构.提供可移植的体系结构和实现可伸缩性. 此影像可用于为本地开发环境.私有云 ...

  7. 大数据容器化-基于Kubernetes(k8s)构建spark运行环境

    Apache Spark 在大数据处理与分析领域,Apache Spark无疑占据着重要地位.它的特点是基于内存计算,支持各类资源管理平台,其中以YARN最为常见,同时又与Hadoop平台集成,在集群 ...

  8. JAVA小程序:一个基于MVC框架的贪吃蛇程序

    学习JAVA也有一段时间了,之前看了翁恺老师的视频,跟着做了一个细胞自动机,粗浅地了解了一点MVC框架的知识,感觉获益匪浅.但是细胞自动机毕竟是跟着视频完成的,有很大程度上都是参考了视频里的代码,没有 ...

  9. c语言程序设计项目化教程第二版130,C语言程序设计项目化教程pdf(附答案)电子版...

    通过了C语言入门的学习,很多朋友已经掌握了一定的C语言知识,那么想要进一步深入了解,就可以开始学习这本C语言程序设计项目化教程了,让你深入了解项目开发,感兴趣的朋友快来下载使用吧. C语言介绍 C语言 ...

最新文章

  1. 怎么去大蒜味(一定要看拉) - 生活至上,美容至尚!
  2. Manacher 求最长回文子串算法
  3. 【XAudio2】8.怎么播放音效
  4. tomcat下只有.class文件 没有java文件_解决tomcat发布工程后,WEB-INF/classes下文件不编译的问题...
  5. 数学建模 TSP(旅行商问题) Lingo求解
  6. 爬楼梯与路径类题目记忆化递归与动态规划双解法(Leetcode题解-Python语言)
  7. pat 乙级 1011 A+B 和 C(C++)
  8. superset0.34源码级别汉化
  9. 通过原码、反码、补码彻底搞清左移、右移、无符号右移
  10. 研制埃博拉疫苗与科学家的奇思秒想
  11. 关于python最大递归深度 - 998
  12. Java毕设项目宠物管理系统计算机(附源码+系统+数据库+LW)
  13. MTK 6589暗码切换开机LOGO(不适应NAND 的FLASH)
  14. iOS 强制横屏的方法
  15. python epub 精品_如何利用Python打包HTML页面为epub?
  16. 技术Leader的30条军规
  17. 冒泡排序 (Java)
  18. surfer9 与Arcgis9.3 完美生成等值线和等值面方法
  19. IDC机房工作的简单流程
  20. Dell戴尔灵越Inspiron 15 3511原装出厂系统恢复原厂系统

热门文章

  1. 固定行表头,固定列的html
  2. 静态路由配置--思科实验
  3. lisp插件圆弧转折线_AutoCAD中圆弧折线化方法与实现
  4. 关键字const是什么含意
  5. python读取txt文件,写入txt文件
  6. 二分查找法时间复杂度计算
  7. 需求沟通的灵魂拷问:人与人之间的信任呢?
  8. python+selenium浏览器驱动(chrome,Firefox,IE)下载与封装
  9. 如何在三至六个月写一篇机器学习领域的论文?
  10. 小型企业局域网免费上网行为管理方案