Unverified 提交 60736693 authored 作者: JarvanMo's avatar JarvanMo 提交者: GitHub

Merge pull request #570 from lopo12123/master

fix + docs: fix #568, #555 & update docs
...@@ -115,7 +115,7 @@ Buy the writer a cup of coffee。 ...@@ -115,7 +115,7 @@ Buy the writer a cup of coffee。
![subscribe](https://gitee.com/OpenFlutter/resoures-repository/raw/master/fluwx/wx_subscription.png) ![subscribe](https://gitee.com/OpenFlutter/resoures-repository/raw/master/fluwx/wx_subscription.png)
## Start history ## Star history
![stars](https://starchart.cc/OpenFlutter/fluwx.svg) ![stars](https://starchart.cc/OpenFlutter/fluwx.svg)
......
## WeChat reference document
## IOS - [WeChat open label jumps to APP: <wx-open-launch-app>](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html#%E8%B7%B3%E8%BD%ACAPP%EF%BC%9Awx-open-launch-app)
Please register your WXApi in your `AppDelegate`: - [App gets the extinfo data in the open tag <wx-open-launch-app>](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/APP_GET_EXTINF.html)
```oc
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ## Platform differences
//向微信注册
[[FluwxDelegate defaultManager] registerWxAPI:@"" universalLink:@""]; - The event type of **Launch-App-From-H5** on Android is `WeChatShowMessageFromWXRequest`
return YES; - The event type of **Launch-App-From-H5** on IOS is `WeChatLaunchFromWXRequest`
## Example
```dart
void handle_launch_from_h5() {
Fluwx fluwx = Fluwx();
fluwx.addSubscriber((response) {
// 1. Handle responses separately for android and ios
if (response is WeChatShowMessageFromWXRequest) {
debugPrint("launch-app-from-h5 on android");
// do something here only for android after launch from wechat
} else if (response is WeChatLaunchFromWXRequest) {
debugPrint("launch-app-from-h5 on ios");
// do something here only for android after launch from wechat
}
// 2. Or handling responses together for android and ios
if (response is WeChatLaunchFromWXRequest ||
response is WeChatShowMessageFromWXRequest) {
debugPrint("launch-app-from-h5");
// do something here for both android and ios after launch from wechat
}
});
} }
``` ```
> If you want to get ext from website, please call ``fluwx.getExtMsg()`。`For details, please read the example. > If you want to get ext from website, please call `fluwx.getExtMsg()`。For details, please read the example project.
\ No newline at end of file
## 微信参考文档
## IOS - [微信开放标签 &lt;wx-open-launch-app&gt; 跳转App](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html#%E8%B7%B3%E8%BD%ACAPP%EF%BC%9Awx-open-launch-app)
请在你的`AppDelegate`中主动注册`WXApi` - [App获取开放标签 &lt;wx-open-launch-app&gt; 中的 extinfo 数据](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/APP_GET_EXTINF.html)
```oc
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ## 平台差异
//向微信注册
[[FluwxDelegate defaultManager] registerWxAPI:@"" universalLink:@""]; - 安卓端 **微信唤起App** 的事件类型为 `WeChatShowMessageFromWXRequest`
return YES; - IOS端 **微信唤起App** 的事件类型为 `WeChatLaunchFromWXRequest`
## 示例
```dart
void handle_launch_from_h5() {
Fluwx fluwx = Fluwx();
fluwx.addSubscriber((response) {
// 1. 为安卓和ios分开处理响应
if (response is WeChatShowMessageFromWXRequest) {
debugPrint("launch-app-from-h5 on android");
// 从微信启动后,在这里只为 android 做一些事情
} else if (response is WeChatLaunchFromWXRequest) {
debugPrint("launch-app-from-h5 on ios");
// 从微信启动后,在这里只为 ios 做一些事情
}
// 2. 或者为安卓和ios一起处理响应
if (response is WeChatLaunchFromWXRequest ||
response is WeChatShowMessageFromWXRequest) {
debugPrint("launch-app-from-h5");
// 从微信启动后,在这里为 android 和 ios 做一些事情
}
});
} }
``` ```
> 如你想主动获取从网页传进来的值 ,请主动调用`fluwx.getExtMsg()`。更多信息请参考example. > 如你想主动获取从网页传进来的值 ,请主动调用`fluwx.getExtMsg()`。更多信息请参考example项目.
...@@ -48,6 +48,8 @@ typedef void(^FluwxWXReqRunnable)(void); ...@@ -48,6 +48,8 @@ typedef void(^FluwxWXReqRunnable)(void);
BOOL _isRunning; BOOL _isRunning;
BOOL _attemptToResumeMsgFromWxFlag; BOOL _attemptToResumeMsgFromWxFlag;
FluwxWXReqRunnable _attemptToResumeMsgFromWxRunnable; FluwxWXReqRunnable _attemptToResumeMsgFromWxRunnable;
// cache open url request when WXApi is not registered, and handle it once WXApi is registered
FluwxWXReqRunnable _cachedOpenUrlRequest;
} }
const NSString *errStr = @"errStr"; const NSString *errStr = @"errStr";
...@@ -205,6 +207,28 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar; ...@@ -205,6 +207,28 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
} }
BOOL isWeChatRegistered = [WXApi registerApp:appId universalLink:universalLink]; BOOL isWeChatRegistered = [WXApi registerApp:appId universalLink:universalLink];
// If registration fails, we can return immediately
if(!isWeChatRegistered){
result(@(isWeChatRegistered));
_isRunning = NO;
return;
}
// Otherwise, since WXApi is now registered successfully,
// we can (and should) immediately handle the previously cached `app:openURL` event (if any)
if (_cachedOpenUrlRequest != nil) {
_cachedOpenUrlRequest();
_cachedOpenUrlRequest = nil;
}
// Set `_isRunning` after calling `_cachedOpenUrlRequest` to ensure that
// the `onReq` triggered by this call to `_cachedOpenUrlRequest` will
// be stored in `_attemptToResumeMsgFromWxRunnable` which can be obtained
// by triggering `attemptToResumeMsgFromWx`.
//
// At the same time, this also coincides with the approach on the Android side:
// cold start events are cached and triggered through `attemptToResumeMsgFromWx`
_isRunning = isWeChatRegistered; _isRunning = isWeChatRegistered;
result(@(isWeChatRegistered)); result(@(isWeChatRegistered));
...@@ -370,27 +394,55 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar; ...@@ -370,27 +394,55 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
} }
// Deprecated since iOS 9
// See https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc
// Use `application:openURL:options:` instead.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// Since flutter has minimum iOS version requirement of 11.0, we don't need to change the implementation here.
return [WXApi handleOpenURL:url delegate:self]; return [WXApi handleOpenURL:url delegate:self];
} }
// Deprecated since iOS 9
// See https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622964-application?language=objc
// Use `application:openURL:options:` instead.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
// Since flutter has minimum iOS version requirement of 11.0, we don't need to change the implementation here.
return [WXApi handleOpenURL:url delegate:self]; return [WXApi handleOpenURL:url delegate:self];
} }
// NOTE: 9.0以后使用新API接口 // Available on iOS 9.0 and later
// See https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options { - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options {
// ↓ previous solution -- according to document, this may fail if the WXApi hasn't registered yet.
// return [WXApi handleOpenURL:url delegate:self];
if (_isRunning) {
// registered -- directly handle open url request by WXApi
return [WXApi handleOpenURL:url delegate:self]; return [WXApi handleOpenURL:url delegate:self];
}else {
// unregistered -- cache open url request and handle it once WXApi is registered
__weak typeof(self) weakSelf = self;
_cachedOpenUrlRequest = ^() {
__strong typeof(weakSelf) strongSelf = weakSelf;
[WXApi handleOpenURL:url delegate:strongSelf];
};
// simply return YES to indicate that we can handle open url request later
return YES;
}
} }
#ifndef SCENE_DELEGATE #ifndef SCENE_DELEGATE
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nonnull))restorationHandler{ - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nonnull))restorationHandler{
// TODO: (if need) cache userActivity and handle it once WXApi is registered
return [WXApi handleOpenUniversalLink:userActivity delegate:self]; return [WXApi handleOpenUniversalLink:userActivity delegate:self];
} }
#endif #endif
#ifdef SCENE_DELEGATE #ifdef SCENE_DELEGATE
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity API_AVAILABLE(ios(13.0)){ - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity API_AVAILABLE(ios(13.0)){
// TODO: (if need) cache userActivity and handle it once WXApi is registered
[WXApi handleOpenUniversalLink:userActivity delegate:self]; [WXApi handleOpenUniversalLink:userActivity delegate:self];
} }
#endif #endif
...@@ -1016,7 +1068,7 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar; ...@@ -1016,7 +1068,7 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
if ([req isKindOfClass:[GetMessageFromWXReq class]]) { if ([req isKindOfClass:[GetMessageFromWXReq class]]) {
} else if ([req isKindOfClass:[ShowMessageFromWXReq class]]) { } else if ([req isKindOfClass:[ShowMessageFromWXReq class]]) {
//onWXLaunchFromWX // ShowMessageFromWXReq -- android spec
ShowMessageFromWXReq *showMessageFromWXReq = (ShowMessageFromWXReq *) req; ShowMessageFromWXReq *showMessageFromWXReq = (ShowMessageFromWXReq *) req;
WXMediaMessage *wmm = showMessageFromWXReq.message; WXMediaMessage *wmm = showMessageFromWXReq.message;
...@@ -1026,6 +1078,7 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar; ...@@ -1026,6 +1078,7 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
[result setValue:showMessageFromWXReq.lang forKey:@"lang"]; [result setValue:showMessageFromWXReq.lang forKey:@"lang"];
[result setValue:showMessageFromWXReq.country forKey:@"country"]; [result setValue:showMessageFromWXReq.country forKey:@"country"];
// Cache extMsg for later use (by calling 'getExtMsg')
[FluwxDelegate defaultManager].extMsg= wmm.messageExt; [FluwxDelegate defaultManager].extMsg= wmm.messageExt;
if (_isRunning) { if (_isRunning) {
...@@ -1039,6 +1092,7 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar; ...@@ -1039,6 +1092,7 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
} }
} else if ([req isKindOfClass:[LaunchFromWXReq class]]) { } else if ([req isKindOfClass:[LaunchFromWXReq class]]) {
// ShowMessageFromWXReq -- ios spec
LaunchFromWXReq *launchFromWXReq = (LaunchFromWXReq *) req; LaunchFromWXReq *launchFromWXReq = (LaunchFromWXReq *) req;
WXMediaMessage *wmm = launchFromWXReq.message; WXMediaMessage *wmm = launchFromWXReq.message;
...@@ -1048,6 +1102,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar; ...@@ -1048,6 +1102,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
[result setValue:launchFromWXReq.lang forKey:@"lang"]; [result setValue:launchFromWXReq.lang forKey:@"lang"];
[result setValue:launchFromWXReq.country forKey:@"country"]; [result setValue:launchFromWXReq.country forKey:@"country"];
// Cache extMsg for later use (by calling 'getExtMsg')
[FluwxDelegate defaultManager].extMsg= wmm.messageExt;
if (_isRunning) { if (_isRunning) {
[_channel invokeMethod:@"onWXLaunchFromWX" arguments:result]; [_channel invokeMethod:@"onWXLaunchFromWX" arguments:result];
...@@ -1058,8 +1114,6 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar; ...@@ -1058,8 +1114,6 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
[strongSelf->_channel invokeMethod:@"onWXLaunchFromWX" arguments:result]; [strongSelf->_channel invokeMethod:@"onWXLaunchFromWX" arguments:result];
}; };
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论