Objective-C与JavaScript交互初探

背景

之前在工程中用到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方法重写就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值