一篇文章搞定iOS的Cookie存取
cookie简介
cookie是在客户端存储服务器状态的一种机制,web服务器可以通过set-cookie或者set-cookie2 http头部设置cookie。
cookie可以分为两类,会话cookie和持久cookie,会话cookie是临时cookie,当前会话结束(浏览器退出)时cookie会被删除。持久cookie会存储在用户的硬盘上,浏览器退出,然后重新启动后cookie仍然存在。会话cookie和持久cookie的区别在于过期时间,如果设置了discard参数(cookie 版本1)或者没有设置expires(cookie版本0)或max-age(cookie版本1)设置过期时间,则此cookie为会话cookie
cookie有两个版本,一个是版本0(netscape cookies)和版本1(rfc 2965),目前大多数服务器使用的cookie 0。
有关cookie的详细内容请参考《http权威指南》的相关章节。
引言
当前一些公司为了快速出一款app,很多时候采用uinavigationcontroller+webview或者navigationcontroller+uitabbarvc+webview的方式,这样就不可避免的需要使用cookie与html5交互,下面讲述几种常用情景下cookie的添加方法:
一. uiwebview:
// 工厂类中存储cookie的方法 + (void)savecookies { // 创建一个可变字典存放cookie nsmutabledictionary *fromappdict = [nsmutabledictionary dictionary]; [fromappdict setobject:@"fromapp" forkey:nshttpcookiename]; [fromappdict setobject:@"ios" forkey:nshttpcookievalue]; // kdomain是公司app网址 [fromappdict setobject:kdomain forkey:nshttpcookiedomain]; [fromappdict setobject:kdomain forkey:nshttpcookieoriginurl]; [fromappdict setobject:@"/" forkey:nshttpcookiepath]; [fromappdict setobject:@"0" forkey:nshttpcookieversion]; // 将可变字典转化为cookie nshttpcookie *cookie = [nshttpcookie cookiewithproperties:fromappdict]; // 获取cookiestorage nshttpcookiestorage *cookiestorage = [nshttpcookiestorage sharedhttpcookiestorage] // 存储cookie [cookiestorage setcookie:cookie]; }
uiwebview使用时间较长,只要在cookiestorage中设置了相应的cookie,每次就会自动带上;
但是这样的弊端是随着与h5的交互增加,cookie占用的空间越来越大,每次交互都夹带大量的cookie,不仅增加服务器端压力,也浪费用户的流量。比如每次交互都夹带5kb的cookie内容,但是真正用到的只有两三百字节。
二. wkwebview
wkwebview相比于uiwebview:
- 速度快了一倍,内存却减少为原来的一半;
- cookie不再是自动携带,需要手动设置;
- 交互更加顺畅,比如app底部四个tabbar也都是网页的,在uiwebview下点击,整个h5页面都会闪白一下,但是在wkwebview下点击,四个tabbar效果与原生app效果更加类似,不会有闪白现象。
- 增减了一些代理方法,更方便的进行协议拦截和进度条展示
1、在创建的时候存放到wkuserscript中进行添加cookie
wkwebviewconfiguration *webconfig = [[wkwebviewconfiguration alloc] init]; // 设置偏好设置 webconfig.preferences = [[wkpreferences alloc] init]; // 默认为0 webconfig.preferences.minimumfontsize = 10; // 默认认为yes webconfig.preferences.javascriptenabled = yes; // 在ios上默认为no,表示不能自动通过窗口打开 webconfig.preferences.javascriptcanopenwindowsautomatically = no; // web内容处理池 webconfig.processpool = [[wkprocesspool alloc] init]; // 将所有cookie以document.cookie = 'key=value';形式进行拼接 #warning 然而这里的单引号一定要注意是英文的,不要问我为什么告诉你这个(手动微笑) nsstring *cookievalue = @"document.cookie = 'fromapp=ios';document.cookie = 'channel=appstore';"; // 加cookie给h5识别,表明在ios端打开该地址 wkusercontentcontroller* usercontentcontroller = wkusercontentcontroller.new; wkuserscript * cookiescript = [[wkuserscript alloc] initwithsource: cookievalue injectiontime:wkuserscriptinjectiontimeatdocumentstart formainframeonly:no]; [usercontentcontroller adduserscript:cookiescript]; webconfig.usercontentcontroller = usercontentcontroller; wkwebview *wkwebview = [[wkwebview alloc] initwithframe:frame configuration:webconfig]; wkwebview.uidelegate = wkwebview; wkwebview.navigationdelegate = wkwebview;
2、加载某个url的时候添加cookie
如果wkwebview在加载url的时候需要添加cookie,需要先手动获取当前nshttpcookiestorage中的所有cookie,然后将cookie放到nsmutableurlrequest请求头中
- (void)loadrequestwithurlstring:(nsstring *)urlstring { // 在此处获取返回的cookie nsmutabledictionary *cookiedic = [nsmutabledictionary dictionary]; nsmutablestring *cookievalue = [nsmutablestring stringwithformat:@""]; nshttpcookiestorage *cookiejar = [nshttpcookiestorage sharedhttpcookiestorage]; for (nshttpcookie *cookie in [cookiejar cookies]) { [cookiedic setobject:cookie.value forkey:cookie.name]; } // cookie重复,先放到字典进行去重,再进行拼接 for (nsstring *key in cookiedic) { nsstring *appendstring = [nsstring stringwithformat:@"%@=%@;", key, [cookiedic valueforkey:key]]; [cookievalue appendstring:appendstring]; } nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:[nsurl urlwithstring:urlstring]]; [request addvalue:cookievalue forhttpheaderfield:@"cookie"]; [self loadrequest:request]; }
3、afnetworking
afnetworking存取cookie就比较常见了,话不多说,都在代码里了 // 获取afhttprequestoperationmanager afhttprequestoperationmanager *operationmanager = [afhttprequestoperationmanager manager]; // 创建可变字典用于存放cookie nsmutabledictionary *cookiedic = [nsmutabledictionary dictionary]; // 存放新添加的cookie #warning 单个的cookie还好,但是楼主在工厂类方法中拼接了一个包含6个设备信息的value值,最后忘记加分号了,测试也没测出来 #warning 因为不影响功能,但是后面的cookie就自动拼接上了,h5那边也识别不到,险造成重大事故(涉及金融。。),望后来者看到,提前做好准备(就凭这个坑,你得给我个赞) nsmutablestring *cookievalue = [nsmutablestring stringwithformat:@"fromapp=ios;"]; // 获取 nshttpcookiestorage *cookiejar = [nshttpcookiestorage sharedhttpcookiestorage]; for (nshttpcookie *cookie in [cookiejar cookies]) { [cookiedic setobject:cookie.value forkey:cookie.name]; } // cookie重复,先放到字典去重,再进行拼接 for (nsstring *key in cookiedic) { nsstring *appendstring = [nsstring stringwithformat:@"%@=%@;", key, [cookiedic valueforkey:key]]; [cookievalue appendstring:appendstring]; } // 将cookie存到请求头中 [operationmanager.requestserializer setvalue:cookievalue forhttpheaderfield:@"cookie"]; // 拼接url地址 nsstring *urlstr = [nsstring stringwithformat:@"%@%@", khostip, kpath]; // 设置参数字典 nsdictionary *paradict = @{ @"key" : value }; // 发送请求,处理结果 [operationmanager post:urlstr parameters:paradict success:^(afhttprequestoperation * _nonnull operation, id _nonnull responseobject) { nslog(@"responseobject-->%@", responseobject); } failure:^(afhttprequestoperation * _nullable operation, nserror * _nonnull error) { nslog(@"error-->%@", error); }];
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
推荐阅读
-
一篇文章搞定iOS的Cookie存取
-
一篇文章让你看懂IOS中的block为何再也不需要WeakSelf弱引用
-
一篇文章搞定java中集合的经典面试题
-
荐 一篇文章带你搞定 JPA 中的复杂查询(JPQL)
-
一篇文章带你搞定 MATLAB 中的循环与分支结构
-
一篇文章搞定如何使用自动生成的序列创建3D图表(Part 2) Devexpresswpf3D
-
一篇文章搞定如何使用自动生成的序列创建3D图表(Part 3) DevExpress v20.2DevExpressWPF
-
一篇文章教你轻松搞定WPF应用程序到 .NET的迁移 WPFdevexpressWPF界面控件应用界面美化
-
一篇文章搞定如何使用自动生成的序列创建3D图表(Part 2) Devexpresswpf3D
-
一篇文章搞定如何使用自动生成的序列创建3D图表(Part 1) DevExpressDevExpress v20.2wpf3d