使用 Gomobile 库就能够利用 Go 语言开发移动应用或者封装一个原生依赖库,Gomobile 代码仓库:https://github.com/golang/mobile
这篇博客中,我将记录一下这两天在使用过程中遇到的一些坑和总结一下使用经验。
我将利用 Gomobile 封装一个依赖库实现通过 swift 调用 Go 写的函数,以及 swift 实现 Go 定义的接口。
在开始之前你可能需要先了解 Go 基础语法,安装 Xcode 以及 IOS 开发环境,安装 Gomobile 工具。
大部分情况我们将偏向 Swift 利用调用 Go 语言实现相关功能,所以我会先讲一下在 Swift 中怎么调用 Go 构造函数创建 Go struct 实例,然后就是了解一下如何在 Go 中定义需要 Swift 实现的接口。
创建项目结构
我创建了一个简单的项目结构,包含一个 example 文件夹(待会我将会创建一个 IOS App 项目用于演示调用 Library,该文件夹还可以包含 Android 的演示项目),src 文件夹(该文件夹将包含 Go 语言项目代码),以及顶层的 go.mod 和 README.md 等文件。
接着我将创建 src/support.go 文件
/*
* @Author: Bin
* @Date: 2022-07-20
* @FilePath: /goMobileDemoApp/src/support.go
*/
package support
import "fmt"
type Support struct {
}
func NewSupport() *Support {
return &Support{}
}
func (s *Support) Echo() *Support {
fmt.Println("Init Support Library")
return s
}
以上代码中,声明了一个 Support
的结构,并且有一个 NewSupport
构造函数用于实例化 Support
结构体,Support
拥有一个 Echo
函数,调用 Echo
函数将会简单的输出一句 Init Support Library
创建 IOS 项目
利用 Xcode 创建一个 IOS Swift 项目到 example 文件夹中。
选择 IOS App 模版
输入你的项目名称,开发语言选择 Swift 就好了。
创建好 App 之后我们的项目文件结构大致如下:
为了方便管理依赖库,我们可以在 ios app 项目中创建一个 frameworks
文件夹,之后将依赖包就统一放到该文件夹下面
编译 xcframework IOS 依赖文件
项目准备好之后,回到项目根目录利用 gomobile 可以将 support.go 编译为 IOS 的 xcframework 依赖文件,打开终端执行编译命令
gomobile bind -target ios -o ./libs/GoMobileDemoApp.xcframework ./src/
编译成功后,就能看到项目下出现了一个 libs 文件夹,将文件夹下的 GoMobileDemoApp.xcframework 导入到 IOS 项目中
然后在 ViewController.swift 代码中导入 import GoMobileDemoApp
//
// ViewController.swift
// goMobileDemo01
//
// Created by Bin on 2022/7/20.
//
import UIKit
import GoMobileDemoApp
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let su = SupportNewSupport()
su!.echo()
}
}
导入 GoMobileDemoApp
包之后,调用 SupportNewSupport()
构造函数,就能实例化一个 Support
结构体,即可调用结构体的 echo()
函数
编译运行 App 后就能看到输出成功了。
如果 import GoMobileDemoApp
显示找不到的报错,可以先检查一下 GoMobileDemoApp.xcframework 包是否导入成功。如果是能够编译通过,但是编辑器提示 No such module 'GoMobileDemoApp'
可以尝试添加 frameworks 目录到项目 Build Settings 配置选项 "Framework Search Path" 中即可解决编辑器提示包不存在问题。
Swift 实现 Go 的接口(传参以及回调)
接下来扩展一下 Support
结构体,我在 support.go
中增加了一个接口声明 SupportObserve
其中需要实现一个 OnCallback
函数,在 Support
结构体上新增两个函数 Call
和 SetObserve
,用于模拟传参后请求以及设置监听回调。
/*
* @Author: Bin
* @Date: 2022-07-20
* @FilePath: /goMobileDemoApp/src/support.go
*/
package support
import "fmt"
type SupportObserve interface {
OnCallback(code int, msg string)
}
type Support struct {
observe SupportObserve
}
func NewSupport() *Support {
return &Support{}
}
func (s *Support) Echo() *Support {
fmt.Println("Init Support Library")
return s
}
func (s *Support) Call(name string) *Support {
// TODO: Implement function
if name == "" {
s.observe.OnCallback(404, "")
return s
}
s.observe.OnCallback(200, "Hello "+name)
return s
}
func (s *Support) SetObserve(o SupportObserve) *Support {
s.observe = o
return s
}
编译后将新的 xcframework 包替换 IOS App 项目 frameworks 文件夹中的旧依赖库文件,接下来我们使用 swift 实现定义的 SupportObserve ,首先在 IOS App 项目中创建一个 SwiftSupportObserve.swift 类。
创建成功后在 SwiftSupportObserve 中实现 SupportObserve 接口
//
// SwiftSupportObserve.swift
// goMobileDemo01
//
// Created by Bin on 2022/7/20.
//
import UIKit
import GoMobileDemoApp
class SwiftSupportObserve: NSObject, SupportSupportObserveProtocol {
func onCallback(_ code: Int, msg: String?) {
NSLog("callback code is \(code) msg is \(msg)")
}
}
和之前调用函数一样,首先需要导入 GoMobileDemoApp
包,然后使 SwiftSupportObserve
类实现 SupportSupportObserveProtocol
并需要实现 onCallback
方法,在方法中我只是简单的打印了 code 和 msg,如果有具体的回调业务逻辑将在这里实现。
SupportSupportObserveProtocol
是 Gomobile 的编译命名规范,这里采用 包名 + 接口名 + Protocol
生成具体接口命名。
接下来,在 ViewController
的 viewDidLoad
生命周期中调用 Support
的 setObserve
设置回调接口,并调用 call
触发回调试试。
//
// ViewController.swift
// goMobileDemo01
//
// Created by Bin on 2022/7/20.
//
import UIKit
import GoMobileDemoApp
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let su = SupportNewSupport()
su?.echo()
let ob = SwiftSupportObserve()
su?.setObserve(ob)
su?.call("bin")
}
}
最后编译运行 IOS App,我们就能在控制台看到输出没有问题。
到这里基本上能够实现利用 Golang 封装一个依赖库并且与 Swift 进行交互。
以上代码已经发布到 Github,如果帮助到你了可以点亮 Star 鼓励一下我: https://github.com/PBK-B/gomobile-library-tmp-examples
有问题可以回复到我博客 https://bin.zmide.com/?p=1047
参考链接:
Gomobile Code Warehouse: https://github.com/golang/mobile
Calling Go code from Swift on iOS and vice versa with Gomobile: https://medium.com/@matryer/tutorial-calling-go-code-from-swift-on-ios-and-vice-versa-with-gomobile-7925620c17a4
Gomobile Documentation: https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile
import GoogleMobileAds No such module 'GoogleMobileAds ': https://stackoverflow.com/questions/39347291/import-googlemobileads-no-such-module-googlemobileads