由于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,然後重新整理頁面,這種方法比較麻煩,我就懶得折騰了,自行研究。
5.踩坑
- 自檢函數用來測試挺好用的,如果加上自檢函數崩潰時,請檢查項目裡是不是加了兩個libWeChatSDK.a,離線包裡的微信sdk比較舊,可能沒有自檢函數。在Build Settings->Search Paths中可以檢視引入的libs位置。
- 出現未驗證應用:連結,常見問題自查,出問題社群99%都是丢給你這兩個連結,也确實有點用。