相信越来越多小伙伴发现不少超级APP的页面都采用小程序开发了。例如支付宝客户端,首页有一个小程序中心的入口,支付宝上很多页面都是小程序了。
第一次打开的一个新功能时,会出现一个短暂的loading过程。小程序右上角有查看详情和关闭的按钮,例如中国体育小程序。
那么为什么越多越多大厂的app采用了小程序容器化开发呢?博主将在本博客简要说明小程序容器化的趋势、优点,以及如何基于uni-app在iOS端开发自己的小程序。本文提纲如下:
一. 小程序趋势回到前言提到的问题——那么为什么越多越多大厂的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 开发版。
1)在主工程下面创建一个group: Uniapp,然后把SDK的Core下面的Headers、Resources、Libs这三个文件夹拷贝到Uniapp group。
2)右键Uniapp,add files到工程。
3)在Build phases中添加以下 lib:
4)Build Settings -> Other Linker Flags,添加-ObjC。
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 *)options {
// 通过 url scheme 唤起 App
[DCUniMPSDKEngine application:app openURL:url options:options];
return YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> * _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下面。
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 ()
@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了。
四. 编写并运行自己的小程序 4.1 编写小程序 打开HBuilderX,文件->新建->项目,项目信息如下:创建好目录之后,我们来看看工程的代码结构。
1)pages:页面布局写在这下面;
2)manifest.json:小程序的配置文件,选择性配置一些信息,如下图所示。前提:你需要到dcloud开发者中心官网注册一个账号,注册地址。在后台创建一个应用,如下图所示。
3)pages.json:页面路由配置及全局样式。例如:
4.2 运行小程序{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/about/about",
"style": {
"navigationBarTitleText": "关于"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "关于",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}
点击HBuilderX左上角的运行按钮,选择编译设备,例如chrome浏览器。
4.3 打包小程序 代码运行没有问题,就可以打包了。打开HBuilderX,点击左上角的发行按钮,生成wgt包 。 4.4 集成小程序将生成的wgt包拷贝到Uniapp/apps下。
4.5 运行小程序在调起小程序的入口,将名字改为我们的小程序名称即可。
#define k_AppId @"__UNI__C0C0F45" // 小程序名称
在Xcode中代码,看到我们的小程序被加载进来了。
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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)