开发者学堂课程【mPaaS 小程序开发实战 - 教你如何独立运行小程序 :iOS 端自定义开发(二)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/741/detail/13133
iOS 端自定义开发(二)
二、iOS 小程序自定义启动加载页
当启动小程序时,如小程序未下载到设备,小程序容器会启动加载页〈如下图)提示用户等待,待小程序安装到设备上,加载页关闭并跳转至小程序。
当小程序启动的时候,如果小程序没有下载到手机上,小程序容器在中间会加载一个的启动过渡页,提示我们进行等待。过渡页样式也是支持自定义的。
实现自定义加载页
对于 iOS 小程序,mPaaS 支持开发者自定义加载页内容,您可按照以下步骤进行配置:
继承 APBaseLoadingView 的子类,自定义加载页 View 子类,您可以在子类中修改页面 view 的样式。
首先创建一个子类,子类必须继承 APBaseLoadingView 基类,子类里面可以修改页面的 icon、title 和pageControl,
代码实例如下:
1.@interface MPBaseLoadingView : APBaseLoadingView
2.
3.@end
4.
5.
@implementation MPBaseLoadingView
6.
7.-(instancetype)init
8.{
9.self = [super init];
10.if (self){
11.self.backgroundColor = [UIColor grayColor];
12.self.titleLabel.backgroundColor = [UIColor redColor];
13.self.titleLabel.font = [UIFont boldSystemFontOfSize:8];
14.
15.self.iconlmageView.backgroundColor=[UIColor blueColor];
16.
17.self.pageControl.backgroundColor=[UIColor orangeColor];
18.
19.}
20.
21.
return self;
22.
}
23.
24.-(void)layoutSubviews
25.{
26.[super layoutSubviews];
27.//调整 view 的位置
28.
29.CGSize size = self. bounds.size;
30.CGRect frame = CGRectMake((size.width - 80)/2,0,80,80);
31.self.iconImageView.frame = frame;
32.
33.
frame = CGRectMake(15,CGRectGetMaxY(self.
iconImageView.frame)+ 6, size.width - 30, 22);
34. self.titleLabel.frame = frame;
35.
36.
frame = CGRectMake((size.width-40)/2,
CGRectGetMaxY(self.titleLabel.frame) +21,40, 20);
37.self.pageControl.frame = frame;
38.}
39.
40.@end
自定义一个view,继承 APBaseLoadingView,在他的 m 文件中,可以修改当前 view 的 titleLabel、图标以及PageControl 的颜色等等,还要在 LayoutSubviews 方法里调整 view 之间的位置。
在 DTFrameworkInterface 类的 category 中,重写 baseloadViewClass 方法,返回自定义的加载页 View 类名。
如果小程序加载的话,中间过度页用 view 的实现。
1.- (NSString ")baseloadViewClass
2.{
3. return @"MPBaseLoadingView";
4.}
在 DTFrameworkInterface+TinyAppDemo.m 里面实现 category,这里返回刚刚创建的子类的类名就可以了,这样就完成了自定义启动加载页的过程。
重新生成一下二维码,也就是发了一个全新的包,扫描这个全新的包的话,就会安装上刚刚自定义启动加载页的效果。
三、iOS 小程序自定义双向通道
如何自定义双向通道也就是如何让小程序与 native 之间进行交互,这里分为两种方式,一是小程序调用原生自定义API 进行小程序与 native 的通信。
小程序调用原生自定义 API
1.客户端自定义 API 并注册。
参考自定义 JSAPI、注册您的自定义 APl。
自定义 JSAPI
要从页面发起 Native 功能调用,例如显示一个 ActionShee 或显示联系人对话框,您需要扩展一个 JavaScript APl(JSAPI)。使用 JSAPI,可以让您在 H5 页面增加 Native 功能调用入口。通过实现自定义 JSAPI 类中的 handler 方法、以 Native 的形式实现特定功能。
如果要从页面发起 Native功能调用,显示一个 ActionShee 或调用 native 相机或短信的功能,肯定需要通过一个breff来让小程序与 native 进行通信的。
H5 容器组件提供以下能力:
丰富的内置 JSAPI,实现例如页面 push、pop、标题设置等功能。更多信息,请参见内置 JSAPl。
支持用户自定义 JSAPI 和插件功能,扩展业务需求。
关于此任务
自定义一个 JSAPI 可以有以下两种方式:
Plist 注册、代码注册
建议大家直接使用 Plist 注册,比较好对 JSAPI 进行管理。
命名规范:为与容器默认提供的插件命名保持一致,创建的 JSAPI 类命名以 XXJsApi4 开头,其中 XX为自定义的前缀。
前缀最好是个性化的配置,避免与容器默认的API发生冲突。
基类:所有 JSAPI 均继承自 PSDJsApiHandler。
实现基础方法:
在.m 文件中,需重写方法 -(void)handler:context:callback:。当在前端调用此 JSAPI 时,会转发到此方法。
该方法的参数含义如下:
参数名 |
含义 |
data |
H5页面调用此JSAPI时传入的参数 |
context |
当前H5页面的上下文,具体可参考PSDContext.h |
callback |
调用此JSAPI完成后的回调方法,以字典方式递调用结果到H5页面 |
方法有三个参数,data 是小程序页面调用 JSAPI 时传入的参数信息;context 是当前小程序页面的上下文,从这里可以回到当前页面所在的 viewcontrolle r以及 view;callback 是调用 API 完成之后的回调,以字典的方式传递调用结果到 H5 页面。
注册 JSAPI 在自定义的 Plist 文件中注册此 JSAPl
为统一管理自定义的JSAPI和Plugin,新建一个plsit 文件,您可以直接下载此模板文件DemoCustomPlugins.bundle.zip 并添加到工程中。
新建一个 plsit 文件,在 JSAPI 数组下新建一个 item,item 有两个属性,
SAPI 表示的是在小程序页面中调用的 JSAPI 接口名。
Name 是刚刚创建的 JSAPI 的类名。把类名调用到对应的 value 值就可以了。
名称 |
含义 |
jsApi |
在H5页面中调用的JSAPI接口,注意:为防止自定义的JSAPI与容器内置JSAPI相互影响导致不可用,请给自定义JSAPI名加上前缀予以区分 |
name |
创建的JSAPI的类名 |
同时需在初始化容器配置时,指定自定义的 Plist 文件的路径。
初始化 H5 容器,请参见 H5 容器快速开始。
在 beforeDidFinishLaunchingwithOptions 里面初始化容器的时候,不再是简单的 inite 操作,inite 传入一个参数,就是当前自定义 config 文件所在的路径,引入它传入到参数里面去,这样就完成了config 文件的注册了。
1. 小程序调用
1.
my.call('tinyToNative' , {
2. param1: 'p1aaa',
3. param2: 'p2bbb'
4.},(result)=> {
5.console.log(result);
6. my.showToast({
7. type: 'none ',
8. content: result.message,
9. duration: 3000,
10.});
11.)
通过 my.call 的方式调用 API,对应自定义 api 的页面,有一个点击按钮,点击按钮就会触发 tinytonative 的方法,通过 my.call 的方式调用 API,tinytonative 就是 Plist 文件里传入的 jsAPI 的名称,这里一定要对应上。看一下效果,点击 API,就会触发一个 native 的事件,重新运行一下,也可以断点查看传入的信息是否正确。
打开小程序,扫描二维码,切换到自定义 jsAPI 页面,点击按钮,可以看到已经断点住了,从小程序调用到 native 中来,data,参数,就是刚刚在小程序页面调用 JSAPI 时传入的参数信息,这样就能进行小程序与 native 之间的通信了。在方法里面,弹出一个窗口,手机端的效果如下:
总结下来就是首先自定义一个 JSAPI,在小程序里面通过 my.call 的方式来调用 API 进行通信。
原生应用向小程序发送自定义事件
在 native 发送一个事件,在小程序里面监听这个事件之后会拿到从 native 里面传出的一些参数或信息,
1.
my.on(nativeToTiny , (res) =>{
2. my.showToast({
3. type: 'none',
4. content: JSON.stringify(res),
5. duration: 3000,
6. success: ()=>{
7.
8.},
9. fail: ()=>{
10.
11.};
12. complete: ()=>{
13.
14.
}
15.
});
16.
})
在小程序注册监听事件,通过 my.on 的方式,在 app.js 里,在小程序启动的时候,通过 my.on 的方式来监听事件,事件名称叫 nativetotiny。
2、客户端发送事件。
获取当前小程序页面所在的 viewController ,调用 callHandler 方法发送事件。
[selfcallHandler:@nativeToTiny"data:e[@"key:@'value”"}responseCallback:^(id responseData){
2.
3.});
Handlername,小程序监听事件的名称,与监听的名称保持一致,native 向小程序发送的一些参数信息和 callback 的回调。
引用信息,点击关闭按钮的时候,不再是退出 app,而是让他发送出事件,重新运行一下工程,点击调试小程序,扫描二维码,点击关闭,出发事件,手机页面就会收到触发的事件。
其中 Data 就是刚刚传递的参数,这样就实现了从 native 到小程序发送消息的过程。