使用 Golang 和 HTML5 开发一个 MacOS App

简介: 本篇文章将介绍如何使用 Go 语言 和 HTML5 来开发一个 MacOS App。

前言

Go语言(也称为Golang)是 google 在 2009 年推出的一种编译型编程语言。相对于其他编程语言,golang 具有编写并发程序或网络交互简单、数据类型丰富、编译速度快等特点,比较适合于高性能、高并发场景。Go 语言一直在网络编程、云平台开发、分布式系统等领域占据着重要的地位,尤其在云原生领域,杀手级项目 Docker 和 Kubernetes 都是采用 Go 语言开发的。而在其他领域,比如桌面应用开发,也有一些框架可以使用,本篇文章就来介绍如何使用 Go 语言 和 HTML5 来开发一个 MacOS App。

框架选择

这里我选用了 echo 作为 web 框架,当然也可以选择其他的 web 框架,选择 echo 只不过因为其比较轻量。要做桌面应用,还需要一个 GUI 框架来构建应用,这里我选择的是 Lorca,使用 Lorca 可以用 Go 编写 HTML5 桌面程序,依赖 Chrome 进行 UI 渲染,但却不需要把 Chrome 打包到应用中,也就是说使用应用的电脑,需要安装 Chrome。

lorca

echo 的使用方式中规中矩,没有什么需要介绍的。这里简要介绍一下 lorca,其的使用方法和原理都很简单,可以将其看做是一个浏览器,可在其上运行 web 应用,lorca 可直接将 web 应用包装成桌面应用。这里提供一个简单的示例:

ui, _ := lorca.New("", "", 480, 320)
defer ui.Close()

// Bind Go function to be available in JS. Go function may be long-running and
// blocking - in JS it's represented with a Promise.
ui.Bind("add", func(a, b int) int { return a + b })

// Call JS function from Go. Functions may be asynchronous, i.e. return promises
n := ui.Eval(`Math.random()`).Float()
fmt.Println(n)

// Call JS that calls Go and so on and so on...
m := ui.Eval(`add(2, 3)`).Int()
fmt.Println(m)

// Wait for the browser window to be closed
<-ui.Done()

制作 MacOS App

在完成基本的编码后,接下来的工作才是重点:将应用包装成一个 MacOS APP。

制作图标

一个 MacOS APP 首先需要一个图标,这里请选择一个 1024 X 1024 分辨率,背景透明的 PNG 图片。这里假设该图片名为 logo.png

  • 新建一个名为 tmp.iconset 的临时目录,用于存放不同大小的临时图片
  • 执行如下命令,将原图转为不同大小的图片并放入临时目录
$ sips -z 16 16     logo.png --out tmp.iconset/icon_16x16.png
$ sips -z 32 32     logo.png --out tmp.iconset/icon_16x16@2x.png
$ sips -z 32 32     logo.png --out tmp.iconset/icon_32x32.png
$ sips -z 64 64     logo.png --out tmp.iconset/icon_32x32@2x.png
$ sips -z 128 128   logo.png --out tmp.iconset/icon_128x128.png
$ sips -z 256 256   logo.png --out tmp.iconset/icon_128x128@2x.png
$ sips -z 256 256   logo.png --out tmp.iconset/icon_256x256.png
$ sips -z 512 512   logo.png --out tmp.iconset/icon_256x256@2x.png
$ sips -z 512 512   logo.png --out tmp.iconset/icon_512x512.png
$ sips -z 1024 1024   logo.png --out tmp.iconset/icon_512x512@2x.png
$ iconutil -c icns tmp.iconset -o icon.icns

icon.icns 就是制作好的 MacOS App 图标。

制作 .app bundle

macOS 上安装的可运行程序是一个 .app 的目录,里面包含了应用的二进制文件、资源文件以及清单文件。其的目录结构为(也可以通过”右键-显示包内容“来查看 .app 文件内容):

$ tree Kustomize.app
Kustomize.app
└── Contents
    ├── Info.plist
    ├── MacOS
    │   └── kustomize
    └── Resources
        ├── assets
        │   ├── css
        │   │   ├── page.css
        │   │   ├── prism.css
        │   │   └── weui.min.css
        │   ├── images
        │   │   └── favicon.ico
        │   └── js
        │       ├── jquery.min.js
        │       ├── prism.js
        │       └── weui.min.js
        ├── icon.icns
        └── views
            ├── copyreght.html
            ├── footer.html
            ├── header.html
            ├── index.html
            └── yaml.html

可以看到:

  • Info.plist 为清单文件,存储应用信息
  • MacOS 中存放二进制可执行文件
  • Resources 存放静态资源文件和图标

Info.plist 文件

这是一个清单文件,根据自己应用的内容对齐进行修改,更多内容可以参考 trayhost 项目的说明。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleExecutable</key>
    <string>kustomize</string>
    <key>CFBundleIconFile</key>
    <string>icon.icns</string>
    <key>CFBundleIdentifier</key>
    <string>io.guoxudong.kustomize-remote-observer</string>
    <key>NSHighResolutionCapable</key>
  <true/>
    <key>LSUIElement</key>
  <string>1</string>
</dict>
</plist>

使用脚本构建 App

上面的这些只不过是介绍一下原理及手动修改方式,实际应用中可以使用脚本来完成这些工作。使用如下脚本,可以一键完成:

  • .app 应用的构建
  • go 应用的打包
  • 清单文件的生成
  • 静态资源的拷贝
#!/bin/sh

APP="Kustomize.app"
mkdir -p $APP/Contents/{MacOS,Resources}
go build -o $APP/Contents/MacOS/kustomize
cat > $APP/Contents/Info.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleExecutable</key>
    <string>kustomize</string>
    <key>CFBundleIconFile</key>
    <string>icon.icns</string>
    <key>CFBundleIdentifier</key>
    <string>io.guoxudong.kustomize-remote-observer</string>
    <key>NSHighResolutionCapable</key>
  <true/>
    <key>LSUIElement</key>
  <string>1</string>
</dict>
</plist>
EOF
cp icons/icon.icns $APP/Contents/Resources/icon.icns
cp -r assets $APP/Contents/Resources/assets
cp -r views $APP/Contents/Resources/views
find $APP

注意
在 MacOS 中,当您运行 App bundle 时,进程的工作目录是根目录(/),而不是 Contents/Resources 目录。如果需要从 Resources 加载资源,则需要进行如下更改:

ep, err := os.Executable()
if err != nil {
    log.Fatalln("os.Executable:", err)
}
err = os.Chdir(filepath.Join(filepath.Dir(ep), "..", "Resources"))
if err != nil {
    log.Fatalln("os.Chdir:", err)
}

制作 DMG 文件

DMG 文件用于分发应用程序,将 .app 文件压缩制成镜像,可以很方便的通过拖拽的形式完成安装。

制作模板

制作 DMG 文件首先需要制作模板。打开磁盘工具 - 文件 - 新建映象 - 空白映象(或直接按 ⌘N)创建一个新的磁盘镜像。给它取个名字,设置足够的空间空间,分区选择CD/DVD

新建模板

制作好后,打开该镜像,进行文件夹视图定制(按⌘J),选择展示图标的大小及背景图片,这里可以隐藏工具栏

文件夹视图定制

右键应用程序选择制作替身,将替身移动到镜像中

制作替身

将打包好的 app 加入到 DMG 镜像中就完成了 DMG 模板的定制

定制好的视图

转换 DMG 文件

目前的 DMG 模板文件还没有经过压缩并且是可写的状态,这样是不能作为程序发布的,所以这里需要对模板进行转换。

转换

打开 磁盘工具 - 映象 - 转换,然后选择压缩后存储的目录就完成了最后一步 DMG 文件的转换。

转换成功

现在点开 DMG 文件,将应用拖动到应用程序中,就可以在启动台中看到我们的应用程序了!

启动台

自动化

上面只是展示了如何手动制作 DMG 镜像,实际使用当然是要将这些步骤自动化的。我将这部分内容做成了一个 go 脚本,原理其实就是使用 hdiutil 这个命令行工具,有兴趣的同学可以文末找到项目地址,Makefile 中有详细构建的命令。

项目展示

我使用 Go + HTML5 制作了一个 Kustomize Remote 的项目,可以从远程 kustomize 项目中获取配置,并 build 成 yaml 文件,UI样式为微信风格,支持 public 和 private 项目。

kustomize-remote-observer

yaml result

项目地址:https://github.com/sunny0826/kustomize-remote-observer

也可以直接在 release 页面 下载 DMG 文件安装试用,只需 Mac 上有 Chrome 即可。

结语

Go 语言一直在网络编程、云平台开发、分布式系统等领域占据着重要的地位,但是像桌面应用或者机器学习这样的领域,同样也能做出不错的效果。作为一门受欢迎的编程语言 Golang 已经有十多年的历史了,相信它在将来还能在更多的领域焕发生机,创造辉煌。

目录
相关文章
|
8天前
|
关系型数据库 MySQL
web简易开发(二){html5+php实现文件上传及通过关键字搜索已上传图片)}
web简易开发(二){html5+php实现文件上传及通过关键字搜索已上传图片)}
|
4天前
|
移动开发 前端开发 JavaScript
:掌握移动端开发:HTML5 与 CSS3 的高效实践
:掌握移动端开发:HTML5 与 CSS3 的高效实践
20 1
|
5天前
|
Kubernetes Cloud Native Go
Golang深入浅出之-Go语言中的云原生开发:Kubernetes与Docker
【5月更文挑战第5天】本文探讨了Go语言在云原生开发中的应用,特别是在Kubernetes和Docker中的使用。Docker利用Go语言的性能和跨平台能力编写Dockerfile和构建镜像。Kubernetes,主要由Go语言编写,提供了方便的客户端库与集群交互。文章列举了Dockerfile编写、Kubernetes资源定义和服务发现的常见问题及解决方案,并给出了Go语言构建Docker镜像和与Kubernetes交互的代码示例。通过掌握这些技巧,开发者能更高效地进行云原生应用开发。
46 1
|
9天前
|
缓存 前端开发 JavaScript
【专栏:HTML与CSS移动端开发篇】移动端网页性能优化策略
【4月更文挑战第30天】本文探讨了移动端网页性能优化的重要性,并提出了优化策略。HTML方面,建议精简结构、使用语义化标签、异步加载脚本和压缩文件;CSS优化包括精简样式、使用CSS3动画、媒体查询和压缩文件。其他策略涉及图片和字体压缩、缓存利用、数据压缩、减少HTTP请求及根据网络状态调整加载。综合运用这些策略能提升网页性能和用户体验。
|
9天前
|
前端开发 JavaScript UED
【专栏:HTML与CSS移动端开发篇】移动端触摸事件与手势识别
【4月更文挑战第30天】本文探讨了移动端触摸事件和手势识别在网页开发中的重要性。介绍了基础触摸事件如`touchstart`, `touchmove`, `touchend`, `touchcancel`及相关属性。文章列举了处理触摸事件的方法,包括单点触摸、多点触摸、滑动、长按、捏合缩放、旋转检测和事件代理。建议使用第三方库如Hammer.js简化手势处理,并分享了最佳实践,如避免意外触摸、提供视觉反馈、考虑性能和跨设备测试。理解并有效利用这些技术能提升用户交互体验。
|
9天前
|
编解码 前端开发 UED
【专栏:HTML 与 CSS 移动端开发篇】CSS 媒体查询与移动端特定样式
【4月更文挑战第30天】CSS媒体查询在移动端开发中至关重要,它基于设备特性(如屏幕尺寸、分辨率、方向)应用特定样式,实现响应式设计。通过`@media`规则定义条件,如`(max-width: 600px)`,当屏幕宽度小于或等于600px时应用相应样式。常见条件包括屏幕宽度、高度、方向和分辨率。媒体查询可用于响应式布局、导航菜单优化、图片加载及字体调整。在实践中,需注意保持查询简洁,充分测试,渐进增强,并提前规划。掌握媒体查询能提升移动端用户体验,创造更优秀的网页设计。
|
9天前
|
编解码 移动开发 前端开发
【专栏:HTML与CSS移动端开发篇】使用Viewport Meta标签优化移动端显示
【4月更文挑战第30天】本文介绍了HTML的Viewport Meta标签在移动端网页优化中的作用。Viewport Meta标签定义了视口属性,如宽度、高度、初始缩放等,解决移动设备因屏幕尺寸差异导致的显示问题。主要属性包括width(常用device-width)、initial-scale、maximum-scale、minimum-scale和user-scalable。
|
9天前
|
编解码 缓存 前端开发
【专栏:HTML与CSS移动端开发篇】移动端网页布局与适配
【4月更文挑战第30天】本文探讨了如何使用HTML和CSS优化移动端网页布局与适配,强调响应式设计、灵活布局和媒体查询的重要性。针对移动设备的屏幕尺寸、操作方式、网络速度和性能差异,提出了断点选择、触摸优化、图像和性能优化等最佳实践。测试和调试、框架工具的应用也是关键步骤,以确保在多设备上提供优秀用户体验。开发者需持续学习新趋势和工具,以适应移动端发展。
|
9天前
|
编解码 前端开发 数据挖掘
【专栏:HTML 与 CSS 移动端开发篇】移动优先的网页设计理念
【4月更文挑战第30天】本文探讨了移动优先的网页设计在HTML和CSS移动端开发中的重要性。随着移动设备普及,移动优先设计理念旨在首先满足移动端用户需求,提供良好体验。通过响应式设计、简洁布局、优化资源和触摸友好交互,确保网站在移动设备上的表现。实施步骤包括分析用户需求、设计原型、编写代码和测试优化。注意避免过度设计,保持一致性,关注性能,并适应不同平台。移动优先设计是提升用户体验和竞争力的关键,随着技术发展,这一理念将持续演进。
|
9天前
|
编解码 前端开发 UED
【专栏:HTML与CSS实践篇】响应式网站开发实战
【4月更文挑战第30天】本文探讨了响应式网站开发,它能根据用户设备自动调整布局,提供最佳浏览体验。通过HTML和CSS,利用媒体查询、Flexbox和百分比宽度等技术实现响应式设计。媒体查询按屏幕尺寸定义CSS规则,Flexbox处理元素排列。文章通过新闻网站首页设计实例,展示了如何应用这些理论,包括使用Flexbox设计导航栏,使用媒体查询调整轮播图和内容区域,以及创建自适应页脚。遵循移动优先原则,关注性能优化和用户体验,响应式设计是前端开发的关键,为多设备用户提供优质浏览体验。