iOS 记录UIWebView & WKWebView 关于JS交互、cookie、session的一些问题和方法

上周在发布版本中,因为要和web做一些交互登录、Native调用、微信支付之类的需求。这让我对JS产生了很大的兴趣,感觉很有意思。
项目中之前多数使用了WKWebView、少部分为了兼容一些第三方的网页使用了UIWebView。WK的API和我们项目封装不完善为这次发版留下了很多坑。期间查到了很多的博客和文章,有很好的但不能解决我的问题,也有人云亦云的,所以趁周末抽空记录一下。

一、Cookie、session id问题

公司这次做了一个线上运动会的活动,要求用户在app里点击web网页时获取用户登录信息,如果没有登录就回调Native的登录页面登录成功在进行报名查询之类的操作。

在我们这边处理时就涉及到一个cookie的操作,同事在debug时发现WKWeb cookie并不能带进去 在网上查资料文章发现所有的都说WK是不自带进去的 经此放弃 但经过。。。后 我发现当时用的是模拟器debug我在使用真机debug时cookie缺可以正常传入 我用了iOS8.4 和11.3的手机测试过 是可以的 很费解 如果有遇到或者研究过什么原因的同学可以一起讨论一下

获取cookie
//cookie在app内有一个储存管理器 根据base url获取cookie列表
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:APIURL]];
    NSHTTPCookie *cookie = nil;
    for (NSHTTPCookie *c in cookies) {
        if ([c.domain hasSuffix:@"imxingzhe.com"] && [c.name isEqualToString:@"sessionid"]) {
            cookie = c;
            NSLog(@"saveCookies name: %@ ", c.value);
            break;
        }
    }
iOS11.0 增加了WKHTTPCookieStore 可以操作WKWeb cookie的store 亲测有效
 [_webView.configuration.websiteDataStore.httpCookieStore setCookie:cookie completionHandler:^{
            
        }];

二、WKWeb&UIWeb 设置User-Agent

/** 设置web全局UA 一般用来标识来源 方便web端来作区分 可以在app初始化时进行设置  WK同样有效*/
- (void)setUserAgent{
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        UIWebView* tempWebView = [[UIWebView alloc] initWithFrame:CGRectZero];
        NSString* userAgent = [tempWebView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
        NSString *newUserAgent ;
        
        NSString *versionString = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
        if (![userAgent containsString:@"AppName"]) {
            newUserAgent = [NSString stringWithFormat:@"%@ AppName/%@",userAgent,versionString];
        }
        NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:newUserAgent, @"UserAgent", nil];
        [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
    });
    
    
}

三、WKWebView JS交互

客户端监听js方法(web调客户端方法)

web端实现 调用webkit组件发送postMessage
//Web 端代码实现 toNativeLogin是方法名 客户端和web端商量协定就行 后面可以携带参数 客户端用来接收
window.webkit.messageHandlers.toNativeLogin.postMessage("参数")
iOS端WK实现 需要在初始化配置的时候addScriptMessageHandler
WKUserContentController *userContentController = [[WKUserContentController alloc] init];   
[userContentController addScriptMessageHandler:self name:@"toNativeLogin"];
// WKWebView的配置       
WKWebViewConfiguration *configuration =[[WKWebViewConfiguration alloc] init];
configuration.userContentController = userContentController;
_webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, _width, _height)
                                      configuration:configuration];
_webView.backgroundColor = [UIColor white];
_webView.UIDelegate = self;
_webView.navigationDelegate = self;
_webView.allowsBackForwardNavigationGestures = YES;
[self.view addSubview:_webView];
#pragma mark-- delegate 监测到js需要调用客户端方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    // 方法名
    NSString *methods = [NSString stringWithFormat:@"%@:", message.name];
    SEL selector = NSSelectorFromString(methods);
    // 调用方法
    if ([self respondsToSelector:selector]) {
        [self performSelector:selector withObject:message.body];
    } else {
        //        NSLog(@"未实行方法:%@", methods);
    }
   
}

- (void)toNativeLogin:(id)body
{
      //JS 调用客户端方法 实现 body参数
}
客户端注入JS(一般用来注入参数或者在某些特定情况下调用JS方法获取参数)

web 端实现方法 可以选择是否带参数 统一

 // 提供 pic_url 给客户端
  var picNative = 'http://static.imxingzhe.com/tuchuangupload/1524196576.jpg';
  function sendPic2Native() {
          return pic2Native;
    }
iOS端实现 可以选择是否带参数 统一
 [webView evaluateJavaScript:@"sendPicNative()" completionHandler:^(id picResurlt, NSError * _Nullable error) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"从web获取需要分享的图片 %2",picResurlt);
                        });
                    }];

四、UIWebView JS交互

iOS端注入JS
//参数方法都可以向web协定传入
JSContext context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
 NSString *alertJS=@"alert('test js OC')"; //准备执行的js代码  
[context evaluateScript:alertJS];//通过oc方法调用js的alert  
iOS端获取web设定的参数 (例如分享参数) 或者web掉用客户端代码 web声明方法 客户端来实现都可以
//从webview上获取相应的JSContext。
JSContext context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"toNativeShare"] = ^(NSString *url,NSString *title,NSString *picStr) {
        dispatch_async(dispatch_get_main_queue(), ^{
           //根据协定参数自定实现
        });
    };

推荐文章:
WKWebView与JS交互内存不释放问题探究
WKWebView 与js交互实例
WKWebView与JS交互实战技巧之API介绍

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容