深入折腾 Weex,知乎日报客户端开发

简介: 深入折腾了一下 Weex,做了一个知乎日报的客户端,同时实现了一种目前 Weex 尚未提供的 Native 页面切换思路。
深入折腾了一下 Weex,做了一个知乎日报的客户端,同时实现了一种目前 Weex 尚未提供的 Native 页面切换思路。

最后效果如下:



这个 demo 主要实践 4 件事情:

1. 模块注册
2. 组件注册
2. Native 方法调用
4. Native 页面切换 & 参数传递

整个 app 只有两个页面,都是纯 Weex 编写的,对于第一个页面非常的简单,布局类似于 iOS 的 TableView
<template>
  <scroller>
    <container repeat="{{list}}" news_id="{{news_id}}" onclick="onclick">
      <container class="cell">
        <image class="thumb" src="{{src}}"></image>
        <text class="title">{{title}}</text>
      </container>
      <text class="separator"></text>
    </container>
  </scroller>
</template>

然后我们使用 this.$sendHttp 发起 http 请求,这里知道,Weex 仅仅是一个渲染引擎,对于 http 请求,mtop 请求,甚至图片加载等功能,是需要业务注入实现类的。比如 WeexDemo 里面的 sendHttp 就是注入了 WXStreamModule 模块,然后在实现里面使用了 NSURLConnection,这个设计非常不错,在具体的业务当中,你可以把实现代码替换成任何你想要的 HTTP 库。

[WXSDKEngine registerModule:@"image" withClass:[WXImageModule class]];
[WXSDKEngine registerModule:@"stream" withClass:[WXStreamModule class]];
[WXSDKEngine registerModule:@"event" withClass:[WXEventModule class]];

这就是 Weex 注册模块的原理,其中图片模块是用 SDWebImage 实现的。我们同样也可以将其他的 Native 方法注册到模块里面,例如:

WX_EXPORT_METHOD(@selector(log:));

- (void)log:(NSString *)text {
    NSLog(@"LOG: %@", text);
}

然后在 JavaScript 代码里面只需要用 this.$call("event", "log", "Hello, World!"); 就能在 Native 里面输出 Hello World! 这提供了强大的扩展能力。

首页的展示是较为简单的,用的是 Weex 自带的 ImageText,但是详情页是一个 Web 页面,貌似我还没找到 Weex 提供的 WebView 渲染组件。(但是奇怪的是,我自建 WXWebViewComponent 的时候提示 Duplicated Symbol,难道是还未实现么),所以我们需要自建一个 WXComponent,用于 WebView 渲染。

当然我们也可以使用 Native 代码打开一个 WebView,不过这样显然不如纯 Weex 实现有趣。

#import "WXHtmlNodeComponent.h"
#import <WebKit/WebKit.h>

@interface WXHtmlNodeComponent()

@property (nonatomic, strong) NSString *URL;
@property (nonatomic, strong) NSString *html;
@property (nonatomic, strong) WKWebView *webView;

@end

@implementation WXHtmlNodeComponent

WX_CUSTOM_ATTRIBUTE(url, URL, NSString)
WX_CUSTOM_ATTRIBUTE(html, html, NSString)

+ (Class)viewClass {
    return [WKWebView class];
}

- (void)applyPropertiesToView:(UIView *)view {
    [super applyPropertiesToView:view];
    WKWebView *webView = (WKWebView *)view;
    if (self.html.length > 0) {
        [webView loadHTMLString:self.html baseURL:nil];
    } else if (self.URL.length > 0) {
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.URL]]];
    }
}

这个 Component 支持 urlhtml 两种 attribute,意味着可以从 url 或者 html 代码渲染他。我们把它注册到 webnode 这个名字上面,就能在详情页使用它了:

<template>
  <container>
    <WebNode url="{{context.url}}" class="webnode"></WebNode>
  </container>
</template>

<script>
  module.exports = {
    data: {
      context: "{{context}}"
    }
  }
</script>

<style>
  .webnode {
    height: 1222;
    flex: 1;
  }
</style>

然后最最关键的事情来了,当用户点击一行的时候,我们要从首页跳到详情页,而这两个页面都是 Weex 的(目前貌似 Weex 没有提供这样的能力)。

但是没有关系,我们有 Module,这里我实现了一套逻辑,包括了本地页面 Push 和 Weex 页面上下文传递逻辑。
- (void)push:(NSDictionary *)params {
    ViewController *controller = [[ViewController alloc] init];
    controller.URL = [NSURL URLWithString:params[@"url"]];
    controller.context = params[@"context"];
    UINavigationController *navigator = [(AppDelegate *)[[UIApplication sharedApplication] delegate] navigator];
    [navigator pushViewController:controller animated:YES];
}

然后在首页 onclick 的时候,只要把 context 带到 Module 里面的 push 方法,往下透传过下一个 Weex 页面,就能完成下个页面的初始化。

onclick: function(e) {
  var news_id = e.target.attr["news_id"];
  var context = this;
  var api = this.api(news_id);
  this.get(api, function(json) {
    var params = {
      url: "next weex url",
      context: {
        url: json.share_url,
        title: json.title
      }
    };
    context.$call("event", "push", params);
  });
}

具体来说,这里面使用了一个数据绑定上面的技巧,我把 weex 页面上的 data 字段放置了一个 "{{context}}"

<script>
  module.exports = {
    data: {
      context: "{{context}}"
    }
  }
</script>

这是一个占位符,会在 Native Code 里面被 Push 传进来的 context 替换(这是一个 NSDictionary),处理的过程只是做一次字符串替换

#import "WXHelper.h"
#import "JSONHelper.h"

@implementation WXHelper

+ (NSString *)scriptWithURL:(NSURL *)URL context:(NSDictionary *)context {
    
    NSString *script = [[NSString alloc] initWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:nil];
    
    if (context == nil || ![context isKindOfClass:[NSDictionary class]]) {
        return script;
    }
    
    return [script stringByReplacingOccurrencesOfString:@"\"{{context}}\""
                                             withString:JSONStringWithObject(context) ?: @""];
}

@end

然后我们的上下文就会被绑定到下一个 weex 页面,其实根据这个思路,我们可以做更多的 Weex 和本地的交互,甚至把它做成 Framework 方便使用。

整个流程如下:

首页 weex 渲染 --> onclick --> module 传递上下文到下一个 weex --> weex 自定义组件 WebView 渲染

以上就是整个 demo 的完整思路。

最后

Weex 的模块注册、组件注册非常的有用,给业务扩展自己的能力,自定义自己的功能提供了强大的基础。
当然也希望 Weex 可以在 Native 交互方面提供更多有用的方法。

目录
相关文章
|
8月前
|
人工智能 安全 搜索推荐
钉钉发布全球首个工作智能操作系统Agent OS,专为AI打造
AI钉钉1.1版本名为“木兰”,距离钉钉发布AI钉钉1.0版本“蕨”不到四个月。“蕨象征着破土,木兰是破土后的初生。”钉钉创始人、CEO陈航(花名:无招)说,“未来,钉钉上所有AI Agent都基于Agent OS搭建和运行,让AI直连物理世界。”
571 1
|
9月前
|
SQL 自然语言处理 BI
另辟蹊径的 Text2SQL,不用大模型也能搞 chatBI
润乾报表NLQ组件摒弃大模型路线,采用规则词典与领域知识库,将自然语言精准转化为MQL查询语言,实现稳定、低成本、可维护的ChatBI。其核心在于结构化语义解析,避免“幻觉”,支持复杂多表关联与计算,适用于企业级BI场景,是可靠高效的自然语言查询解决方案。
|
8月前
|
人工智能 自然语言处理 算法
2025年 GEO行业年度鸟瞰全景报告:商业化深耕期的全球竞合与企业适配指南
2025年,中国生成式AI搜索(GEO)市场规模突破480亿元,年增68%。技术成熟与企业需求推动商业化爆发,多模态检索、垂直领域适配成主流。头部效应显著,国内外巨头竞逐本土化与全球化赛道,中小企业迎来轻量化机遇。
|
机器学习/深度学习 测试技术 计算机视觉
RT-DETR改进策略【Conv和Transformer】| ICCV-2023 iRMB 倒置残差移动块 轻量化的注意力模块
RT-DETR改进策略【Conv和Transformer】| ICCV-2023 iRMB 倒置残差移动块 轻量化的注意力模块
492 14
RT-DETR改进策略【Conv和Transformer】| ICCV-2023 iRMB 倒置残差移动块 轻量化的注意力模块
|
安全 关系型数据库 文件存储
Websoft9 服务器面板中 Odoo 安装与群晖 NAS 的对比
传统部署Odoo面临基础设施搭建、镜像供应链、复杂配置及运维监控四大难题,而群晖NAS方案存在Docker依赖、插件更新滞后和配置自由度低的局限。Websoft9提供开箱即用的解决方案:无需预装Docker,三键式安装支持全版本Odoo;具备企业级扩展功能如负载均衡与集群部署;兼容混合云架构,支持公有云、私有云及边缘设备管理;同时确保合规性,自动扫描漏洞并生成修复报告,大幅提升部署效率与系统安全性。
List并发线程安全问题
【10月更文挑战第21天】`List` 并发线程安全问题是多线程编程中一个非常重要的问题,需要我们认真对待和处理。只有通过不断地学习和实践,我们才能更好地掌握多线程编程的技巧和方法,提高程序的性能和稳定性。
871 59
|
缓存 网络协议 前端开发
Web 性能优化|了解 HTTP 协议后才能理解的预加载
本文旨在探讨和分享多种预加载技术及其在提升网站性能、优化用户体验方面的应用。
Web 性能优化|了解 HTTP 协议后才能理解的预加载
|
机器学习/深度学习 PyTorch API
优化注意力层提升 Transformer 模型效率:通过改进注意力机制降低机器学习成本
Transformer架构自2017年被Vaswani等人提出以来,凭借其核心的注意力机制,已成为AI领域的重大突破。该机制允许模型根据任务需求灵活聚焦于输入的不同部分,极大地增强了对复杂语言和结构的理解能力。起初主要应用于自然语言处理,Transformer迅速扩展至语音识别、计算机视觉等多领域,展现出强大的跨学科应用潜力。然而,随着模型规模的增长,注意力层的高计算复杂度成为发展瓶颈。为此,本文探讨了在PyTorch生态系统中优化注意力层的各种技术,
1199 6
优化注意力层提升 Transformer 模型效率:通过改进注意力机制降低机器学习成本
|
人工智能 算法 搜索推荐
云端问道11期方案教学-创建专属AI助手-阿里云百炼产品能力分享
阿里云百炼产品能力分享旨在帮助用户深入了解百炼的核心功能,并快速将大模型与系统结合。主要内容包括:1. 百炼的产品定位和能力简介,涵盖模型推理、应用搭建等;2. 知识检索RAG智能体的应用能力和优势,介绍其高效构建知识库的步骤及常见问题;3. 最佳落地案例实践,如宠物行业AI助手和产业分析类互联网企业的Copilot机器人。通过这些内容,用户可以全面掌握百炼在实际业务中的应用方法和效果。
705 0
|
存储 固态存储 Windows