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

深入折腾了一下 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 交互方面提供更多有用的方法。

时间: 2024-07-31 23:35:21

深入折腾 Weex,知乎日报客户端开发的相关文章

微信小程序版的知乎日报开发实例_相关技巧

先看看效果图 开发环境准备 小程序 出来第二天就被破解,第三天微信就把开发工具开发下载了, 现在只需要下载 微信开发者工具 就可以使用了, 创建项目的时候,要选择无 appid, 这样就不会有 appid 的验证了. 目录结构      1.app.js 注册app逻辑, app.wxss 全局样式文件 app.json 配置信息      2.pages 存放页面文件      3.utils 工具类代码      4.images 图片资源文件 小程序中每一个页面都会有三个文件 .wxml

Python采用Django制作简易的知乎日报API_python

现在我主要教大家如何去实战,做一个简易的知乎日报API 首先你要熟悉django的基本用法,会写模型,会写视图函数,会配置url. 1.配置字符编码 因为我们等一下要使用中文,所以要先设好字符编码 在settings.py里将LANGUAGE_CODE设为'zh-CN' 然后添加这两行 FILE_CHARSET='utf-8' DEFAULT_CHARSET='utf-8' 还要进入到数据库 依次输入 set character_set_client=utf8 ; set character_s

C# 海康DVR客户端开发系列(3)—— 连接DVR和图像预览

前言 一直没有稳定的DVS供我测试用,朋友那边也是频频宕掉,所以延误至今,所幸还是出来了.此外非常遗憾的是没能用WPF实践成功,关键是IntPtr句柄设置不对,没法显示出来,为了保证进度也只好暂时放弃用WPF做显示.   提醒 欢迎转载,但请保留博客园(www.cnblogs.com).农民伯伯(over140.cnblogs.com)的出处,谢谢合作:) 系列 1. C# 海康DVR客户端开发系列(1)-- 准备 2. C# 海康DVR客户端开发系列(2)-- 封装API  3. C# 海康D

应用-IPTV客户端开发需要的技术

问题描述 IPTV客户端开发需要的技术 大家好,有人知道iptv的开发需要什么技术吗.像是普通安卓系统中运行的apk或者是其他的web版应用是否可以在iptv机顶盒上运行,求解答.灰常感谢 解决方案 在iptv机顶盒上运行基本上是不可能的,需要开发.具体要看iptv的方案而定! 解决方案二: 客户端开发的话,现在一般都是安卓的系统,可以开发web应用和安卓原生应用.但是需要根据IPTV服务端的技术做链路和接口对接.

知乎iOS客户端下午瘫了 原来是第三方防火墙变更害的

9月7日消息,下午有iOS知乎用户发现知乎服务器出现故障,知乎iOS客户端暂时不能登录.此外,有消息称知乎登录端口出现混乱,登录后提示出现"503"错误,更有网友反映登录之后账号串号. 对此,知乎发布晚些时候发公告称,是知乎所使用的第三方防火墙产品内部变更导致了移动端发生故障. 知乎方面表示,今日下午14 点 05 分知乎部分地区用户在使用知乎客户端时确实遇到"登录帐号串号"的情况(后经确认属于数据展示错乱).随后工程师团队迅速进行了故障筛查.同时,为避免后续较大范

【Parallax Animation】实现知乎 Android 客户端启动页视差滚动效果

欢迎转载,但请务必注明出处!http://ryanhoo.github.io/blog/2014/07/16/step-by-step-implement-parallax-animation-for-splash-screen-of-zhihu/ 前言 Parallax Scrolling(视差滚动),是一种常见的动画效果.视差一词来源于天文学,但在日常生活中也有它的身影.在疾驰的动车上看风景时,会发现越是离得近的,相对运动速度越快,而远处的山川河流只是缓慢的移动着,这就是最常见的视差效果.视

阿里宣布开源Weex,用Web方式开发Native性能体验应用

4月21日,北京 - 阿里巴巴今天在Qcon大会上宣布跨平台移动开发工具Weex开放内测邀请.Weex能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出Native级别的性能体验,并支持iOS.安卓.YunOS及Web等多端部署.   对于移动开发者来说,Weex主要解决了频繁发版和多端研发两大痛点,同时解决了前端语言性能差和显示效果受限的问题.开发者可通过Weex官网申请内测.(http://alibaba.github.io/weex/)   开发者只需要在自己的APP中嵌入Wee

socket-android 客户端开发好之后下载到手机上,ip 和 端口应该怎么设置才能连接到我的电脑(服务器)

问题描述 android 客户端开发好之后下载到手机上,ip 和 端口应该怎么设置才能连接到我的电脑(服务器) android 客户端开发好之后下载到手机上,ip 和 端口应该怎么设置才能连接到我的电脑(服务器) 解决方案 HTTP请求的地址改为你的ip和端口就可以了.例如:http://192.168.1.29:80/api.php?device=1111

access-新浪微博客户端开发初期遇到的问题

问题描述 新浪微博客户端开发初期遇到的问题 新手刚刚接触android开发,做一个新浪微博客户端的开发,在OAuth2.0认证中知道有这四组关键数据 第一组:(App Key和App Secret) 第二组:(Request Token和Request Secret) 第三组:(oauth_verifier) 第四组:(user_id.Access Token和Access Secret) 百度了一些资料知道认证过程中这四组数据的传递,但是始终搞不明白这些 RequestTokenRequest