EMAS提供WindVane供您集成应用,以实现通过WindVane集成H5应用。本文介绍如何在iOS端集成WindVane。
接入SDK
在podfile文件中指定仓库,添加依赖,并执行
pod install
或者pod update
命令,获取SDK到项目中。source 'https://github.com/CocoaPods/Specs.git' source 'https://github.com/aliyun/aliyun-specs.git' pod 'WindVane' ,'11.2.2.1'
按照如下配置,初始化SDK。
@interface EMASWindVaneConfig : NSObject + (void)setUpWindVanePlugin; @end @implementation EMASWindVaneConfig + (void)setUpWindVanePlugin { // 设置APPKey, 如果使用了安全黑匣子, 就会使用安全黑匣子的key //[WVUserConfig setAppKey:@"4272"secrect:@"0ebbcccfee18d7ad1aebc5b135ff****"]; [WVUserConfig setAppKey:[[EMASServiceshareInstance] appkey]]; // 设置是否使用安全黑匣子 [WVUserConfig useSafeSecert:NO]; // 设置环境 // [WVUserConfigsetEnvironment:WVEnvironmentDaily]; [WVUserConfig setEnvironment:WVEnvironmentRelease]; // 设置TTID //[WVUserConfig setTTid:@"windvane@****"]; // 设置UA [WVUserConfig setAppUA:[NSStringstringWithFormat:@"TBIOS"]]; // 设置 App 名称,会在 UserAgent 中带上,请务必正确设置。 [WVUserConfig setAppName:@"EMASDemo"]; // 设置App版本 NSDictionary *infoDictionary =[[NSBundle mainBundle] infoDictionary]; [WVUserConfig setAppVersion:[infoDictionary objectForKey:@"CFBundleShortVersionString"]]; // WKWebView 支持 NSURLProtocol [WVURLProtocolService setSupportWKURLProtocol:YES]; #ifdef DEBUG [WVBasicUserConfig setDebugMode:YES]; // 打开 WindVane 的 Log [WVBasicUserConfig openWindVaneLog]; [WVUserConfig setLogLevel:WVLogLevelVerbose]; [WVBasic setJSLogLevel:WVLogLevelVerbose]; #endif // 初始化WindVane各模块 //[WVTBExtension setup]; [WVBasic setup]; [WVAPI setup]; [WVMonitor startMonitoring]; [EMASWVExtensionConfig setup]; } @end
在
AppDelegate.m
文件的application:didFinishLaunchingWithOptions
方法中,调用以下代码,初始化SDK。- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self initZCacheConfig]; [EMASWindVaneConfig setUpWindVanePlugin]; }
使用WVWKWebView
建议在iOS 9或更高版本再使用WKWebView,iOS 8及之前版本存在较多缺陷。
WVWKWebView使用的是iOS 9.0新加入的WKWebView,使用WebKit内核进行渲染,具有更高的渲染效率和JS执行效率,也支持更多的HTML5特性。有需要的Native业务方可以根据自己的需要,使用WVWKWebView来展示页面。
WindVane iOS版本中,全面优化了对WVWKWebView的支持,通过 [WVURLProtocolServicesetSupportWKURLProtocol:YES]
主动开启NSURLProtocol的拦截功能后,可以正常使用预加载功能,持久化Cookie(设置有expires或max-age)也可以正常同步,但POST请求会丢失body,非持久化 Cookie仍是不能同步的。目前仅有XMLHTTPRequest
同步POST请求Blob和FormData不支持。
监听页面信息
WindVane提供了页面的基础信息。通过KVO监听WebView title属性和estimatedProgress属性的变化,就可以及时获取页面标题和加载进度的改变,然后客户端自行决定如何显示在界面中。
// 添加 KVO 监听,务必在 WebView 销毁前移除监听。
[_webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNewcontext:nil];
[_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNewcontext:nil];
// 处理 KVO 监听。
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context {
[super observeValueForKeyPath:keyPathofObject:object change:change context:context];
if ([keyPathisEqual:@"title"]) {
// change[NSKeyValueChangeNewKey] 就是新的页面标题。
} else if ([keyPath isEqual:@"estimatedProgress"]){
// [change[NSKeyValueChangeNewKey]doubleValue] 就是新的加载进度,范围是 0.0~1.0。
// 注意加载进度可能在非主线程触发,如果有 UI 操作注意切换线程。
}
}
- (void)dealloc {
// 移除KVO监听,这里只是一个示例,根据实际情况不一定要在dealloc中做。
[_webView removeObserver:selfforKeyPath:@"title"];
[_webView removeObserver:selfforKeyPath:@"estimatedProgress"];
}
接入灰度SDK
接入灰度SDK。
pod 'DynamicConfiguration', '~> 11.0.0' pod 'DynamicConfigurationAdaptor', '~> 1.0.0'
初始化灰度SDK。
// 灰度初始化 - (void)initDyConfig { NSString *appKey = @"xxxxx"; NSString * logicIdentifier = [NSString stringWithFormat:@"%@@%@",appKey, [self isDeviceIphone] ? @"iphoneos" : @"iPad"]; [[DynamicConfigurationAdaptorManager sharedInstance] setUpWithMaxUpateTimesPerDay:10 AndIdentifier:logicIdentifier AndAppkey:appKey]; }
接入ZCache SDK
1.接入ZCache SDK。
pod 'ZCache', '~> 11.1.0.0'
2.初始化ZCache SDK。
- (void)initZCache
{
NSString *appKey = @"xxx";
NSString *appSecret = @"xxx";
NSString *version = @"xxx";
[ZCache setupWithAppKey:appKey appSecret:appSecret appVersion:version];
}
(可选)使用JSBridge
JSBridge的Native方法提供方,要像提供普通方法一样提供JSBridge,要求必须满足以下基本约束:
方法调用后,必须返回,任何情况下都要调用callback以将结果返回给JS;可以根据需要返回不同的数据。
方法只能有一个返回值,也就是说callback只允许调用一次,如果有多个数据需要返回给H5,Android请使用标准事件机制,iOS请使用
JSBridge context的dispatchEvent
方法。注意做好资源的释放工作,尤其iOS不允许对View或ViewController有强引用。
注册JSBridge。
EMAS提供了两种注册方案:动态注册和静态注册。
动态注册:无需主动注册给WindVane,使用简单方便。但是要求类名与JSBridge调用时的ClassName相同,且目前仅限WindVane iOS。
静态注册:需要调用WindVane的注册方法,使用操作复杂。不要求特定的类名,会更加灵活。
总之,只要JSBridge调用的ClassName并没有被占用,那么总是建议使用动态注册的方式。
iOS动态注册JSBridge。
WindVane提供了新版本的用法,在
WVBridgeCallbackContext
中统一提供了JSBridge需要的所有功能,而且为Weex等非WebView场景也提供了支持。详情请参见下文的新接口介绍。假设需要实现两个JSBridge:
MyJSBridge.firstAPI
和MyJSBridge.secondAPI
,那么JSBridge的ClassName是MyJSBridge,HandlerName分别是firstAPI和secondAPI。创建一个MyJSBridge类(动态注册要求与JSBridge调用时的ClassName相同),需要确保不会有同名类。
令MyJSBridge类继承自WVDynamicHandler(引入头文件WVDynamicHandler.h)。
实现firstAPI和secondAPI方法,要求方法的签名必须为
-/+(void)handlerName:(NSDictionary *)paramswithWVBridgeContext:(id<WVBridgeCallbackContext>)context
,其中:方法可以是静态方法,也可以是动态方法。实例方法会直接调用,实例方法会先创建一个实例,然后在实例上调用。
方法名与JSBridge调用的HandlerName相同,这里为firstAPI和secondAPI。
第一个参数为NSDictionary *,是JS传入的参数对象。
第二个参数为 id<WVBridgeCallbackContext>,是JSBridge的调用上下文。
在方法中实现JSBridge的逻辑,使用
[contextcallbackSuccess:RESULT]/[contextcallbackFailure:RET withResult:RESULT]
来输出执行成功/失败的结果返回给JSBridge调用方。请保证任何情况下都会调用、且只会调用一次[context callbackXXX]
系列方法。说明JSBridge总是在主线程调用,如果有耗时操作,请务必自行切换线程。
可能你提供的服务带有多个阶段输出性,请使用
[contextdispatchEvent:eventName withParam:param]
将结果通过事件的方式输出给JSBridge调用方。当你的JSBridge逻辑执行完毕,可以主动调用
[contextreleaseHandler:self]
方法来主动释放内存,否则就只能等到页面销毁的时候才会释放。注意在dealloc中调用是没有意义的,因此此时对象已经被释放了。
#import <Foundation/Foundation.h> #import <WindVane/WindVane.h> @interface MyJSBridge : WVDynamicHandler @end @implementation MyJSBridge // 这是一个静态方法,直接调用。 + (void)firstAPI:(NSDictionary *)params withWVBridgeContext:(id<WVBridgeCallbackContext>)context{ // 回调中处理业务逻辑 [context callbackSuccess:nil]; } // 这是一个实例方法,会创建一个新实例,然后再调用。 // API实例 - (void)secondAPI:(NSDictionary *)params // 回调中处理业务逻辑 [context callbackSuccess:nil]; } @end
动态注册的JSBridge,要求类名不能重复。若希望扩展现有ClassName,可以使用JSBridge别名。
常见错误
如果引入WindVane时报如下的错误,那么可以在项目的BuildPhrase
中的Link Binary With Libraries
中添加 WebKit,并选择Status为Optional。
[MISSING IMAGE:error message | left | 618x118, error message | left | 618x118 ]
[MISSING IMAGE:WebKit framework | left | 479x80, WebKit framework | left | 479x80 ]
使用iOS WebView
WindVane在iOS平台提供了WVWebView(基于UIWebView)和WVWKWebView(基于WKWebView)的支持,并为两种WebView做了功能和接口的兼容。因此请总是使用
UIView*
作为WebView的类型,可以兼容WVWebView和WVWKWebView的主要功能。另外,请使用
#import <WindVane/WindVane.h>
来引入WindVane的头文件,无需区分WindVane整包或者分包。您在升级WindVane版本时,请注意检查并修改代码的Warning,尽早修改已废弃的方法。使用WindVane提供的ViewController
首先您可以选择使用WindVane提供的含有
WebView的WVUIWebViewController
,它封装了常用的WebView接口,提供了WVWebView和WVWKWebView切换、状态栏背景兼容、工具栏、错误页、加载框和横屏支持等功能。关于UI无关的基础功能信息请参考
WVViewController.h
,UI相关的功能请参考WVUIWebViewController.h
。要在
WVUIWebViewController
中切换到WVWKWebView
,可以设置useWKWebView
属性:WVUseWKWebViewNever
表示总是使用WVWebView
,是useWKWebView
属性的默认值。WVUseWKWebViewAlways
表示总是使用WVWKWebView
。WVUseWKWebViewCustomdecideIsUseWKWebView
方法的返回值决定是使用WVWKWebView
,还是WVWebView
。由于必须在初始化WebView
之前就决定是否切换到WVWKWebView
,因此WVUIWebViewController
默认会检查loadUrl
中是否包含_wvUseWKWebView=YES
参数,包含的话就切换到WVWKWebView
。#import <WindVane/WindVane.h> WVUIWebViewController * controller =[[WVUIWebViewController alloc] init]; controller.loadUrl = @"http://m.taobao.com"; // 开启 JSBridge,如果需要使用 JSBridge 必须调用。 controller.openLocalService = YES; // [iOS 7 适配] 隐藏导航栏时,为 Status Bar 添加白色背景颜色,按需要设置。 [controller supportiOS7WithoutStatusBar]; // 禁用 WebView 的长按事件,按需要设置。 // controller.openWebKitLongPress = NO; [self.navigationController pushViewController:controlleranimated:YES];
WindVane功能说明
WindVaneCore
WindVane核心库,定义了模块间的接口和约束,以及公共工具类,所有模块都必须依赖它。
WindVaneBridge
WindVane JSBridge库,提供了JSBridge的功能,可以在自己的WebView中或者直接脱离WebView使用。
WindVaneBasic
WindVane基础WebView库,提供了WebView相关功能优化和扩展,包括WebView、WKWebView、ViewController、StandardEventModal模块。
WindVaneAPI
WindVane自身提供的一些基础JSBridge API。 需要添加系统库:CoreBluetooth.framework、AddressBookUI.framework、AddressBook.framework、MessageUI.framework、Messages.framework、ContactsUI.framework、Contacts.framework、UserNotifications.framework。
WindVaneMonitor
WindVane埋点支持库,提供了埋点的UT。
WindVaneEMASExtension
EMAS扩展库,主要有URL拦截使用预加载配置和上报Crash,预加载可以让前端在EMAS平台将html、js、css 等资源打包成一个zip包,客户端可以采用启动后下载或者直接预置的方式将zip包解压到本地,使得用户在浏览网页的时候不需要再去下载资源,提升用户体验。
自定义生命周期
如果实现的是实例方法,默认情况下,每次调用都会创建一个实例。该实例会被强引用以保证不会被错误释放,直到WebView被销毁时才会释放。您可以通过以下方法,实现实例生命周期的自定义。
@implementation MyJSBridge
+ (WVBridgeScope)instanceScope {
return WVBridgeScopeInvocation;
}
@end
WindVane支持四种生命周期:每次调用一个实例(WVBridgeScopeInvocation),每个页面一个实例(WVBridgeScopePage),每个View一个实例(WVBridgeScopeView)和全局唯一实例(WVBridgeScopeStatic)。
对于ScopeInvocation和ScopePage,实例的引用会持续到页面被切换(例如WebView跳转新页面、回退历史记录等)。对于ScopeView,实例的引用会持续到View被销毁。因此在确保当前实例可以被销毁时,建议主动调用 [contextreleaseHandler:self]
立刻释放当前实例,以节约内存。ScopeStatic的实例,会一直存在,但也支持通过 [contextreleaseHandler:self] 主动释放。
与View或ViewController交互
JSBridge中允许与View(包括WebView)或ViewController交互,以实现某些特殊逻辑。或者检查ViewController是否具有特定的类型,以实现只允许在某类ViewController中调用的私有JSBridge。
不允许对View或ViewController持有强引用,防止出现循环引用导致内存泄露。context已提供view属性和 viewController供实例方法使用,在WebView环境下提供了webViewEnv属性,Weex场景下提供了weexEnv 属性。这些属性会自动设置和更新,您可以直接使用。
发送事件
在JSBridge中向容器发送事件,请使用[contextdispatchEvent:withParam:],会对当前环境(WebView/Weex)做适配。
事件机制中提供的方法只能够支持WebView环境。
复杂的JSBridge生命周期管理
对于一些持续性的JSBridge,如音频播放、动作感应,需要长时间的发送事件。但是在用户跳转到其它Native 页面、跳转到其它H5 WindVane提供了以下生命周期回调方法,可以在JSBridge中实现。
@implementation MyJSBridge /** * 重置处理器 - 该方法将会在加载新页面时调用,可以做一些清理工作。 * * @param context WVBridge 被重置时的上下文。 * @param request 要加载的新页面。 */ -(void)resetWithContext:(id<WVBridgeContext>)contextwithNextRequest:(NSURLRequest *)request { } /** * 暂停处理器 - 该方法将会在 UIViewControllerviewWillDisappear 时调用,用于降低WVBridge API的性能消耗,例如暂停播放音乐和持续性监听器等。 * 不会对 WVBridgeScopeStatic 作用域的 WVBridge 调用。 * * @param context WVBridge 被暂停时的上下文。 */ -(void)pauseWithContext:(id<WVBridgeContext>)context { } /** * 恢复处理器 - 该方法将会在 UIViewControllerviewWillAppear 时调用,用于恢复 WVBridge API 的性能,例如恢复播放音乐和持续性监听器等。 * 不会对 WVBridgeScopeStatic 作用域的 WVBridge 调用。 * * @param context WVBridge 被恢复时的上下文。 */ -(void)resumeWithContext:(id<WVBridgeContext>)context { } @end
如果JSBridge需要在切换到新页面后自动清理,需要实现
resetWithContext:withNextRequest:
;如果需要在当前UIViewController
被其它Native界面覆盖时暂停和恢复,需要实现pauseWithContext:
和resumeWithContex:
。一般建议与WVBridgeScopeView同时使用。如果需要在应用切换前后台时做特殊工作,可以自行注册
UIApplicationDidBecomeActiveNotification
和UIApplicationWillResignActiveNotification
这两个通知。新接口介绍
在新版本JSBridge接口,将所有功能收拢到了统一的id<WVBridgeCallbackContext>中,一切功能都可以通过context来实现。具体包括:
获取环境信息,基本信息有来源URL referrer,view和viewController,以及当前的环境
envUIView<WVWebViewBasicProtocol> *WeexSDKInstance *
。发送事件,提供了
dispatchEvent:withParam:
方法。释放实例,提供了
releaseHandler:
方法。回调,提供了
callbackSuccess:
和callbackFailure:withResult:
方法,以及一系列失败回调的快捷方法。所有JSBridge的方法参数全部统一为
NSDictioanry* params
和id<WVBridgeCallbackContext> context
,无论是动态注册,还是各类静态注册的方法。
支持懒加载的动态库
一些客户端为了提高应用打开速度,对动态库做了懒加载处理,这样可以将动态库的加载延迟到使用时,避免影响应用启动耗时。
如果动态库中提供了动态注册JSBridge,那么在动态库被加载之前,是找不到对应的类的,也无法正常调用。因此我们懒加载的动态库做了特别的支持,允许动态库通过plist 配置动态JSBridge的类名,以便WindVane在需要使用JSBridge时主动将动态库加载进来。
解决方案是在动态库的framework根目录,提供一个命名为XXX_bundle.plist的文件,其中的XXX部分可以任意命名,甚至同一个framework包含多个符合此规则的plist也可以。在plist中添加名为windvane_bridge_list的数组,并在数组中添加需要配置的动态JSBridge类名,多个plist的配置会自动合并。示例如下:
[MISSING IMAGE:Dynamic Framework Config | left | 600x374, Dynamic Framework Config | left |600x374 ]
请确保动态库全部位于客户端的Frameworks目录,如果不同动态库之间的映射关系存在覆盖,动态库会在JSBridge被首次使用时,打出日志 'A' 注册的WVBridge 'XXX' 被 'B' 覆盖了,此外,在WindVane的DEBUG模式下还会弹出Alert提示。
iOS静态注册JSBridge
WindVane iOS允许将JSBridge注册到全局,也可以注册到特定WebView。前者可以在任意WebView中调用,而后者只能在注册的WebView中使用,适合需要较严格的权限控制的JSBridge。 但是注册到全局的JSBridge,也可以通过对ViewController 的类型或属性进行校验,以达到部分权限的控制,因此如无特别的必要,请总是将JSBridge注册到全局,会有更少的内存消耗。
将JSBridge注册到全局
#import <WindVane/WindVane.h> // JSBridge 调用的 Block。 WVBridgeHandler handler = ^(NSDictionary *params, id<WVBridgeCallbackContext> context) { [context callbackSuccess:nil]; }; // 注册JSBridge到全局,特别注意这里的JSBridge 名称合并写作@"className.handlerName" 格式。 WVBridgeRegisterHandler(@"className.handlerName",handler);
将JSBridge注册到特定WebView
这样注册的JSBridge,只能在注册到的WebView中使用className和handlerName调用。
#import <WindVane/WindVane.h> // JSBridge 调用的 Block WVBridgeHandler handler = ^(NSDictionary *params, id<WVBridgeCallbackContext> context) { [context callbackSuccess:nil]; }; // 注册 JSBridge 到指定 WebView,特别注意这里的 JSBridge 名称合并写作 @"className.handlerName" 格式。 [webview registerHandler:@"className.handlerName" withBlock:handler]; // 注册 JSBridge到指定ViewController中的WebView,特别注意这里的JSBridge名称合并写作 @"className.handlerName" 格式。 [wvViewController registerHandler:@"className.handlerName" withBlock:handler];
静态注册的JSBridge,不支持复杂的生命周期管理。如果需要实现复杂的JSBridge,请动态注册JSBridge。
静态注册的JSBridge,若className和handlerName都相同,那么后注册的会覆盖先注册的。同时也会覆盖同名的动态注册方法。
JSBridge别名
WindVane提供了JSBridge的别名服务,可以用来对现有ClassName的JSBridge进行扩展或覆盖,也可以对JSBridge的升级、更新、改名和冲突提供解决方案。
允许将原始的JSBridge className.handlerName
,映射到新的别名aliasClassName.aliasHandlerName
,您既可以使用旧的className.handlerName
来访问,也可以使用新的aliasClassName.aliasHandlerName
来访问。
WindVane的别名服务,是首先将别名解析为原始名称,然后使用原始名称来查找 JSBridge;不要将别名指向其它别名,可能导致无法正确找到JSBridge。
iOS注册全局别名:全局别名必须与全局JSBridge配合使用。
#import <WindVane/WindVane.h>
// 注册 JSBridge 别名到全局。
NSDictionary * alias = @{
@"类别名.方法别名": @"类名.方法名",
@"aliasClassName.aliasHandlerName":@"className.handlerName"
};
WVBridgeRegisterAlias(alias);
JSBridge全局鉴权
WindVane提供了JSBridge的全局鉴权接口,供实现App级别的JSBridge API鉴权。该鉴权层切入到JSBridge的调用逻辑中,可以由客户端统一自定义鉴权逻辑。
对于单个JSBridge的鉴权,请在该JSBridge的实现中自行实现。
#import <WindVane/WindVane.h>
// 实现 JSBridge 鉴权方法。
@interface MyJSBridgeCheckerHandler : NSObject<WVBridgeCheckerProtocol>
@end
@implementation MyJSBridgeCheckerHandler
/**
检查指定 WVBridge 是否具有执行权限。
* 总是在后台线程调用。
*
* @param apiName WVBridge 的名称,格式为 "类名.方法名"。
* @param paramsWVBridge 的调用参数。
* @param context WVBridge 的执行上下文。
*
* @return 权限检查结果。
*/
- (WVBridgePermission*)checkPermission:(NSString *)apiName withParams:(NSDictionary *)paramswithContext:(id<WVBridgeContext>)context {
return [WVBridgePermissionpermissionNotSure];
}
@end
// 注册鉴权处理器。
[WVBridgeChecker registerChecker:[[MyJSBridgeCheckerHandler alloc]init]];
在Native中使用JSBridge
WindVane iOS中,支持在Native中调用JSBridge。现在提供有两种用法:
简单用法
这里适合一些简单场景下,Native调用与UI无关的JSBridge。直接调用
[WVBridge callHandler:withParams:withCallback:]
方法,传入以下参数:name: 要执行的JSBridge名称,格式为@"类名.方法名"。
params: 要执行的JSBridge参数,与JS使用方式保持一致 ,对象用NSDictionary代替,数组用NSArray代替)。
callback: 此次JSBridge调用的回调,可能在任意线程调用。
复杂用法
这里适合Native调用全功能的JSBridge,可以用于在自己的容器中完整接入JSBridge。
实现WVBridgeDelegate协议,供JSBridge回调数据给Native。
实例化自己的WVBridge实例,传入env和上面实现的delegate。
设置 WVBridge 实例的view和viewController属性,为JSBridgeAPI提供环境信息。其它属性可以根据需要设置:
opageId:当前页面的ID,变化后前一页面未调用的JSBridge会全部失效,避免影响到当前页面。
oopenPermissionCheck:启用白名单校验,只允许符合WindVane domain 配置中的Ali域名白名单的 URL 调用JSBridge,其它URL的调用都会被拒绝。
调用
callHandlerWithRequest:
、callHandlerWithURL:
或callHandler:withParams:withReqId:
方法之一,就会调用实际的JSBridge,JSBridge的回调、事件都会通过delegate返回回来。
标准事件机制
WindVane的标准事件机制,提供了Native和H5之间互发事件的标准通讯接口,便于各业务场景下的基于统一的事件模型来通讯。
Native向H5发送事件
WindVane提供了WVStandardEventCenter 类,供Native向H5发送事件:
在事件参数中,WebView是要发送事件的目标WebView,eventName是事件的名称(字符串),eventData是事件的数据(iOS是
NSDictionary*
,Android是一个JSON Object
格式的String)。在iOS平台的JSBridge中,不建议使用这里的方法来发送事件,而是使用JSBridge context的dispatchEvent方法来发送事件,对多种容器(WebView/Weex)提供了兼容。#import <WindVane-Basic/WVStandardEventCenter.h> // 向指定 WebView 发送事件。 [WVStandardEventCenter postNotificationToJS:eventName withEventData:eventData withWebView:webView]; // 向所有 WebView 发送事件,请谨慎使用。 [WVStandardEventCenter postNotificationToJS:eventName withEventData:eventData];
H5用法:
document.addEventListener('eventName', function(data) { // 这里要注意,Native 传递过来的事件参数是在data的param属性中。 alert(data.param); }, false);
H5向Native发送事件
H5用法:使用JSBridge来发送事件,注意引入windvane.js,详情可以参考如下示例。
WVStandardEventCenter.postNotificationToNative: var params = { event: 'eventName', param: { // 事件要传递的数据。 } }; window.WindVane.call('WVStandardEventCenter','postNotificationToNative',params, function(e) { alert('success'); }, function(e) { alert('failure: ' + JSON.stringify(e)); });
iOS用法:使用标准的消息中心监听事件。
[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(myEventListener) name:eventName object:nil] - (void)myEventListener:(NSNotification*)notification { // 事件参数可以从 notification.userInfo 中获取。 }