GaiaX dynamic template engine is a lightweight cross-platform solution for pure native dynamic card.

Last update: Jun 20, 2022

GaiaX-logo

GaiaX dynamic template engine is a lightweight cross-platform solution for pure native dynamic card, developed by Alibaba YouKu technology team

README-en README-zh Docs-zh GitHub release License GitHub Stars GitHub Forks user repos GitHub Contributors

GaiaX dynamic template engine

GaiaX dynamic template engine is a lightweight cross-platform solution for pure native dynamic card, developed by Alibaba YouKu technology team.

Besides client SDK, we provide the template visual build tool - GaiaStudio, and Demo Project - template sample and real-time preview, which supports creating templates, editing templates, real machine debugging, and real-time preview.

GaiaX dynamic template engine aims to ensure that the native experience and performance at the same time, help the client achieve low code.

Goals

The following goals are the way forward for our project:

  • High performance
  • Cross-platform technology
  • Visual construction
  • Pure native rendering

Supported Platforms

  • Android
  • iOS

Core Concept

GaiaX-arch

The technology used

Rust/Android/Kotlin/iOS/OC/C++/JNI/CSS/FlexBox

Usage

Android

Dependency

add jitpack source:

// with setting.gradle
pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        maven { url 'https://jitpack.io' }
        mavenCentral()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        maven { url 'https://jitpack.io' }
        mavenCentral()
    }
}

// with build.gradle
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

Android-Support version:

implementation 'com.github.alibaba.GaiaX:GaiaX-Adapter:$version-support'
implementation 'com.github.alibaba.GaiaX:GaiaX:$version-support'
implementation 'com.alibaba:fastjson:1.2.76'

AndroidX version:

implementation 'com.github.alibaba.GaiaX:GaiaX-Adapter:$version'
implementation 'com.github.alibaba.GaiaX:GaiaX:$version'
implementation 'com.alibaba:fastjson:1.2.76'

Template File

// Path used to store template resources
/assets/${templateBiz}/${templateId}

Methods

// SDK usages

// Initialization - Initializes the SDK
GXTemplateEngine.instance.init(activity)

// Build template parameters - Template information
// activity       - context
// templateBiz    - template biz id
// templateId     - template id
val item = GXTemplateEngine.GXTemplateItem(activity, "templateBiz", "templateId")

// Build template parameters - Viewport size (template draw size, similar to the concept of canvas in Android)
val size = GXTemplateEngine.GXMeasureSize(100F.dpToPx(), null)

// Build template parameters - Template data
val dataJson = AssetsUtils.parseAssets(activity, "template-data.json")
val data = GXTemplateEngine.GXTemplateData(dataJson)

// Create template View - Creates a native View based on template parameters
val view = GXTemplateEngine.instance.createView(item, size)

// Bind the view data
GXTemplateEngine.instance.bindData(view, data)

// Insert the template into the container for rendering
findViewById<ViewGroup>(R.id.template_container).addView(view, 0)

iOS

CocoaPods

Add a dependency to your Podfile

// Dependency
pod 'GaiaXiOS'

Template File

Add template files to App or FrameWork

// Path used to store template resources
xxx.bundle/templateId

Methods

// SDK Usages

// Introduced header files
#import <GaiaXiOS/GaiaXiOS.h>

//register template service
[TheGXRegisterCenter registerTemplateServiceWithBizId:bizId templateBundle:@"xxx.bundle"];

// Build template parameters - Template information
// activity       - context
// templateBiz    - template biz id
// templateId     - template id
GXTemplateItem *item = [[GXTemplateItem alloc] init];
item.templateId = templateId;
item.bizId = templateBiz;

// Build template parameters - Viewport size (template draw size, similar to the concept of canvas in Android)
CGSize size = CGSizeMake(1080, NAN);

// Build template parameters - Template data
GXTemplateData *data = [[GXTemplateData alloc] init];
data.data = @{@"xxx": @"xxx"};

// Create template View - Creates a native View based on template parameters
UIView *view = [TheGXTemplateEngine creatViewByTemplateItem:item measureSize:size];

// Bind the view data
[TheGXTemplateEngine bindData:data onView:view];

// Insert the template into the container for rendering
[self.view addSubview:view];

Contributing

We very welcome your to contribute code for the project. In you before writing any code, start by creating a issue or pull request in order for us to be able to discuss details of the proposal and the rationality of the scheme. You can in the following areas contribute code:

  • Packet size
  • The run-time performance
  • Across-side consistency
  • Unit test cases
  • Document or use cases
  • And so on

Tool

Contact us

DingTalk:

WeChat:

Email: [email protected]

Supporters

Forkers repo roster for @alibaba/GaiaX

Stargazers repo roster for @alibaba/GaiaX

LICENSE

Ali-GaiaX-Project is a template dynamic develop solutions developed by Alibaba and licensed under the Apache License (Version 2.0)
This product contains various third-party components under other open source licenses. 
See the NOTICE file for more information.

GitHub

https://github.com/alibaba/GaiaX
Comments
  • 1. GaiaXAndroidDemo ScrollView 如何设置点击事件?

    demo中设置了eventListener. 模板gx-content-uper-scroll-item的databinding如下 { "data": { "cover-img": { "value": "$data.img" }, "title": { "value": "$data.title" } }, "event":{ "gx-content-uper-scroll-item":{ "type":"'tap'", "params": { "value": "'我是event'" } } } } 点击单个item无法回调onGestureEvent. 打断点可以看到gxTemplateContext.templateData?.eventListener为空。请问这个问题如何解决?

    Reviewed by Wusssy at 2022-06-08 07:56
  • 2. 数据的值是小数的时候会崩溃,整数就不会崩溃

    描述这个问题

    数据的值是小数的时候会崩溃,整数就不会崩溃

    复现步骤

    可通过分步复现该问题:

    1. gaia studio创建模版,添加子view为text类型,id为a
    2. mock数据为{"data":{"data1":1.1}}
    3. a的绑定数据为$data.data1
    4. 预览崩溃

    预期正确的结果

    预览显示1.1

    截图

    客户端 (请填写如下信息) :

    • 设备: [e.g. iPhone6]
    • 系统: [e.g. iOS8.1]
    • GaiaX SDK版本 [0.1.15]
    • GaiaX 模板文件和模板数据
    {
      "id": "test",
      "uid": "5828b7d946fb205985ca85c16de2e1dd",
      "type": "gaia-template",
      "package": {
        "id": "test",
        "version": "0.0.1",
        "modify-timestamp": "Tue Jun 14 2022 15:13:46 GMT+0800 (中国标准时间)"
      },
      "layers": [
        {
          "id": "a",
          "uid": "6127e23bcf9c932c757a2662619faf7b",
          "type": "text"
        }
      ]
    }
    

    #test {
      width: 100%;
      height: 100%;
      background-color: #ffffff;
    }
    
    #a {
      width: 100px;
      text-overflow: ellipsis;
      height: 20px;
      color: #000000;
      font-size: 15px;
    } 
    

    {
      "data": {
        "a": {
          "value": "$data.data1"
        }
      }
    }
    

    {
      "a": {
        "value": "请在这里输入文本"
      }
    }
    

    附加信息

    Reviewed by TracyWangqq at 2022-06-14 07:29
  • 3. ios pod crash, 有计划修复吗?

    1. 新建工程 ,
    2. pod 'GaiaXiOS'
    3. 更新pod
    4. 打开项目真机运行 崩溃报以下错误
    dyld: Library not loaded: @rpath/XCTest.framework/XCTest
      Referenced from: /private/var/containers/Bundle/Application/7D0527AC-DAF8-4655-BE83-0F45977564A3/TestGaiaX.app/TestGaiaX
      Reason: image not found
    dyld: launch, loading dependent libraries
    DYLD_LIBRARY_PATH=/usr/lib/system/introspection
    DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
    

    查了下, 是因为 https://github.com/CocoaPods/Specs/blob/019a3d1b3894515bd6057e56b706309338e95272/Specs/8/e/a/GaiaXiOS/0.1.0/GaiaXiOS.podspec.json 这个配置, "frameworks": "XCTest"

    XCTest不能链接到主target

    Reviewed by amjunliang at 2022-04-12 10:41
  • 4. 关于模板异步请求数据

    Hi!我们团队之前用的是 Tangram ,在其基础上扩展了卡片异步加载的功能。这个有其对应的业务场景,比如某个卡片是定位相关的,需要 App 获取定位后,根据经纬度请求额外信息,再回显到卡片上。

    参考之前的做法,我在 GXDataManager#gx_bindData:onNode: 做了简单的扩展:

    + (void)gx_bindData:(NSDictionary *)data onNode:(GXNode *)node {
        ...
        //绑定数据,重新计算布局
        if (node.isRootNode) {
            ...
            // for async load
            [self startAsyncLoadIfNeedForNode:node withOriginalData:data];
        }
    }
    
    + (void)startAsyncLoadIfNeedForNode:(GXNode *)node withOriginalData:(NSDictionary *)rawData {
        // 原数据中补充 load 字段,代表需要异步加载
        if ([rawData[@"load"] length] == 0) return;
        GXTemplateData *templateData = node.templateContext.templateData;
        // 再补充个代理方法
        if (!templateData.dataListener || ![templateData.dataListener respondsToSelector:@selector(gx_asyncLoadDataForKey:completion:)]) {
            return;
        }
        
        [templateData.dataListener gx_asyncLoadDataForKey:rawData[@"load"] completion:^(NSDictionary * _Nullable response) {
            if (response && response.count > 0) {
                NSMutableDictionary *convertedRes = [NSMutableDictionary dictionaryWithDictionary:response ?: @{}];
                // 移除load字段,避免多次触发
                [convertedRes removeObjectForKey:@"load"];
                // TODO:新旧数据合并
    
                templateData.data = [convertedRes copy];
                [self bindData:templateData onRootNode:node];
            }
        }];
    }
    

    GaiaXiOSDemoListViewController 中添加代理方法,并根据不同的 load 模拟异步请求:

    - (void)gx_asyncLoadDataForKey:(NSString *)loadKey completion:(void (^)(NSDictionary * _Nullable))completion {
        // 异步加载的卡片1
        if ([loadKey isEqualToString:@"async_load1"]) {
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    completion(@{
                        @"img": @"https://s.xiaopeng.com/xp-app/material/webp/ngp.webp",
                        @"title": @"async title",
                        @"desc": @"我是副标题",
                        @"load": @"asyn_load1"
                    });
                });
            });
        } else if ([loadKey isEqualToString:@"async_load2"]) {
            // 异步加载的卡片2
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                completion([GaiaXHelper jsonWithFileName:@"load2"]);
            });
        }
        ...
    }
    

    目前自己在 Demo 中自测正常,可以达到异步加载目的。今天刚接触这个项目,其实主要有两个疑问:

    • 后续是否考虑为模板添加异步请求的功能?
    • 我在 Demo 中尝试了支持文本自适应的模板,在异步请求中模拟了超长文本的数据,最后 bindData 时模板可以正常自适应高度。不过由于 ListViewControllercell 的高度为手动设置,这时候我没有重新设置高度的话,发现 cell 还是保持原来的高度。所以想问下,是否有比较好的方式来处理这种动态高度的场景?
    Reviewed by ljunb at 2022-06-07 08:57
  • 5. 和手淘的DinamicX很像,是借鉴的DX吗?后续是否有融合的计划?

    **描述这个问题 **

    请清晰和简明的描述这个问题。

    **复现步骤 - **

    可通过分步复现该问题:

    1. 到什么页面 '...'
    2. 点击 '....'
    3. 滑动到 '....'
    4. 产生错误

    预期正确的结果

    请清晰和简明的描述你预期正确的结果。

    截图

    如果可以的话,添加截图来帮助解释您的问题。

    客户端 (请填写如下信息) :

    • 设备: [e.g. iPhone6]
    • 系统: [e.g. iOS8.1]
    • GaiaX SDK版本 [e.g. 0.1.0]
    • GaiaX 模板文件和模板数据

    附加信息 在这里添加有关该问题的任何其他信息。

    Reviewed by Yang9322 at 2022-04-26 05:24
🤖🦀 A rust native replacement for Android's `sdkmanager`
🤖🦀 A rust native replacement for Android's `sdkmanager`

???? A rust native replacement for Android's `sdkmanager`

Apr 9, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

Jun 24, 2022
Cross-platform, cross-browser, cross-search-engine duckduckgo-like bangs

localbang Cross-platform, cross-browser, cross-search-engine duckduckgo-like bangs What are "bangs"?? Bangs are a way to define where to search inside

May 9, 2022
Blockchain Business Card v2
 Blockchain Business Card v2

This is NEAR chain dApp consisting a relatively simple smart contract written in rust and implemented with a react front end. The contract allows you to mint a business card for 5 NEAR.

Feb 8, 2022
Cross-platform tool to update DNS such as Gandi.net with your dynamic IP address

GDU | Generic DNS Update A cross-platform tool to update DNS zonefiles (such as Gandi.net) when you have a dynamic public IP address. It's a DynDNS or

Jan 20, 2022
Neutral cross-platform Rust game template

Rust Game Template Neutral cross-platform Rust game template. Build tool This project uses cargo-make task runner. It's required to build the project.

Feb 5, 2022
Rust bindings to the minimalist, native, cross-platform UI toolkit `libui`
Rust bindings to the minimalist, native, cross-platform UI toolkit `libui`

Improved User Interface A cross-platform UI toolkit for Rust based on libui iui: ui-sys: iui is a simple (about 4 kLOC of Rust), small (about 800kb, i

Jun 23, 2022
Truly cross platform, truly native. multiple backend GUI for rust
Truly cross platform, truly native. multiple backend GUI for rust

WIP: Sauron-native a rust UI library that conquers all platforms ranging from desktop to mobile devices. An attempt to create a truly native, truly cr

May 28, 2022
Cross-platform native Rust menu library

A cross-platform Rust library for managing the native operating system menus.

Jan 13, 2022
Native cross-platform full feature terminal-based sequence editor for git interactive rebase.
Native cross-platform full feature terminal-based sequence editor for git interactive rebase.

Native cross-platform full feature terminal-based sequence editor for git interactive rebase.

Jun 18, 2022
unrust - A pure rust based (webgl 2.0 / native) game engine

unrust A pure rust based (webgl 2.0 / native) game engine Current Version : 0.1.1 This project is under heavily development, all api are very unstable

Jun 20, 2022
A lightweight, cross-platform epub reader.
A lightweight, cross-platform epub reader.

Pend Pend is a program for reading EPUB files. Check out the web demo! Preview Image(s) Installation Building Pend is simple & easy. You should be abl

May 5, 2022
A lightweight cross-platform system-monitoring fltk gui application based on sysinfo
A lightweight cross-platform system-monitoring fltk gui application based on sysinfo

Sysinfo-gui A lightweight cross-platform system-monitoring fltk gui application based on sysinfo. The UI design is inspired by stacer. The svg icons a

Jun 8, 2022
Mordern Redis Cluster solution for easy operation.

Mordern Redis Cluster solution for easy operation.

Jun 15, 2022
One-Stop Solution for all boilerplate needs!
One-Stop Solution for all boilerplate needs!

One Stop Solution for all boilerplate needs! Consider leaving a ⭐ if you found the project helpful. Templa-rs Templa-rs is a one-of-a-kind TUI tool wr

Mar 12, 2022
Stylist is a CSS-in-Rust styling solution for WebAssembly Applications.

Stylist Stylist is a CSS-in-Rust styling solution for WebAssembly Applications. This is a fork of css-in-rust. Install Add the following to your Cargo

Jun 19, 2022
My solution for the advent of code 2021, mainly written in Rust

Advent-of-Code-2021 My solution for the advent of code 2021, written in Rust Error Handle NOPE!!! unwrap() everything everywhere Use To run all of the

Jan 8, 2022
Aptos-core strives towards being the safest and most scalable layer one blockchain solution.
Aptos-core strives towards being the safest and most scalable layer one blockchain solution.

Aptos-core strives towards being the safest and most scalable layer one blockchain solution. Today, this powers the Aptos Devnet, tomorrow Mainnet in order to create universal and fair access to decentralized assets for billions of people.

Jun 26, 2022
Sanzu is a graphical remote desktop solution

Sanzu Sanzu is a graphical remote desktop solution. It is composed of: a server running on Unix or Windows which can stream a X11 or a Windows GUI env

Jun 23, 2022
Cross-platform audio I/O library in pure Rust

CPAL - Cross-Platform Audio Library Low-level library for audio input and output in pure Rust. This library currently supports the following: Enumerat

Jun 26, 2022