由于5+已经停止更新了,官方的虽然有跳转小程序的方法,但是试了几个离线包都不成功,安卓倒是一次成功了,附上hbuilder文档 调用微信小程序写得够简洁的,简直是垃圾!
注:以下文档大部分是踩坑记录,并无太多详细步骤,前人的教程已经很详细了。
一、申请Universal Link
附上简书的教程:iOS Universal Link(通用链接)
已经很详细了,就不再重复了
强调几点:
- 需要https的链接;
- Universal Link中的appid是teamid+bundle id;
- 配置的链接普通打开时404也没关系,safari中刷新一下能提示跳转信息就行。
- 苹果官方验证universal link 的地址是:链接,里面填的 https://domians/apple-app-site-association地址,不是universal link链接,这问题又浪费了我半个小时。最后一项提示如下是就是正常的了。
- 申请成功后需要重新生成profile,看看profile里有包含associated domains行了,xcode是自动生成profile的,如果没有,试试重启xcode,或者到资源库里面清空profile文件,再切换回来xcode就会重新生成profile了。有很多教程是让你去开发者中心看associated domains的是不是enable了,但我找不到那个页面,估计是旧版的。
二、申请微信应用
地址:微信开放平台
需要审核通过的应用才能用,修改Universal Link不需要重新申请审核。
三、接入微信sdk
官方文档:IOS接入指南
详细请看官方文档。
1.注册
在AppDelegate.m中的 didFinishLaunchingWithOptions方法中注册,这里的id是微信应用的id,不是小程序ID。自检函数发布时要注销掉。didFinishLaunchingWithOptions在离线包中已经存在,不要另外添加。
//在register之前打开log, 后续可以根据log排查问题
// [WXApi startLogByLevel:WXLogLevelDetail logBlock:^(NSString *log) {
// NSLog(@"WeChatSDK: %@", log);
// }];
NSLog(@"-----didFinishLaunchingWithOptions");
//向微信注册
BOOL res = [WXApi registerApp:@"wx********"
universalLink:@"https://********/ulink/"];
NSLog(@"-----registerApp:%@", res ? @"yes" : @"no");
// //调用自检函数
// [WXApi checkUniversalLinkReady:^(WXULCheckStep step, WXCheckULStepResult* result) {
// NSLog(@"-----%@, %u, %@, %@", @(step), result.success, result.errorInfo, result.suggestion);
// }];
2.监听处理Universal Link回调
实现三个微信sdk需要调用的方法,原样复制即可,AppDelegate.m中已经存在,需要把huilder的给注释掉,按方法名搜索。注意!由于AppDelegate.m里面代码多,不要粘贴错地方,里面有两个@implementation XXX @end模块:@implementation UINavigationController(Orient)@end 和 @implementation AppDelegate @end。 代码需要放在@implementation AppDelegate @end中。或者你放到原来方法的旁边,被这个坑了三天,原生大佬勿喷,我不是很懂ios原生。不然会出现,跳转到微信后,显示正在连接,然后又跳回来,并提示PBItemCollectionServicer connection disconnected。自建函数第5步也会提示该错误。因为没有正确处理微信的Universal Link回调方法。onResp监听微信返回app。
//
-(void)onResp:(BaseResp *)resp
{
NSLog(@"-----onResp---");
if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]])
{
NSString *string = resp.errStr;
NSLog(@"-----onResp:%@", string);
// 对应JsApi navigateBackApplication中的extraData字段数据
}
}
-(void) onReq:(BaseReq*)req
{
NSLog(@"-----onReq---");
if([req isKindOfClass:[GetMessageFromWXReq class]])
{
// 微信请求App提供内容, 需要app提供内容后使用sendRsp返回
NSString *strTitle = [NSString stringWithFormat:@"微信请求App提供内容"];
NSString *strMsg = @"微信请求App提供内容,App要调用sendResp:GetMessageFromWXResp返回给微信";
}
else if([req isKindOfClass:[ShowMessageFromWXReq class]])
{
ShowMessageFromWXReq* temp = (ShowMessageFromWXReq*)req;
WXMediaMessage *msg = temp.message;
//显示微信传过来的内容
WXAppExtendObject *obj = msg.mediaObject;
NSString *strTitle = [NSString stringWithFormat:@"微信请求App显示内容"];
NSString *strMsg = [NSString stringWithFormat:@"标题:%@ \n内容:%@ \n附带信息:%@ \n缩略图:%u bytes\n\n", msg.title, msg.description, obj.extInfo, msg.thumbData.length];
}
else if([req isKindOfClass:[LaunchFromWXReq class]])
{
//从微信启动App
NSString *strTitle = [NSString stringWithFormat:@"从微信启动"];
NSString *strMsg = @"这是从微信启动的消息";
}
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSLog(@"-----handleOpenURL---");
return [WXApi handleOpenURL:url delegate:self];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(@"-----openURL---");
return [WXApi handleOpenURL:url delegate:self];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable))restorationHandler {
NSLog(@"-----continueUserActivity---");
return [WXApi handleOpenUniversalLink:userActivity delegate:self];
}
3.hbuilder自定义插件开发
头部.h:
#include "PGPlugin.h"
#include "PGMethod.h"
#import <Foundation/Foundation.h>
@interface AlibabaRLSB : PGPlugin
- (void)LaunchMiniProgram:(PGMethod*)command;
@end
内容.m
#import "PGPlugin+AlibabaRLSB.h" //引入头部
#import <RPSDK/RPSDK.h>
#import "WXApi.h"
@implementation AlibabaRLSB
/**
*启动小程序
*/
- (void)LaunchMiniProgram:(PGMethod*)commands
{
if ( commands ) {
// CallBackid 异步方法的回调id,H5+ 会根据回调ID通知JS层运行结果成功或者失败
NSString* cbId = [commands.arguments objectAtIndex:0];
NSString* path = [commands.arguments objectAtIndex:1];
NSLog(@"小程序路径path:%@", path);
WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object];
launchMiniProgramReq.userName = @"gh_******"; //拉起的小程序的username
launchMiniProgramReq.path = path; 拉起小程序页面的可带参路径,不填默认拉起小程序首页,对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"。
launchMiniProgramReq.miniProgramType = 0; //拉起小程序的类型 0-正式版; 1-测试版; 2-体验版
return [WXApi sendReq:launchMiniProgramReq completion:^(BOOL success) {
NSLog(@"拉起小程序结果=%d",success);
}];
// 运行Native代码结果和预期相同,调用回调通知JS层运行成功并返回结果
// PDRPluginResult *resultShow = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsString:pResultString];
//
// // 通知JS层Native层运行结果
// [self toCallback:cbId withReslut:[resultShow toJSONString]];
}
}
//获取当前屏幕显示的viewcontroller
- (UIViewController *)getCurrentVC
{
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
UIViewController *currentVC = [self getCurrentVCFrom:rootViewController];
return currentVC;
}
- (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC
{
UIViewController *currentVC;
if ([rootVC presentedViewController]) {
// 视图是被presented出来的
rootVC = [rootVC presentedViewController];
}
if ([rootVC isKindOfClass:[UITabBarController class]]) {
// 根视图为UITabBarController
currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
} else if ([rootVC isKindOfClass:[UINavigationController class]]){
// 根视图为UINavigationController
currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
} else {
// 根视图为非导航类
currentVC = rootVC;
}
return currentVC;
}
@end
我的组件名叫做AlibabaRLSB。下面那个getCurrentVC,这里没用到,用阿里人脸识别时用到,就没删,如果你要开发其他插件可能也会用到。userName 是小程序的原始ID,不是小程序ID。 注册插件的写法如下,hbuilder的文档写得很模糊,位置:PandoraApi.bundle->feature.plist。
4.html页面调用插件
function WXTools() {}
// 微信授权登录对象
WXTools.prototype.aweixin = undefined;
// 当前环境支持的所有授权登录对象
WXTools.prototype.auths = {};
WXTools.prototype.SuccessCallBack = undefined;
WXTools.prototype.FailCallBack = undefined;
WXTools.prototype.Options = undefined;
/*
* 打开小程序
*/
WXTools.prototype.launchMiniProgram = function launchMiniProgram(_Options) {
this.Options = _Options || {};
this.MiniProgramPath = _Options.path;
this.SuccessCallBack = this.Options.success;
this.FailCallBack = this.Options.fail;
if (window.plus.os.name == 'Android') {
this.getShareService();
} else {
this.launchMiniProgram_IOS();
}
}
/*
* ios打开小程序
*/
WXTools.prototype.launchMiniProgram_IOS = function launchMiniProgram_IOS() {
var that = this;
var success = typeof that.SuccessCallBack !== 'function' ? null : function(args) {
console.log("--SuccessCallBack---")
console.log(JSON.stringify(args))
//that.SuccessCallBack(args);
},
fail = typeof that.FailCallBack !== 'function' ? null : function(code) {
console.log("--FailCallBack---")
console.log(JSON.stringify(code))
//that.FailCallBack(code);
};
callbackID = plus.bridge.callbackId(success, fail);
if(!this.IsFirst_IOS){
//跳转回来时刷新
document.addEventListener("resume", function() {
console.log("--小程序跳转app---")
that.SuccessCallBack && that.SuccessCallBack();
}, false);
this.IsFirst_IOS = true;
}
return plus.bridge.exec("AlibabaRLSB", "LaunchMiniProgram", [callbackID, this.MiniProgramPath]);
}
//获取微信分享服务
WXTools.prototype.getShareService = function getShareService() {
var that = this;
that.shareauths = [];
plus.share.getServices(function(services) {
for (var i in services) {
var service = services[i]
that.shareauths[service.id] = service;
}
that.wxShare = that.shareauths['weixin'];
that.launchMiniProgram_in(); //下一步授权
}, function(e) {
console.log("获取登录授权服务列表失败:" + JSON.stringify(e));
that.FailCallBack && that.FailCallBack(e);
});
}
WXTools.prototype.launchMiniProgram_in = function launchMiniProgram_in() {
var that = this;
if (!this.wxShare) {
console.log("当前环境不支持微信操作");
that.FailCallBack && that.FailCallBack({
code: -1,
message: "当前环境不支持微信操作"
});
return;
}
document.addEventListener("resume", function() {
if (plus.runtime.arguments != "") {
var re = {};
try {
re = JSON.parse(plus.runtime.arguments);
} catch (e) {
re = plus.runtime.arguments;
}
that.SuccessCallBack && that.SuccessCallBack(re);
}
});
var herf = this.MiniProgramPath;
this.wxShare.launchMiniProgram({
id: 'gh_***c',
path: herf, //跳转到小程序的页面并传参
type: 0 //0-正式版; 1-测试版; 2-体验版
},
function(e) {},
function(e) {
console.log("当前环境不支持微信操作:" + JSON.stringify(e));
that.FailCallBack && that.FailCallBack(e);
})
}
var WXTool = new WXTools();
这里的安卓是调用hbuilder的插件,ios是刚刚自己写的插件。通过document.addEventListener("resume")监听小程序跳转回app,然后刷新页面;也可以通过监听onResp,然后刷新页面,这种方法比较麻烦,我就懒得折腾了,自行研究。