当前位置: 首页 > 编程笔记 >

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

傅恺
2023-03-14
本文向大家介绍浅谈iOS解析HTMl标签以及开发中的一些坑,包括了浅谈iOS解析HTMl标签以及开发中的一些坑的使用技巧和注意事项,需要的朋友参考一下

开篇

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

正文

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

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

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

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

那么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>

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

环境的配置

导入静态库

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

然后导入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];

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍浅谈js script标签中的预解析,包括了浅谈js script标签中的预解析的使用技巧和注意事项,需要的朋友参考一下 首先介绍预解析,虽然预解析字面意思很好理解,但是却是出坑出的最多的地方,也是bug经常会有的地方,利用好预解析的特性可以解决很多问题,并且提高代码的质量及数量,浏览器在解析代码前会把变量的声明和函数(整个函数体)提前到当前作用域的最顶端。 细节问题:在多对的scr

  • 本文向大家介绍浅谈bootstrap使用中的一些问题以及解决过程,包括了浅谈bootstrap使用中的一些问题以及解决过程的使用技巧和注意事项,需要的朋友参考一下 bootstrap是一个不错的前端框架。这里写一下使用中遇到过的几点问题。 1.bootstrap的模态框modal的问题。  有时候会出现弹出模态框的时候遮罩把模态框遮住的情况。 出现这个问题的原因,多半是模态框的html代码放置位置

  • 本文向大家介绍iOS多线程开发——NSThread浅析,包括了iOS多线程开发——NSThread浅析的使用技巧和注意事项,需要的朋友参考一下   在iOS开发中,多线程的实现方式主要有三种,NSThread、NSOperation和GCD,我前面博客中对NSOperation和GCD有了较为详细的实现,为了学习的完整性,今天我们主要从代码层面来实现NSThread的使用。案例代码上传至 http

  • 本文向大家介绍谈谈iOS开发之JSON格式数据的生成与解析,包括了谈谈iOS开发之JSON格式数据的生成与解析的使用技巧和注意事项,需要的朋友参考一下 本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一、JSON是什么? 二、我们为什么要用JSON格式的数据? 三、如何生成JSON格式的数据? 四、如何解析JSON格式的数据? JSON格式取代了xml给网络传输带来了很大的便

  • 本文向大家介绍基于Spring开发之自定义标签及其解析,包括了基于Spring开发之自定义标签及其解析的使用技巧和注意事项,需要的朋友参考一下 Spring框架是现在Java最流行的开源框架之一,并且Spring下的各种子项目对某些特定问题的解决有很好的支持。因此,如果能在Spring 基础上实现搭建自己的一套框架(基于XML配置)。就必然需要实现一些自定义的标签,主要是方便使用我们框架的人能够快

  • 本文向大家介绍浅谈vue在html中出现{{}}的原因及解决方式,包括了浅谈vue在html中出现{{}}的原因及解决方式的使用技巧和注意事项,需要的朋友参考一下 原因: 浏览器渲染机制,解析html结构 -> 加载外部脚本和样式表文件 -> 解析并执行脚本代码 -> 构造html dom模型 -> 加载图片等外部文件 -> 页面加载完毕。 初始化vue的js写在页面底部,也就是最后才执行js脚本