今天早上爆出,许多 iOS APP 在提交审核的时候未通过,或者是收到警告,其原因是违反了 section 3.3.2 中的规定。

高潮来了,像 JSpatch 这种方案已经确定使用,同时躺枪的还有 React Native 以及 Weex。

然后,就出现了这一幕:

言归正传,是从周边朋友那里了解下来,纯 React Native 的应用也没有收到类似的警告邮件,Weex Playground 也没有收到类似邮件。

在正式公告出来之前,我们还是拭目以待吧。

所以,这篇文章还是要整理滴,在 Weex 中如果需要用到图标,改如何处理,有哪些姿势?

背景

APP 中使用图标是非常常见的需求了。例如:

如果是在 Native 开发流程中,这不难解决,可以直接用本地图片资源(包括本地文件系统中,或者是打包在APP内部的资源文建),还可以根据手机分辨率不同使用不同规格的图片资源。

对于 Weex 该如何处理呢 ?

先看一下官网提供的姿势。

正常的话,图标是一个 <image> 标签,例如:

1
<img style="width: 560;height: 560;" src="https://img.alicdn.com/tps/TB1z.55OFXXXXcLXXXXXXXXXXXX-560-560.jpg"></img>

src 指定了图标的 URI。

下面总结一下图标 URI 都有哪些。

姿势探讨

URI 主要 主要参考了官网 Path 部分

http or https

它的工作方式与 web 相同,Weex 一直支持这种方式。

如下代码中 src 部分指定的就是图片的 URI。

1
<img style="width: 560;height: 560;" src="https://img.alicdn.com/tps/TB1z.55OFXXXXcLXXXXXXXXXXXX-560-560.jpg"></img>

local

Weex SDK 提供 local scheme 来访问打包在应用程序中的资源,此 scheme 无法在 H5 环境下使用。目前,开发者可以在 image 组件和字体文件中使用本地资源。

custom

还有一种方式是自定义 Scheme。

集成 Weex 到已有项目中的文档 中提供了 ImageAdapter 供开发者自定义:

1
package com.weex.sample;
import android.widget.ImageView;
import com.taobao.weex.adapter.IWXImgLoaderAdapter;
import com.taobao.weex.common.WXImageStrategy;
import com.taobao.weex.dom.WXImageQuality;

public class ImageAdapter implements IWXImgLoaderAdapter {
  @Override
  public void setImage(String url, ImageView view, WXImageQuality quality, WXImageStrategy strategy) {
    //实现你自己的图片下载,否则图片无法显示。
    //!! 这里的 url 就是 <image> 标签的 src 属性
  }
}

注意代码中的 String url 参数,这里可以自定义 Scheme,例如 对于 fs://data/data/imgCache/test.png 格式的 Scheme 就从本地的文件系统加载图片,对于 http 或者 https 开头的 Scheme 则从网络上下载。

通过自定义 Scheme ,基本上可以满足大部分需求。

base64

Web 开发中经常会对图片文件做 Base64 编码作为字符串在网络上传播,并且这种格式 img 标签是支持的。

但是 Weex 的 demo 代码中是这样子写的:

官方文档从未提及可以通过 Base64 编码格式显示图片,但是 demo 的代码中却明明写了,注意红色方框的内容(其中有一处 typo,Depending 而非 Depanding, am I right?)。

那如何自持呢?

仍然以安卓为例,找到 ImageAdapter 初始化部分:

Playground 默认初始化的是第二个 ImageAdapter,这个 ImageAdapter 的内容如下:

看可以看到最终使用了 Picasso 来 load image,而 Picasso 默认不支持 Base64 编码,这就是为什么 demo 里隐晦的注释需要客户端 SDK 的支持的原因了。

最简单的解决方法就是在初始化 ImageAdapter 处使用 第一个 FrescoImageAdapter,Fresco 默认支持 Base64 编码。

当然客户端不一定要使用 Fresco,对于其他的方式,只要在自己的 ImageAdapter 解析 Base64 to Bitmap 就 OK。

ttf 字体文件

这种姿势也可以显示图标,但是放在这里可能不太妥当,因为不是通过 <image> 标签来实现的。这种实现方案跟 Web 的字体是一致的, 但是使用的是 <text> 标签。

首先需要去 iconfont 选择图标,然后添加到项目里:

然后记下 .ttf 字体文件的 CDN 地址。

在我们的项目中做如下处理:

首先在第 32 行添加规则。

接下来就可以像如下代码使用字体显示图标了,可以修改大小和字体颜色。

1
<text class="icon" :style="{fontFamily: 'iconfont', color: 'red'}" >&#xe61e;</text>

    <text class="icon" :style="{fontFamily: 'iconfont', marginTop: 20}" >&#xe6

显示效果如下:

对比

上一部分总结了在 Weex 中显示图标的四种姿势(如果有其他更好的方案或者姿势,求分享),下面总结下各种这四种方案的优缺点。

使用 http or https 会有网络延时,第一次页面渲染的时候需要网络获取图片,再次渲染的时候,会有缓存机制,但是图标和图片不一样,如果初次不能及时渲染,影响体验。

对于 local 这种方案可以避免网络延时和消耗,但是需要在 APP 内置资源文件,并且 local 不支持 H5,如果使用 playground 来测试的话,同样不能显示(playground 未内置我们需要的图标资源)。

对于自定义 Scheme 的方案,可行,但是需要定制 ImageAdapter,同样也不兼容 H5 和 playground。

对于 Base64 的方式,需要定制 ImageAdapter,虽然有成本,但是可以兼容 H5,如果自己打包 playground 内置支持,调试的时候也会方便很多,除此之外,webpack 可以通过 url-loader 配置项目资源

这样就可以将图片作为 js module 引入进来:

所以下面的写法就很方便了:

1
<image :src="Images" :style="{width: 300, height: 200}"></image>

看,跟 Web 开发并无二致。

当然不要忘记 npm i url-loader --saveDev

最后的一种方案是字体文件,这种方案可以同时兼容 H5 和 Weex , playground 也不需要做任何修改,还能自持颜色和大小调整,但是我们也可以看到,这种写法不太友好,字体文件这部分有更好的解决方法欢迎分享出来。

总结

以上。该总结的都总结了,希望 Weex 不会被 Apple 给禁用掉吧!God Bless Weex!


接下来的安排看明天的心情了!