• iOS:使用模板引擎渲染HTML界面


    在实际开发中,UIWebView控件接受一个HTML内容,用于相应的界面,下面是该API的接口:

    - (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL

    由于HTML内容通常是变化的,所以我们需要在内存中生成该HTML内容。比较简单粗暴的做法是将该HTML的基本内容定义在一个NSString中,然后用[NSString stringWothFormat]方法将内容进行格式化,示例如下:

    //给对应的标签格式化内容
    -(NSString *)demoFormatWithName:(NSString *)name value:(NSString *)value{
        NSString *html =
        @"<!DOCTYPE html>
    "
        "<html lang="zh-cn">
    "
        "<head>""
    "
        "<meta charset="utf-8">
    "
        "<title>这是一个HTML测试</title>
    "
        "</head>
    "
        "<body>
    "
        "<h1>%@</h1>
    "
        "<p>%@</p>
    "
        "<img src="http://img3.redocn.com/20131012/Redocn_2013101208320171.jpg" width="256" height="128"><br><hr>
    "
        "</body>
    "
        "</html>";
        NSString *content = [NSString stringWithFormat:html,name,value];
        return content;
    }

    但其实我们可以看出,这样写并不舒服,因为:

    1、模板内容和代码混在一起,既不方便阅读,也不方便更改;

    2、模板内容的渲染逻辑使用简单的[NSString stringWothFormat]来完成,功能单一。在实际开发中,我们很可能需要就原始数据进行二次处理,而这些如果模板渲染模块不能支持,我们就只能自己手工鞋这部分数据二次处理,费时费力。例如,微博的详情页面,如果微博的发送时间小于1天,则需要显示成"xxx小时前",如果小于1分钟,则需要显示成"刚刚"。这些界面渲染方便的逻辑如果能够抽取到专门的排版代码中,则会清晰很多。

    所以我们需要一个模板引擎,专门负责这类渲染的工作。

    模板引擎复杂的有:MGTemplateEngine(http://mattgemmell.com/mgtemplateengine-templates-with-cocoa/),它的模板语言比较像Smarty、FreeMarker和Django。另外它可以自由的定义Filter,以便实现上面提到的自定义渲染逻辑。它需要依赖RegexKit,RegexKit是一个正则表达式工具类,提供强大的表达式匹配和替换功能。

    也有简单的是:GRMustache(https://github.com/groue/GRMustache),它比MGTemplateEngine的功能更简单。另外GRMustache在开源社区更加活跃、更新更加频繁。

    对于上面的示例代码,在使用GRMustache模板后,我们首先需要调整模板的内容:

    1、将模板内容放在一个单独的文件中,方便日后更改,如template.html

    2、将原来的%@替换成{{ name }}的形式。

    例如调整后的模板内容为:(文件名为:template.html) 

    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="utf-8">
        <title>这是一个HTML测试</title>
    </head>
    <body>
        <h1> {{ name }} </h1>
        <p> {{ content }} </p>
        <img src="http://img3.redocn.com/20131012/Redocn_2013101208320171.jpg" width="256" height="128"><br><hr>
    </body>
    </html>

    即如图:template.html

    然后我们在代码中将该文件读取到内存中,再使用GRMustache的renderObject方法生成渲染后的HTML内容,示例代码如下:

    //给template.html中对应的标签格式化内容
    -(NSString *)demoFormatWithName:(NSString *)name value:(NSString *)value{
        NSString *fileName = @"template.html";
        NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:fileName];
        NSString *template = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        NSDictionary *renderObject = @{@"name":name,@"content":value};
        NSString *content = [GRMustacheTemplate renderObject:renderObject fromString:template error:nil];
        return content;
    }

    这样,我们使用GRMustache模板引擎成功完成了HTML内容的渲染工作,之后就可以通过UIWebView来加载HTML的内容了:

        _webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
        [self.view addSubview:_webView];
        
        //通得模板渲染得到内容(可以随时修改对应标签的内容)
        NSString *rendering = [self demoFormatWithName:@"标题" value:@"内容"];
        NSString *path = [[NSBundle mainBundle] bundlePath];
        NSURL *baseUrl = [NSURL fileURLWithPath:path];
        [self.webView loadHTMLString:rendering baseURL:baseUrl];

    下载GRMustache框架如下:

      

     Code:

    #import "ViewController.h"
    #import <GRMustache.h>
    
    @interface ViewController ()
    @property (strong,nonatomic)UIWebView *webView;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        _webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
        [self.view addSubview:_webView];
        
        //通得模板渲染得到内容(可以随时修改对应标签的内容)
        NSString *rendering = [self demoFormatWithName:@"标题" value:@"内容"];
        NSLog(@"
    %@",rendering);
        NSString *path = [[NSBundle mainBundle] bundlePath];
        NSURL *baseUrl = [NSURL fileURLWithPath:path];
        [self.webView loadHTMLString:rendering baseURL:baseUrl];
    }
    
    //给template.html中对应的标签格式化内容
    -(NSString *)demoFormatWithName:(NSString *)name value:(NSString *)value{
        
        NSString *fileName = @"template.html";
        NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:fileName];
        NSString *template = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        NSDictionary *renderObject = @{@"name":name,@"content":value};
        NSString *content = [GRMustacheTemplate renderObject:renderObject fromString:template error:nil];
        return content;
    }
    
    @end

    打印渲染后HTML内容如下:

    2016-12-25 15:21:42.629 JSWeb[1858:83103] 
    
    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="utf-8">
        <title>这是一个HTML测试</title>
    </head>
    <body>
        <h1> 标题 </h1>
        <p> 内容 </p>
        <img src="http://img3.redocn.com/20131012/Redocn_2013101208320171.jpg" width="256" height="128"><br><hr>
    </body>
    </html>

    webView显示渲染后的HTML内容如下: 

    GRMutstache提供的渲染HTML内容的核心类方法大概有如下这些:

    + (instancetype)templateFromString:(NSString *)templateString error:(NSError **)error;
    
    + (instancetype)templateFromResource:(NSString *)name bundle:(NSBundle *)bundle error:(NSError **)error;
    
    + (instancetype)templateFromContentsOfFile:(NSString *)path error:(NSError **)error;
    
    + (instancetype)templateFromContentsOfURL:(NSURL *)URL error:(NSError **)error;
    
    + (NSString *)renderObject:(id)object fromString:(NSString *)templateString error:(NSError **)error;
    
    + (NSString *)renderObject:(id)object fromResource:(NSString *)name bundle:(NSBundle *)bundle error:(NSError **)error;

    作者提供的示例如:

    // Renders "Hello Arthur!"
    NSString *rendering = [GRMustacheTemplate renderObject:@{ @"name": @"Arthur" } fromString:@"Hello {{name}}!" error:NULL];
    // Renders the `Profile.mustache` resource of the main bundle
    NSString *rendering = [GRMustacheTemplate renderObject:user fromResource:@"Profile" bundle:nil error:NULL];
    //Reuse templates in order to avoid parsing the same template several times:
    GRMustacheTemplate *template = [GRMustacheTemplate templateFromResource:@"Profile" bundle:nil error:nil];
    rendering = [template renderObject:arthur error:NULL];
    rendering = [template renderObject:barbara error:NULL];
    rendering = ...

    更多详情内容查看github上的源码:https://github.com/groue/GRMustache

    本文参考书籍:《iOS开发进阶--唐巧》

  • 相关阅读:
    中债登、银行间市场、上清所… 这些机构你能分清几个?
    期货界的四大天王
    心理学的几个现象
    西方金融交易员揭露行业潜规则
    瑞银保住欧股交易经纪龙头宝座 算法交易傲视同业
    【Python】 zabbixAPI的包装pyzabbix
    【Python】 日志管理logging
    【Python】 子进程创建与使用subprocess
    【Python】 配置解析ConfigParser & 命令行参数解析optparser
    【Python】 SSH连接的paramiko
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/6219656.html
Copyright © 2020-2023  润新知