背景
之前在工程中用到webView的情况大多都是一些协议条款之类简单的东西并没有交互的要求,所以只用一个UIWebView展示了出来,最近公司出了一个活动需要快速上线,主体是前端同事做的,但是一些功能还需要移动端支持,所以产生了交互的需求,目前是一个初步的方案。
大致方案
我采用的方案是封装了一个父类的ViewController, 将webView与一些基本的需要设置的东西(例如右上角菜单,访问网页时传入cookie)以及一些通用的交互方法(如分享,保存图片到本地)封装到着各类中,然后根据不同的业务创建不同的子类,子类可以根据自身需求加入独有的交互方法,方便管理。
代码
- 父类的实现
1、采用实现交互,子类可以通过重写
- (void)JavaScriptCallObjectiveC
与- (void)ObjectiveCCallJavaScript
方法来实现自己独有的交互需求 2、返回按钮在webView进入二级页面时会变成一个返回按钮(用来返回上一页)、一个关闭按钮(用来直接关闭Controller) 3、注意这里我采用了一个进度条的第三方 如果处理不当会与产生冲突,解决方法可以参照我的另一篇 4、- (void)setCookiesForURL:(NSURL *)url
方法是为webView设置Cookie (比如我们某些页面防止有人恶意访问,会验证用户的真实性,还有就是传入app版本让前端来做一些判断)
#import#import @interface ZCQGBaseWebViewViewController : UIViewController- (instancetype)initWithUrlString:(NSString *)urlString title:(NSString *)title;@property (nonatomic, strong) UIWebView *webView;@property (nonatomic, strong) WebViewJavascriptBridge *jsBridge;//bridge实体@property (nonatomic, assign) BOOL canShare;//能否分享@property (nonatomic, assign) BOOL needCookie;//是否需要传token和userId- (void)JavaScriptCallObjectiveC;//JS调用OC的方法- (void)ObjectiveCCallJavaScript;//OC调用JS的方法//.m中- (void)viewDidLoad { [super viewDidLoad]; [self initNavigationView];//初始化navigationView [self cleanCookies];//清除cookie [self createWebView];//创建webView}- (void)initNavigationView { self.navigationItem.title = self.headTitle; self.view.backgroundColor = [UIColor whiteColor]; self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName : [UIFont navTitleFont]}; self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"arrow_back"] style:UIBarButtonItemStylePlain target:self action:@selector(customBackItemAction:)]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"TD_icon_more"] style:UIBarButtonItemStylePlain target:self action:@selector(moreAction:)];}- (void)cleanCookies { NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (NSHTTPCookie *cookie in [storage cookies]) { [storage deleteCookie:cookie]; } [[NSURLCache sharedURLCache] removeAllCachedResponses];}- (void)createWebView { self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; self.webView.opaque = NO; self.webView.backgroundColor = [UIColor clearColor]; self.webView.scrollView.bounces = NO; self.webView.scrollView.showsVerticalScrollIndicator = NO; [self.view addSubview:self.webView]; [WebViewJavascriptBridge enableLogging]; self.jsBridge = [WebViewJavascriptBridge bridgeForWebView:self.webView]; [self.jsBridge setWebViewDelegate:self]; [self baseJavaScriptCallObjectiveC]; [self JavaScriptCallObjectiveC]; webViewProgress = [[NJKWebViewProgress alloc] init]; self.webView.delegate = webViewProgress; webViewProgress.webViewProxyDelegate = self.jsBridge; webViewProgress.progressDelegate = self; webViewProgressView = [[NJKWebViewProgressView alloc] init]; webViewProgressView.frame = CGRectMake(0, 64, SCREEN_WIDTH, 3); webViewProgressView.progressBarView.backgroundColor = RGBAVALUECOLOR(0x40F44A, 0.8); webViewProgressView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; [webViewProgressView setProgress:0 animated:YES]; [self.view addSubview:webViewProgressView]; NSString *newUrl = [self.urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; newUrl = [newUrl stringByReplacingOccurrencesOfString:@" " withString:@""]; NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:newUrl]]; [self.webView loadRequest:request];}//基类实现的JS调OC方法- (void)baseJavaScriptCallObjectiveC { __weak ZCQGBaseWebViewViewController *weakSelf = self; //默认的native分享方法 [self.jsBridge registerHandler:defaultShareMethod handler:^(id data, WVJBResponseCallback responseCallback) { if (![[ZCQShareManager manager] detectPlatforms]) { [weakSelf showHint:@" 未检测到可以分享的平台 "]; return; } NSDictionary *result = (NSDictionary *)data; ZCQShareUrlModel *model = [[ZCQShareUrlModel alloc] init]; model.shareTitle = (NSString *)result[@"title"]; model.shareUrl = (NSString *)result[@"shareUrl"]; model.descriptionString = (NSString *)result[@"description"]; model.shareImage = (NSString *)result[@"shareImgPath"]; [[ZCQShareManager manager] openShareViewWithModel:model completion:^(ZCQShareType type) { NSLog(@"%ld",type); }result:^(NSError *error, ZCQShareType type) { }]; }];}- (void)JavaScriptCallObjectiveC { //交给子类重写实现 }- (void)ObjectiveCCallJavaScript { //交给子类重写实现 }- (void)setCookiesForURL:(NSURL *)url { if (!self.needCookie) { return; } //设置token 和 userId NSString *host = [url host]; NSString *path = [url path]; if (host == nil || path == nil) { return; } NSString *appToken = [ZCQUserManager manager].token; if(appToken){ NSHTTPCookie *tokenCookie = [NSHTTPCookie cookieWithProperties:@{NSHTTPCookieDomain:[url host],NSHTTPCookiePath:[url path],NSHTTPCookieName:@"x-auth-token",NSHTTPCookieValue:[ZCQUserManager manager].token}]; [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:tokenCookie]; } NSString *userId = [ZCQUserManager manager].userModel.userId; if(userId){ NSHTTPCookie *uidCookie = [NSHTTPCookie cookieWithProperties:@{NSHTTPCookieDomain:[url host],NSHTTPCookiePath:[url path],NSHTTPCookieName:@"uid",NSHTTPCookieValue:[ZCQUserManager manager].userModel.userId}]; [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:uidCookie]; } NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; if (appVersion) { NSHTTPCookie *versionCookie = [NSHTTPCookie cookieWithProperties:@{NSHTTPCookieDomain:[url host],NSHTTPCookiePath:[url path],NSHTTPCookieName:@"zcqAppVersion",NSHTTPCookieValue:appVersion}]; [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:versionCookie]; } }复制代码
- 子类的实现
此时 就可以根据不同的业务类型来写一些子类来实现不同的功能,只需要根据要求将
- (void)JavaScriptCallObjectiveC
与- (void)ObjectiveCCallJavaScript
方法重写就可以了。