背景
之前在工程中用到webView的情况大多都是一些协议条款之类简单的东西并没有交互的要求,所以只用一个UIWebView展示了出来,最近公司出了一个活动需要快速上线,主体是前端同事做的,但是一些功能还需要移动端支持,所以产生了交互的需求,目前是一个初步的方案。
大致方案
我采用的方案是封装了一个父类的ViewController, 将webView与一些基本的需要设置的东西(例如右上角菜单,访问网页时传入cookie)以及一些通用的交互方法(如分享,保存图片到本地)封装到着各类中,然后根据不同的业务创建不同的子类,子类可以根据自身需求加入独有的交互方法,方便管理。
代码
- 父类的实现
1、采用WebViewJavascriptBridge实现交互,子类可以通过重写
- (void)JavaScriptCallObjectiveC
与- (void)ObjectiveCCallJavaScript
方法来实现自己独有的交互需求
2、返回按钮在webView进入二级页面时会变成一个返回按钮(用来返回上一页)、一个关闭按钮(用来直接关闭Controller)
3、注意这里我采用了一个进度条的第三方 NJKWebViewProgress 如果处理不当会与WebViewJavascriptBridge产生冲突,解决方法可以参照我的另一篇文章
4、- (void)setCookiesForURL:(NSURL *)url
方法是为webView设置Cookie (比如我们某些页面防止有人恶意访问,会验证用户的真实性,还有就是传入app版本让前端来做一些判断)
#import <UIKit/UIKit.h>
#import <WebViewJavascriptBridge.h>
@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
方法重写就可以了。
由于涉及到某些具体的业务,并没有将所有代码贴出来,有什么疑问可以联系我qq:329592157
,有什么建议也可以和我分享,祝大家早日升职加薪,步入人生巅峰!
网友评论