调研: GoMobile SDK 在 iOS 与 Android 上的集成与边界

问题java

在手机应用的开发中,一般会将复杂的业务逻辑层实现放在服务端,客户端仅负责表现层。可是对于某些手机应用而言,业务逻辑的实现位于服务端反而是不安全的或是不合理的,而是须要将其逻辑直接在手机端实现。android

目的ios

面对不一样系统的手机客户端,单独重复实现相同的业务逻辑,并不是最佳实践。如何经过第三方语言 Go 语言将业务逻辑封装成库的形式,并以静态打包的方式提供给不一样系统的手机客户端使用,是本次调研的目的。git

理想目标图:github

具体调研内容包括:golang

其中关于 gRPC 在 iOS 与 Android 的实现,自己官方就已经提供了样例。本次调研会用到相关内容,因此将其做为调研的一部分记录下来,方便后来者阅读。调研中全部涉及的项目代码均存放于: grpc-apps 仓库中, 须要的朋友能够直接下载测试。sql

1. 环境安装

1.1 GoMobile 工具安装

首先保证开发环境处于"全球通"状态,保证顺利安装相关依赖包与工具。数据库

注意: GoMobile 不支持最新的 Go Module 包依赖功能,因此建议在开始本教程以前, 执行 export GO111MODULE=off 关闭 Go Module 功能。编程

经过如下命令直接源码安装swift

$: go get golang.org/x/mobile/cmd/gomobile 
$: gomobile -h
Usage:

	gomobile command [arguments]

Commands:

	bind        build a library for Android and iOS
	build       compile android APK and iOS app
	clean       remove object files and cached gomobile files
	init        build OpenAL for Android
	install     compile android APK and install on device
	version     print version
复制代码

从命令输出可以看出,gomobile 可以经过子命令build直接构建不一样系统的客户端应用,还能够经过子命令bind构建支持不一样系统的开发库。基于本次调研的目的,主要使用bind子命令生成相应平台的SDK。

1.2 iOS 工具安装

XCode 安装是必备的,请参考:iOS 应用实现 gRPC 调用

若是使用gomobile生成 iOS SDK,还须要安装Command Line Tools for XCode工具, 直接经过开发者帐号登陆苹果官网上下载.

安装完成后执行:

$: xcode-select -s /Applications/Xcode.app/
复制代码

1.3 Android 工具安装

Android Studio 安装是必备的,请参考:Android 应用实现 gRPC 调用

若是使用gomobile生成 Android SDK,还须要安装 Android NDK 环境。未安装时会报如下错误:

$: gomobile bind -target=android github.com/liujianping/golib
gomobile: no Android NDK found in $ANDROID_HOME/ndk-bundle nor in $ANDROID_NDK_HOME
复制代码

打开 Android Studio,进入Tools > Android > SDK Manager 勾选安装:

  • LLDB
  • CMAKE
  • NDK

过程有点慢,耐心等待。完成安装后,设置环境变量便可。

export ANDROID_HOME=~/Library/Android/sdk/
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle
复制代码

2. Go SDK 样例实现

在官方的GoMobile/Wiki上,安装包内就已经提供了最简单的样例代码了,能够直接使用。由于是现成的代码,缺乏过程,因此这里仍是从头开始建立,记录过程。

2.1 Golib 实现

首先建立一个新的本地 Go 项目:Golib, 具体代码放在Golib中。

$: mkdir -p $GOPATH/src/github.com/liujianping/golib
$: cd $GOPATH/src/github.com/liujianping/golib
$: cat <<EOF > golib.go
package golib

import (
	"errors"
	"fmt"
)

func Greetings(name string) string {
	return fmt.Sprintf("Hello, %s!", name)
}

func NumberError(num int) (int, error) {
	if num >= 10 {
		return 0, errors.New("num > 10")
	}
	return num, nil
}
EOF

复制代码

这个样例程序比官方的多了一个函数NumberError实现。由于真实项目必定会存在异常处理,因此增长这个函数顺便调研一下。

若是前一节的环境所有都安装成功的话,如今咱们就能够生成相应平台的SDK了。

2.2 生成 iOS SDK

生成 iOS SDK 过程很简单:

$: gomobile bind -target=ios github.com/liujianping/golib
$: ls
Golib.framework  golib.go  
复制代码

完成命令后,在当前目录下就生成了Golib.framework的目录,固然也能够经过指定-o设置输出路径。

2.3 生成 Andorid SDK

Android SDK 的生成过程,一样很简单:

$: gomobile bind -target=android github.com/liujianping/golib
$: ls
golib-sources.jar  golib.aar  Golib.framework  golib.go  
复制代码

不一样的是,android 平台生成的是 jararr 两个包。具体 jararr 包的区别,贴下 google 的结果:

The main difference between a Jar and a AAR is that AARs include resources such as layouts, drawables etc. This makes it a lot easier to create self-contained visual components.

3. GoMobile SDK 的集成

3.1 在 iOS 上集成

打开iOS 应用实现 gRPC 调用中建立的项目,将Golib.framework拖拽到项目中。

打开ViewController.swift文件:

import UIKit
import Golib


class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        // gRPC client
        ...
        
        // golib
        let reply = GolibGreetings("JayL")
        print("golib reply: \(reply)")

        // golib error
        var err1: NSError?
        var num: Int = 0
        GolibNumberError(11, &num, &err1)
        print("golib num: \(num), err: \(err1)")
    }

}
复制代码

从新编译并执行测试项目,在控制台输出得出预期结果。完成 iOS 上集成 GoMobile SDK的集成。

3.2 在 Android 上集成

在 Android 上集成没有 iOS 上拖拽那么简单, 能够按如下步骤经过新建一个新Module的方式将 Golib SDK 导入到项目中。

打开Android 应用实现 gRPC 调用中建立的项目,执行 File -> New -> NewModule菜单建立一个新的 Module golib。再打开 Module: appGradle文件,引入 Module: golib, 即增长项目依赖: implementation project(":golib")。以下图:

完成上面步骤,就能够在代码中引用该 SDK 了。 打开主实现 java 文件:

String goLib_hello = Golib.greetings("GoLib Hello");
	Log.i("golib", goLib_hello);

	try {
		long l = Golib.numberError(11);
		Log.i("golib", Long.toString(l));
	}
	catch (Exception e) {
		Log.e("golib", e.getMessage());
	}
复制代码

设置不一样的Golib.numberError(11)输入参数,查看控制台的输出状况。完成 Android 上集成 GoMobile SDK的集成。

4. GoMobile SDK 功能边界

完成了 GoMobile SDK 的集成工做, 如今看看它能作什么。

4.1 日志打印

在 GoMobile SDK 上的日志输出是否能够正常的在 iOS 与 Android 平台正常输出,不妨在 Golib 的实现上增长 log.Println 输出。

经过验证,GoMobile SDK 上的日志输出在 iOS 与 Android 上能够正常输出。有了日志输出就能够很是方便的调试 GoMobile SDK 的具体功能了。

4.2 文件系统

不一样的手机系统平台,第三方应用的文件目录存储路径不同的。因此,具体路径仍是让上层调用代码做为参数传入比较合理。

在 golib 实现库中增长目录枚举函数,并增长日志:

package golib

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
)

func WalkDirectory(path string) error {
	return filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			log.Println("walk fn failed: ", err)
			return err
		}
		log.Printf("walked file or dir: %q\n", path)
		return nil
	})
}
复制代码

从新编译生成对应平台的SDK,再集成测试。

4.3 数据存储

大部分手机应用的本地数据存储都会使用sqlite做为数据库存储。因此就sqlite再GoMobile SDK 中的实现进行调研。

$: get get github.com/mattn/go-sqlite3
复制代码

能够直接取github.com/mattn/go-sqlite3仓库中的样例代码进行实验。具体代码请参考:golib/sqlite.go

编译从新集成测试可知,在 GoMobile SDK在 iOS/Android实现 sqlite 的功能可行。

4.4 网络操做

网络操做是最不须要验证的功能了,SDK 中彻底能够将手机应用的网络操做所有封装到其中。

小结

本文仅仅是对 GoMobile SDK 在集成与边界的简单验证,提供一套解决手机应用混合编程的新思路。虽然可以完成本次调研的预期目的,可是若是须要用于生产环境中,请进行更多的功能验证。

相关文章
相关标签/搜索