YTKWebView 0.1.4

YTKWebView 0.1.4

xiaochun0618维护。



  • 作者
  • lihc

YTKWebView

CI Status Version License Platform

YTKWebView 是什么

YTKWebView 是对 UIWebView 进行更高层次封装的工具类,为 UIWebView 封装了生命周期、JS 注入通信的能力,生命周期概念包括:init 初始化、loading 加载中、succeed 加载完毕、failed 加载失败、close 关闭,主要由 UIWebViewDelegate、runtime、YTKJSBridge 实现。

YTKWebView 提供了哪些功能

  • 支持生命周期概念。
  • 支持自动或手动管理生命周期。
  • 支持生命周期变化通知,包括 Protocol、Notification 的通知方式。
  • 支持向 webView 注入 JS 方法。
  • 支持调用 webView 提供的 js 方法。

哪些项目适合使用 YTKWebView

YTKWebView 适合用 Objective-C 实现的项目,并且项目中使用 UIWebView 作为网页展示的容器,并且有较多的 JS 通信需求。

如果你的项目使用了 YTKWebView,将会提升 WebView 的加载速度以及用户使用体验,节省 JS 通信的开发成本,提高开发效率。

YTKWebView 的基本思想

YTKWebView 的基本思想是给 UIWebView 封装一个生命周期的概念。

对于webView的UIWebViewDelegate的回调将不会产生影响,生命周期状态的变化将通过protocol或notification的方式通知使用者,使用者可以根据状态变化执行一些操作,例如:在loading状态时显示本地的加载UI,这样在webView渲染完毕之前,用户不会看到空白页面等;在close状态时清理webView资源等。

通过JSContext注入的方式实现JS对native方法的同步和异步调用,从而实现JS与native之间的互相调用。

安装

你可以在Podfile中加入以下一行代码来使用YTKWebView:

pod 'YTKWebView'

安装要求

YTKWebView 版本 最低 iOS Target 注意
0.1.0 iOS 7 需要 Xcode 7 或更高版本

例子

克隆当前仓库,到Example目录下执行pod install命令,就可以运行示例工程。

使用方法

生命周期使用方法,看是否需要主动管理YTKWebView的生命周期,如果不需要管理,则只需要监听生命周期变化通知即可;如果需要主动管理YTKWebView生命周期,则需要通过业务代码来管理YTKWebView的生命周期,一个典型的例子就是JS控制YTKWebView的生命周期,例如显示loading UI等,然后通知native来做一些事情,如下所示:

// 手动管理生命周期
UIWebView *webView = [UIWebView new];
YTKWebView *ytkWebView = [[YTKWebView alloc] initWithWebView:webView];
ytkWebView.lifecycleDelegate = self;

// 监听YTKWebView生命周期变化通知,支持protocol以及notification的方式,这里以protocol为例
#pragma mark - YTKWebViewLifecycleDelegate
- (void)webViewLifecycle:(YTKWebViewLifecycle *)lifecycle webView:(UIWebView *)webView lifecycleStateDidChange:(YTKWebViewLifecycleState)state {
    NSLog(@"lifecycle did change: %@", @(state));
}

JS与native互调使用方法,native向JS注入方法,需要创建一个注入方法实现类,下面就是向JS注入同步syncSayHello以及异步asyncSayHello的方法例子,方法功能是弹出alert,标题通过JS指定,注意:方法是在异步线程执行的,如下所示:

@interface YTKAlertHandler : NSObject

@end

@implementation YTKAlertHandler

// 同步方法syncSayHello
- (void)syncSayHello:(nullable NSDictionary *)msg {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSString *title = [msg objectForKey:@"title"];
        UIAlertView *av = [[UIAlertView alloc] initWithTitle: title
                                                     message: nil
                                                    delegate: nil
                                           cancelButtonTitle: @"OK"
                                           otherButtonTitles: nil];
        [av show];
    });
}

// 异步方法asyncSayHello,带有异步方法回调completion
- (void)asyncSayHello:(nullable NSDictionary *)msg completion:(void(^)(NSError *error, id value))completion {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSString *title = [msg objectForKey:@"title"];
        UIAlertView *av = [[UIAlertView alloc] initWithTitle: title
                                                     message: nil
                                                    delegate: nil
                                           cancelButtonTitle: @"OK"
                                           otherButtonTitles: nil];
        [av show];
        if (completion) {
            completion(nil, nil);
        }
    });
}

@end

向JS注入sayHello方法,如下所示:

UIWebView *webView = [UIWebView new];
YTKWebView *ytkWebView = [[YTKWebView alloc] initWithWebView:webView];
// 向JS注入在命名空间yuantiku之下的sayHello方法
[ytkWebView addJsCommandHandlers:@[[YTKAlertHandler new]] namespace:@"yuantiku"];

JS调用native注入的方法,下面就是JS调用native来异步执行yuantiku命名空间下的asyncSayHello方法的代码,客户端注入的asyncSayHello方法需要title参数,如下所示:

// 准备要传给客户端异步方法asyncSayHello的数据,包括指令,数据,回调等,
var data = {
    methodName:"yuantiku.asyncSayHello", // 带有命名空间的方法名
    args:{title:"async: hello world"},  // 参数
    callId:123  // callId为-1表示同步调用,否则为异步调用
};
// 直接使用这个客户端注入的全局YTKJsBridge方法调用yuantiku命名空间下的asyncSayHello方法执行
YTKJsBridge(data);

下面就是JS调用native来同步执行yuantiku命名空间下的syncSayHello方法的代码,客户端注入的syncSayHello方法需要title参数,如下所示:

// 准备要传给客户端同步方法syncSayHello的数据,包括指令,数据,回调等,
var data = {
    methodName:"yuantiku.syncSayHello", // 带有命名空间的方法名
    args:{title:"sync: hello world"},  // 参数
    callId:-1  // callId为-1表示同步调用,否则为异步调用
};
// 直接使用这个客户端注入的全局YTKJsBridge方法调用yuantiku命名空间下的syncSayHello方法执行
YTKJsBridge(data);

native调用JS方法,下面就是native调用JS执行名为alert的JS方法,带有三个参数message,cancelTitle,confirmTitle,分别代表alert提示的文案、取消按钮文案、确认按钮文案,如下所示:

UIWebView *webView = [UIWebView new];
// webView加载代码省略...
YTKWebView *ytkWebView = [[YTKWebView alloc] initWithWebView:webView];
// 准备传入JS的数据,包括指令,数据等
NSDictionary *parameter = @{@"message" : @"hello, world",
                        @"cancelTitle" : @"cancel",
                       @"confirmTitle" : @"confirm"};
// 客户端调用网页的alert方法,弹出alert弹窗
[ytkWebView callJsCommandName:@"alert" argument:@[parameter]];

作者

YTKWebView 的主要作者是:

lihc, https://github.com/xiaochun0618

协议

YTKWebView 在MIT协议下授权使用。查阅LICENSE文件以获取更多信息。