Russ Cox | 270a22d | 2023-12-05 11:15:03 -0500 | [diff] [blame] | 1 | --- |
| 2 | title: Mobile |
| 3 | --- |
| 4 | |
K037_이노원 | f8bd810 | 2021-08-06 00:39:14 +0900 | [diff] [blame] | 5 | **The Go mobile subrepository adds support for mobile platforms (Android and iOS) and provides tools to build mobile applications.** |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 6 | |
| 7 | There are two strategies you can follow to include Go into your mobile stack: |
| 8 | |
| 9 | - Writing all-Go native mobile applications. |
| 10 | - Writing SDK applications by generating bindings from a Go package and invoke them from Java (on Android) and Objective-C (on iOS). |
| 11 | |
| 12 | This article will contain step-by-step guides to explain how to achieve |
| 13 | these strategies. |
| 14 | |
| 15 | - [Tools](#tools) |
| 16 | - [Native applications](#native-applications) |
| 17 | - [Building and deploying to Android](#building-and-deploying-to-android) |
| 18 | - [Building and deploying to iOS](#building-and-deploying-to-ios) |
Herman Bergwerf | 8cd81b6 | 2020-04-24 17:59:32 +0200 | [diff] [blame] | 19 | - [App icon](#app-icon) |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 20 | - [SDK applications](#sdk-applications-and-generating-bindings) |
| 21 | - [Building and deploying to Android](#building-and-deploying-to-android-1) |
| 22 | - [Building and deploying to iOS](#building-and-deploying-to-ios-1) |
| 23 | - [iOS Simulator](#ios-simulator) |
| 24 | |
| 25 | ## Tools |
| 26 | |
Sean Liao | 3c9c9e1 | 2022-01-22 17:27:16 +0100 | [diff] [blame] | 27 | You need to have [Go 1.16 or above](https://go.dev/dl/) to install mobile tools. |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 28 | |
Changkun Ou | 922c110 | 2021-09-02 10:25:11 +0200 | [diff] [blame] | 29 | Go Mobile introduces a tool, [`gomobile`](https://golang.org/x/mobile/cmd/gomobile), |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 30 | to help you with the build and the binding process. |
| 31 | |
Sean Liao | 3c9c9e1 | 2022-01-22 17:27:16 +0100 | [diff] [blame] | 32 | `gomobile` also supports [Go Modules](https://go.dev/ref/mod), e.g. using |
Changkun Ou | 120f89c | 2021-08-31 18:00:53 +0200 | [diff] [blame] | 33 | |
| 34 | ``` |
| 35 | $ gomobile bind -v -o android.aar -target=android ./package |
| 36 | ``` |
| 37 | |
Changkun Ou | 922c110 | 2021-09-02 10:25:11 +0200 | [diff] [blame] | 38 | under a project directory. |
Changkun Ou | 120f89c | 2021-08-31 18:00:53 +0200 | [diff] [blame] | 39 | |
| 40 | On macOS, you will need to have [Xcode Command Line Tools](https://developer.apple.com/downloads/) installed. |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 41 | |
Changkun Ou | 922c110 | 2021-09-02 10:25:11 +0200 | [diff] [blame] | 42 | To install `gomobile` tools: |
Changkun Ou | 120f89c | 2021-08-31 18:00:53 +0200 | [diff] [blame] | 43 | |
| 44 | ``` |
| 45 | $ go install golang.org/x/mobile/cmd/gomobile@latest |
| 46 | $ gomobile init |
| 47 | ``` |
| 48 | |
Changkun Ou | 922c110 | 2021-09-02 10:25:11 +0200 | [diff] [blame] | 49 | The following sections will help you how to use the `gomobile` tool. |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 50 | |
| 51 | ## Native applications |
| 52 | |
| 53 | The native category includes applications entirely written in Go. Currently, the |
Sean Liao | 6fe9f52 | 2022-01-22 16:52:18 +0100 | [diff] [blame] | 54 | [golang.org/x/mobile](https://pkg.go.dev/golang.org/x/mobile) |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 55 | contains only a small set of packages that focus on: |
| 56 | |
| 57 | * App control and configuration |
Einthusan Vigneswaran | 31d8598 | 2021-01-22 20:07:01 +0530 | [diff] [blame] | 58 | * OpenGL ES 2 and ES 3 bindings |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 59 | * Asset management |
| 60 | * Event management |
| 61 | * Experimental packages include OpenAL bindings, audio, font, sprite and motion sensors |
| 62 | |
| 63 | There are various example native applications under [golang.org/x/mobile/example](https://golang.org/x/mobile/example). We will build and deploy the basic example both to an Android and iOS device. |
| 64 | |
| 65 | Grab the application. |
| 66 | |
| 67 | ``` |
| 68 | $ go get -d golang.org/x/mobile/example/basic |
| 69 | ``` |
| 70 | |
| 71 | ### Building and deploying to Android |
| 72 | |
| 73 | Run `gomobile build` to build an Android APK. |
| 74 | |
| 75 | ``` |
Justin Vieira | 3721154 | 2022-08-11 11:23:48 -0400 | [diff] [blame] | 76 | $ gomobile build -target=android -androidapi 19 golang.org/x/mobile/example/basic |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 77 | ``` |
| 78 | |
| 79 | Build command will build an APK named basic.apk. |
| 80 | |
| 81 | If an AndroidManifest.xml is defined in the package directory, it is added to the APK output. Otherwise, a default manifest is generated. |
| 82 | |
| 83 | If you have the [adb](http://developer.android.com/tools/help/adb.html) command installed on your machine, you can use `gomobile install` to build and push the APK to your mobile device. |
| 84 | |
| 85 | ``` |
| 86 | $ gomobile install golang.org/x/mobile/example/basic |
| 87 | ``` |
| 88 | |
| 89 | ### Building and deploying to iOS |
Changkun Ou | 922c110 | 2021-09-02 10:25:11 +0200 | [diff] [blame] | 90 | |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 91 | Run `gomobile build` to build the package as an iOS application. |
| 92 | |
Thiago Holanda | d3f5d0e | 2020-05-16 20:31:30 +0200 | [diff] [blame] | 93 | Note: target=ios requires the host machine running macOS. You need to obtain a [signing identity and download provisioning profiles](https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html) in order to continue. |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 94 | |
| 95 | ``` |
| 96 | $ gomobile build -target=ios golang.org/x/mobile/example/basic |
| 97 | ``` |
| 98 | |
| 99 | The build command will build an application bundle, named `basic.app`. |
| 100 | |
| 101 | You can deploy .app files by dragging and dropping them to the device. |
| 102 | |
| 103 | * In Xcode, open Window > Devices. |
| 104 | * Select the physical device from the left pane. |
| 105 | * Drag and drop the .app file to "Installed Apps" section. |
| 106 | * Check the "Copy items if needed" option |
| 107 | |
| 108 |  |
| 109 | |
| 110 | Alternatively, you can deploy application bundles to your iOS device by using the [ios-deploy](https://github.com/phonegap/ios-deploy) utility command line tool. Use ios-deploy to push the application to your device. |
| 111 | |
| 112 | ``` |
| 113 | $ ios-deploy -b basic.app |
| 114 | ``` |
| 115 | |
Herman Bergwerf | 8cd81b6 | 2020-04-24 17:59:32 +0200 | [diff] [blame] | 116 | ### App icon |
| 117 | |
| 118 | It is possible to set an app icon by creating `assets/icon.png`. |
| 119 | |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 120 | ## SDK applications and generating bindings |
| 121 | |
| 122 | In this category, we will show you how you can use a Go package in |
| 123 | your existing Android or iOS application. |
| 124 | |
| 125 | The advantages to following this strategy: |
| 126 | |
| 127 | * You can reuse a Go package from a mobile app without making significant changes to your existing application. |
| 128 | * In cases where you want to share a common code base between your Android and iOS application, you can write the common functionality once in Go and glue them to the platform-specific code by invoking the Go package through bindings. |
| 129 | |
| 130 | Current limitations are listed below. |
| 131 | |
Sean Liao | 6fe9f52 | 2022-01-22 16:52:18 +0100 | [diff] [blame] | 132 | * Only a [subset of Go types](https://pkg.go.dev/golang.org/x/mobile/cmd/gobind) are currently supported. |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 133 | * Language bindings have a performance overhead. |
| 134 | * There are a few limitations on how the exported APIs should look due to the limitations of the target language. |
| 135 | |
| 136 | We will use the example package under [golang.org/x/mobile/example/bind/hello](https://golang.org/x/mobile/example/bind/hello) to generate bindings and invoke Greetings function from Java and Objective-C. |
| 137 | |
| 138 | Grab the example by running the command below. |
| 139 | |
| 140 | ``` |
| 141 | $ go get -d golang.org/x/mobile/example/bind/... |
| 142 | ``` |
| 143 | |
| 144 | ### Building and deploying to Android |
| 145 | |
| 146 | Note: Go Mobile runs on the same architectures as Go, which currently means ARM, ARM64, 386 and amd64 devices and emulators. Notably, Android on MIPS devices is not yet supported. |
| 147 | |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 148 | * Run the following command to generate the [aar](https://developer.android.com/studio/projects/android-library.html) file that is suitable for importing into Android projects: |
| 149 | |
| 150 | ``` |
| 151 | $ gomobile bind -o app/hello.aar -target=android golang.org/x/mobile/example/bind/hello |
| 152 | ``` |
| 153 | |
李小明 | 80bee2b | 2021-08-31 10:33:26 +0800 | [diff] [blame] | 154 | Tips: From 1.16, it is recommended to execute `go get -d golang.org/x/mobile/cmd/gomobile` before each execution of `gomobile bind ...`. go get will automatically add indirect references to go.mod. These indirect references maybe automatically deleted by ide or go mod tidy, but they are required! |
| 155 | ``` |
| 156 | require ( |
| 157 | golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect |
| 158 | golang.org/x/mod v0.4.2 // indirect |
| 159 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect |
| 160 | golang.org/x/tools v0.1.2 // indirect |
| 161 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect |
| 162 | ) |
| 163 | ``` |
| 164 | |
Adrian Wan | 08e1eb3 | 2021-02-17 12:38:16 -0800 | [diff] [blame] | 165 | * Launch Android Studio. |
| 166 | * File > Import Project... to import the reference project from $GOPATH/src/golang.org/x/mobile/example/bind/android. |
| 167 | |
| 168 |  |
| 169 | |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 170 | * Build and deploy the application to the device. |
| 171 | |
| 172 | The app module contains the main application that invokes the `hello.Greetings`. When the application is launched the text view is updated with the string returned value. |
| 173 | |
| 174 | If you are not using Android Studio, in order to work with bindings for Android, you need to have [Android SDK](https://developer.android.com/sdk/index.html#Other) installed and ANDROID_HOME environment variable set to the SDK path. You also need the [NDK](https://developer.android.com/ndk/) installed; the easiest way is to run the SDK command `sdkmanager ndk-bundle`. |
| 175 | |
makeworld | fe00aab | 2022-04-01 11:48:25 -0400 | [diff] [blame] | 176 | Alternatively, if you are not familiar with android development, and you do not wish to set up all the required environment (Android SDK, Gradle, etc), you can use [this](https://github.com/AgregoreWeb/gomobile-android-docker) docker image to build the application in [docker](https://www.docker.com/) instead. |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 177 | |
chenhua | 61bd8ab | 2019-09-18 23:48:49 +0800 | [diff] [blame] | 178 | Besides, if you try to add yourmodule.aar into your own project, after copy the yourmodule.aar file and yourmodule.jar file to "android\app" folder, below editing in "android\app\build.gradle" file should be done in order to make your module imported correctly. |
chenhua | 06516dd | 2019-09-18 23:49:40 +0800 | [diff] [blame] | 179 | |
chenhua | 61bd8ab | 2019-09-18 23:48:49 +0800 | [diff] [blame] | 180 | ``` |
| 181 | + repositories { |
| 182 | + flatDir { |
| 183 | + dirs '.' |
| 184 | + } |
| 185 | + } |
| 186 | ``` |
chenhua | 06516dd | 2019-09-18 23:49:40 +0800 | [diff] [blame] | 187 | |
chenhua | 61bd8ab | 2019-09-18 23:48:49 +0800 | [diff] [blame] | 188 | ``` |
| 189 | dependencies { |
| 190 | ... |
| 191 | + implementation (name:'yourmodulename', ext:'aar') |
| 192 | } |
| 193 | ``` |
| 194 | |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 195 | ### Building and deploying to iOS |
| 196 | |
Thiago Holanda | d3f5d0e | 2020-05-16 20:31:30 +0200 | [diff] [blame] | 197 | Note: target=ios requires the host machine to be running macOS. |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 198 | |
| 199 | ``` |
| 200 | $ cd $GOPATH/src/golang.org/x/mobile/example/bind |
| 201 | $ gomobile bind -target=ios golang.org/x/mobile/example/bind/hello |
| 202 | ``` |
| 203 | |
Thiago Holanda | 87f1151 | 2020-05-16 20:36:17 +0200 | [diff] [blame] | 204 | Gomobile bind will generate a framework bundle called `Hello.framework`. Open the sample Xcode project by running the command below. |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 205 | |
| 206 | ``` |
| 207 | $ open ios/bind.xcodeproj |
| 208 | ``` |
| 209 | Drag and drop the `Hello.framework` bundle to the Xcode project. Check "Copy items if needed" if you need a different copy of the framework bundle within the Xcode otherwise. Otherwise, modifying the Go package source code and rerunning `gomobile bind` will update the hello.framework. |
| 210 | |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 211 |  |
| 212 | |
Philipp Wallrich | d4a0c7a | 2020-04-27 23:03:02 +0200 | [diff] [blame] | 213 | If you decide to keep `Hello.framework` in the main directory you have to add the main directory to the `Framework Search Paths` in the the targets Build Settings. |
| 214 | |
| 215 |  |
| 216 | |
Ian Lance Taylor | b2def95 | 2019-07-19 05:51:43 -0700 | [diff] [blame] | 217 | Your project layout should look like what's shown below. |
| 218 | |
| 219 |  |
| 220 | |
| 221 | Build and run it on the simulator or an actual device (Cmd+R). When the application launches, the label on the main view will be modified with the string returned from `GoHelloGreetings` which invokes the `hello.Greetings` function. |
| 222 | |
| 223 | Note that you can also invoke `GoHelloGreetings` from Swift by importing Hello. |
| 224 | |
| 225 | ```swift |
| 226 | @import Hello |
| 227 | // ... |
| 228 | let msg = Hello.GoHelloGreetings("gopher") |
| 229 | ``` |
| 230 | |
| 231 | #### iOS Simulator |
| 232 | |
| 233 | As of Go 1.5, only darwin/amd64 works on the iOS simulator. To use the simulator, you need to configure Xcode to only try to run 64-bit binaries. |
| 234 | |
| 235 | Xcode matches the bit width of the ARM binaries when running on the X86 simulator. That is, if you configure Xcode to build both 32-bit and 64-bit ARM binaries (the default), it will attempt to run 32-bit X86 binaries on the simulator, which will not work with Go today. Modify the Xcode build settings to only build 64-bit ARM binaries, and the simulator will run the amd64 binary. |
Russ Cox | 270a22d | 2023-12-05 11:15:03 -0500 | [diff] [blame] | 236 | |