美文网首页
iOS之WKWebView封装

iOS之WKWebView封装

作者: 喵洛 | 来源:发表于2019-01-21 16:23 被阅读0次

    最近在开发的时候遇到一个麻烦的事,iOS客户端开发使用了webview,但是发现共性问题了之后,就得每个项目都要去改动,然后我就封装了个webview,准备以后得iOS客户端项目统一使用这个类,出现问题了也好处理。

    首先,这个封装是针对WKWebView的封装,我们现在使用的也是此webview。源码如下,也欢迎大家留言,我来完善。

    @interface LLWKWebView : UIView
    
    //web的title,时时更新
    @property (nonatomic, copy  )   NSString *titleName;
    
    //加载的H5的链接
    @property (nonatomic, copy  )   NSString *url;
    
    //自定义的UA,默认为""
    @property (nonatomic, copy  )   NSString *userAgent;
    
    //url的requestHeader里的内容,string形式的key和value,默认@{}
    @property (nonatomic, copy  )   NSDictionary *headerParams;
    
    //message.name,message.body
    @property (nonatomic, copy  )   void(^jsActionBlock)(NSString *name,id body);
    
    //jsArray:ScriptMessageHandler方法名
    - (instancetype)initWithConfig:(NSArray *)jsArray frame:(CGRect)frame;
    
    //加载url
    - (void)startLoadUrl;
    
    //刷新界面
    - (void)wkRefresh;
    
    //返回上一个界面---popViewController
    - (void)wkPopViewController;
    
    //返回web的history---[wkWebView goBack];
    - (void)wkGoWebHistory;
    
    //返回主界面---popToRootViewController
    - (void)wkPopRootViewController;
    
    @end
    
    @interface LLWKWebView()<WKNavigationDelegate,WKScriptMessageHandler>
    {
        NSMutableURLRequest *webRequest;
        WKWebViewConfiguration *wkConfig;
        
        NSArray *configArray;
        NSMutableDictionary *headers;
    }
    
    @property (nonatomic, copy  )   WKWebView *wkWebView;
    
    @property (nonatomic, copy  )   UIActivityIndicatorView *loadingView;
    
    @end
    
    @implementation LLWKWebView
    
    - (void)dealloc
    {
        [wkConfig.userContentController removeAllUserScripts];
        _wkWebView.navigationDelegate = nil;
    }
    
    #pragma -mark init
    - (instancetype)initWithConfig:(NSArray *)jsArray frame:(CGRect)frame
    {
        self = [super init];
        if (self) {
            self.frame = frame;
            configArray = jsArray;
            headers = [NSMutableDictionary dictionary];
            
            _titleName = @"";
            _url = @"";
            _userAgent = @"";
            wkConfig = [[WKWebViewConfiguration alloc] init];
            _loadingView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
            
            [self initWeb:frame];
        }
        return self;
    }
    
    - (void)initWeb:(CGRect)frame
    {
        WKUserContentController *userContentController = [[WKUserContentController alloc] init];
        for (NSString *jsName in configArray) {
            [userContentController addScriptMessageHandler:self name:AI_STR_DEFAULT(jsName)];
        }
        wkConfig.userContentController = userContentController;
        
        _wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) configuration:wkConfig];
        _wkWebView.navigationDelegate = self;
        [self addSubview:_wkWebView];
        
        _loadingView.center = _wkWebView.center;
        [self addSubview:_loadingView];
    }
    
    #pragma -mark setter
    - (void)setUserAgent:(NSString *)userAgent
    {
        _userAgent = userAgent;
        if (@available(iOS 12.0, *)){
            NSString *baseAgent = [_wkWebView valueForKey:@"applicationNameForUserAgent"];
            NSString *userAgent = [NSString stringWithFormat:@"%@ %@",baseAgent,_userAgent];
            [_wkWebView setValue:userAgent forKey:@"applicationNameForUserAgent"];
        }
        [_wkWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
            NSString *newUA = [NSString stringWithFormat:@"%@ %@",result,self->_userAgent];
            self->_wkWebView.customUserAgent = newUA;
        }];
    }
    
    - (void)setUrl:(NSString *)url
    {
        NSString *urlString = [url stringByReplacingOccurrencesOfString:@"\r" withString:@""];
        urlString = [urlString stringByReplacingOccurrencesOfString:@"\r" withString:@""];
        urlString = [urlString stringByReplacingOccurrencesOfString:@"\r" withString:@""];
        _url = urlString;
    }
    
    - (void)setHeaderParams:(NSDictionary *)headerParams
    {
        _headerParams = headerParams;
        [headers setValuesForKeysWithDictionary:_headerParams];
    }
    
    #pragma mark - webView加载
    - (void)startLoadUrl
    {
        if (_url && _url.length > 0)
        {
            webRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20];
            NSArray *headerKeys = headers.allKeys;
            for (NSInteger i=0;i<headerKeys.count;i++) {
                NSString *key = AI_STR_DEFAULT(headerKeys[i]);
                NSString *value = AI_STR_DEFAULT(headers[key]);
                [webRequest setValue:value forHTTPHeaderField:key];
            }
            [_wkWebView loadRequest:webRequest];
        }
    }
    
    - (void)wkRefresh
    {
        [self startLoadUrl];
    }
    
    #pragma mark - WKWebview
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
    {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    
    - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
    {
        [self startLoading];
    }
    
    - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
    {
        [self stopLoding];
    }
    
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
    {
        [self stopLoding];
        if(error.code == NSURLErrorCancelled)  {
            return;
        }
        if (error.code == NSURLErrorUnsupportedURL) {
            return;
        }
    }
    
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
    {
        [self stopLoding];
        self.titleName = webView.title;
    }
    
    #pragma mark - 加载JS处理
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
    {
        if (_jsActionBlock) {
            _jsActionBlock(AI_STR_DEFAULT(message.name),message.body);
        }
    }
    
    #pragma -mark 方法
    - (void)startLoading
    {
        [_loadingView startAnimating];
        _loadingView.hidden = NO;
    }
    
    - (void)stopLoding
    {
        [_loadingView stopAnimating];
        _loadingView.hidden = YES;
    }
    
    - (UIViewController *)findViewController
    {
        id target=self;
        while (target) {
            target = ((UIResponder *)target).nextResponder;
            if ([target isKindOfClass:[UIViewController class]])
                break;
        }
        return target;
    }
    
    - (void)wkPopViewController{
        [[self findViewController].navigationController popViewControllerAnimated:YES];
    }
    
    - (void)wkPopRootViewController{
        [[self findViewController].navigationController popToRootViewControllerAnimated:YES];
    }
    
    - (void)wkGoWebHistory{
        if ([_wkWebView canGoBack]) {
            [_wkWebView goBack];
        }
        else{
            [self wkPopViewController];
        }
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:iOS之WKWebView封装

          本文链接:https://www.haomeiwen.com/subject/kuvcjqtx.html