iOS解析HTMl标签以及开发中的一些坑

开篇

看了看更新日期好久没写简书了,经常还有小伙伴在文章下面评论,看到自己写的东西还是有点用的,鼓励自己接着坚持下去吧,哈哈。今天主要就写写iOS中怎么解析HTML标签,我们常用的后台返回数据一般是json格式的但是有些时候如果我们收到的是带HTMl标签的我们该怎么处理他呢,今天就来说一说吧。

正文

前两天获取后台数据的时候,得到这么一条返回信息

"恭喜您获得<font color='red'>8.1元</font>现金奖励 "

本来简简单单的把返回数据展示到label上的事情一下子变得有趣起来,后台说是为了以后产品改返回内容的时候容易处理,可以这理由很强势。


很强势

但是作为开发的我们怎么处理呢,首先我们看下安卓的处理方法,安卓对处理这个还是比较粗暴的人家有系统方法,如下:

安卓端解析html.png

那么iOS端怎么处理呢,我们可以用webview,也可以用Label的attributedString属性,也可以直接简单粗暴的分割字符串,然后去除HTML标签,然后处理,听听就让人惆怅,然而毕竟是一种方法,能解决问题的方法都是好方法,我们就放一下最粗暴方法的主要代码(其余方法在评论补充有,哈哈),去除HTML标签的方法如下:

//过滤后台返回字符串中的标签
- (NSString *)flattenHTML:(NSString *)html {
    
    NSScanner *theScanner;
    NSString *text = nil;
    
    theScanner = [NSScanner scannerWithString:html];
    
    while ([theScanner isAtEnd] == NO) {
        // find start of tag
        [theScanner scanUpToString:@"<" intoString:NULL] ;
        // find end of tag
        [theScanner scanUpToString:@">" intoString:&text] ;
        // replace the found tag with a space
        //(you can filter multi-spaces out later if you wish)
        html = [html stringByReplacingOccurrencesOfString:
                [NSString stringWithFormat:@"%@>", text]
                                               withString:@""];
    }
    MidStrTitle = html;
    return html;
}

这样我们就处理掉了HTML标签,那么问题来了,如果我们要处理的是很多的HTML标签呢,我们该怎么处理呢,这就是这篇文章的目的。

TFHpple库

如果我们想要得到是如下一个HTML源码中某一个标签的内容呢,部分源码如下,这里只是放了标签部分的内容

<title>关于APP的声明</title>

</head>
<body>
<h3>关于APP的声明</h3>

<p>只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试</p>

<p>只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试</p>

<h3>联系我们</h3>

<p>若您在使用该APP有遇到任何问题或有新想法,都可以联系我们. 如下是我们的联系方式:</p>

<ul>
<li>只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试</li>
<li>E-mail: xxxxxxxxxxxxxxxxxxxxxxxxxx</li>
<li>phone: xxxxxxxxxxxxxxxxxx</li>
</ul>


<h3>感谢</h3>

<p>首先,感谢广大用户对公司的支持和鼓励,谢谢你们对我们的一路支持.</p>

<p>只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试</p>

<h3>版权声明</h3>

<p>只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试只是测试</p>
</body>
</html>

这里如果我要针对性取某一个标签的内容就要用到我们今天介绍的库了。

环境的配置

导入静态库


导入静态库.png

然后把导入的静态库添加到文件的路径

添加库文件的paths.png

然后导入TFHpple库就可以了。

使用方法1,简单的标签形式取值法

直接上代码

    NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
        NSString *filePath =[resourcePath stringByAppendingPathComponent:@"about.html"];
        NSData *data =[[NSData alloc]initWithContentsOfFile:filePath];
        NSString *result = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];   //data转字符串 为了打印不是乱码
        NSLog(@"------%@",result);
    
        TFHpple *Hpple = [[TFHpple alloc]initWithHTMLData:data];
    
        //测试1:获取简单的标题
        NSArray *array =[Hpple searchWithXPathQuery:@"//title"]; //获取到为title的标题
    
        for (TFHppleElement *HppleElement in array) {
    
            NSLog(@"测试1的目的标签内容:-- %@",HppleElement.text);
            
        }

我们首先获取到本地的about.html的文件,然后转化为data,加UTF8编码转换为我们可以看到的容如下图:


运行结果图

上部分为HTML文件的原标签,下部分为我们去到的标签为“title”的内容。
这样我们就得到了我们想要的。

使用方法2:有自己属性的标签内容取值

上面的那个HTML文件由于内容的局限性不方便我们举例,我们使用的HTML标签源码如下:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>hello</title>
</head>
<body>hello world
<span>
</span>
无序列表
<ul type="disc">
    <li>苹果</li>
    <li>水果</li>
    <li>桃子</li>
</ul>
<ul type="circle">
    <li>苹果2</li>
    <li>水果2</li>
    <li>桃子2</li>
</ul>
</body>
</html>

我们想去取到的是无序列表 节点属性为type 属性值为disc的标签内容,显然上面的方法已经不能满足我们的需要,老规矩先上代码:

  //测试2:获取更加详细的内容
    NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
    NSString *filePath =[resourcePath stringByAppendingPathComponent:@"first.html"];
    NSData *data =[[NSData alloc]initWithContentsOfFile:filePath];
    
    NSString *result = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];   //data转字符串 为了打印不是乱码
    NSLog(@"------%@",result);
    
    TFHpple *Hpple = [[TFHpple alloc]initWithHTMLData:data];
    NSArray *array =[Hpple searchWithXPathQuery:@"//ul"];
    
    for (TFHppleElement *HppleElement in array) {
        
        if ([HppleElement.attributes[@"type"]isEqualToString:@"disc"]) {  //找出  ul标签下  节点属性type   属性值为 disc 的数组
            
            NSArray *array2  = [HppleElement searchWithXPathQuery:@"//li"];
            
            for (TFHppleElement *HppleElement2 in array2) {
                
                NSLog(@"测试2的目的标签内容:-- %@",HppleElement2.text);
            }
        }
    }

使用方法重点在下面的这个if语句的判断里

 if ([HppleElement.attributes[@"type"]isEqualToString:@"disc"]) {

}

如果存在这种条件下的内容,根据这个BOOL值,去取到下面标签为“li‘的内容
运行结果如下:

方法二运行结果

项目中遇到的一些坑

我们取完了标签并不能结束,好不容易有时间就再写一下一些遇到的小的问题吧。

自定义键盘

自定义键盘也算是老问题了,由于情况的不同,我们可能需要定义一个完全自定义的键盘,来适应各种奇葩的需求。最近看代码的时候才发现不同的人写法真不一样,这里介绍一个个人认为比较简单的方法吧。
UITextField的inputView的属性,用法举例如下:

    kkeyboardView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320 ,260 )] ;
    kkeyboardView.backgroundColor = [UIColor lightGrayColor];
    [self setUpMyKeyBoard2];
    self.textfiled.inputView = kkeyboardView;

创建一个View 然后把它作为UITextField的inputView,这个时候就可以完全的自定义自己想要的自定义键盘了,产品你过来说说你还要键盘上有啥。

来说说
UIScrollView的滚动问题

前天同事说了一个奇怪的问题,说懒加载也写了,布局也搞了,偏移量也设置了,在别的页面都搞好了,这个页面的滚动试图忽然就不动了。老司机也翻车了喜闻乐见,但是问题怎么处理呢。

-(void)viewDidLayoutSubviews
{
    _BaseScore.contentSize = CGSizeMake(SCREEN_WIDTH, 568.0 - 44); 
}

一阵折腾之后给了他这个方法,把偏移量写在这个方法里就可以滚动了,同事不禁说老了老了,发现自己记忆越来越差了,哈哈,有一群这样的同事真的工作比较开心。

后记

今天的主要介绍就这么多吧,希望对需要的小伙伴有所帮助,有时间的话下次写一下,项目中用到的,商家端生成二维码收款,用户端扫描二维码付款,以及定时刷新,状态判断,扫描二维码生成邀请码等一系列二维码相关的功能。有写的不对地方的欢迎指出,大神轻喷,哈哈。

补充:

再补充两条简单情况下的方法:

  • Label的attributedString属性
NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[h5str dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
[selflab setAttributedText:attrStr];
  • 利用web view
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
NSString *html_str = [NSString stringWithFormat:@"<div style='color:red'>666666</div> 测试 %@",@"新风作浪",@"2020-01-00"];
[self.webView loadHTMLString:html_str baseURL:nil];
[self.view addSubview:self.webView];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,630评论 1 92
  • 在开发React Native的App的时候,你会遇到很多情况是原生的视图组件已经开发好了的。有的是系统的SDK提...
    uncle_charlie阅读 2,806评论 0 5
  • 诗诗,昨晚睡得早,没来得及给你写汇报,事实上更悲惨的是,早上我把调好的闹钟“6:15”给按掉,重新躺下来睡着了...
    谢baby阅读 330评论 0 0