We use cookies to improve your experience on our website. By browsing this website, you agree to our use of cookies. More info Ok, I understand!

9 March 2016

GoMobile: Library development for IOS/Android

Cross platform development of mobile applications was quite popular back then. This approach was used by most companies in the time of mobile branch establishment. The main reasons for using this approach were simple – lack of professionals in the market, slow development speed and unreasonable cost. Unfortunately, in most cases this approach did not justify itself. But why not to give that approach the second chance? Technology took a big step forward and theoretically we can get a high-quality product. In this article we’ll review in practice how to develop Library for iOS/Android in Golang and have a look at the problems and constraints faced in the development process.

Our main task is to develop SDK for log and crash collection from mobile applications. Here SDK have to connect and work with Android and iOS platforms. At the same time the library should interact with the main service – LogPacker that aggregates and analyze data.

We decided to use new opportunities of Golang for cross platform library creation. First of all, our main application is written in Go and it was easier for us to use that lang and not to involve Java/Objective-C developers. Second of all, we saved development time and tried old approach with improved features.

What is GoMobile?

Gomobile project provides developers with tools for code creation for Android and iOS mobile platforms.

Nowadays there are two ways for Go integration into mobile environment:

  1. Full development of Go-application without Ul.
  2. Java/Objective-C/Swift generation requiring Go.

This function is supported starting with Go 1.5. New gomobile utility helps to compile Go to mobile applications or to create a bindings in Java/Objective-C/Swift code.

For starters, we need to choose one of the integration ways. First option is not suitable for us because of the wrong problem setting – we need a small library, not a separate application. Although this option is interesting and perspective thanks to Go speed and minimal resources consumption of mobile applications. We stopped our choice on the second option and generated Java/Objective-C/Swift code from Go.

Environment setting

First, let’s prepare the environment for the development. We need Go 1.5 and higher (the higher – the better, Go-community updates Go Mobile regularly).

Then, let’s install gomobile utility and Android SDK library. Let’s start with gomobile installation:

go get golang.org/x/mobile/cmd/gomobile

Note: in OS X you need to have installed Xcode Command Line Tools. Then you need to initialize gomobile, this can be done one time in any work directory.

gomobile init

Note: this command might take several minutes.

For building Java-code you need Android SDK and installed Java (OpenJDK is enough).

Download ⇪  and unpack Android SDK to home directory, for example, ~/android-sdk, and make the following command for API installation.

~/android-sdk/tools/android sdk

Then you need to set environment variable:

export ANDROID_HOME=$HOME"/android-sdk"

Environment for the library development and building is ready. Let’s move to the code building and see what constraints we will face.

Shared GO-code for Android and iOS

The same code can be used for the future compilation for Android and iOS. Building of such cross platform code has its own constraints. As for now we can use only certain set of data types. We need to take it into consideration when developing application in Go. Let’s review in more detail the supported types:

  • int and float;
  • string and boolean;
  • byte[]. The current implementation doesn’t allow to use []byte as the function argument (https://golang.org/issues/12113);
  • function has to return only supported types, it may not return the result, it may return one or two types wherein the second type should be an error;
  • interfaces could be used if they are exported to files of any supported type;
  • struct type, only in case all fields meet the constraints.

So, if the type is not supported by gomobile bind command, you’ll see the similar error:

panic: unsupported basic seqType: uint64

It’s obvious that the set of supported types is very limited, but this is enough for the SDK implementation.

Building and import to Java/Objective-C/Swift

Gobind generates target language (Java, Objective-C or Swift) bindings for each exported symbol in a Go package. Unfortunately, gomobile doesn’t work for Windows Phone, and we have to consider that at the stage of product planning.

As a rule gobind is not used directly, instead the code is generated automatically and is packed by `gomobile bind` command. More details you can find here https://golang.org/x/mobile/cmd/gomobile.

Let’s consider several commands and special features of compilation process for every platform.

Let’s start with flag -target that defines platform for generation. Here is an example for Android:

gomobile bind --target=android .

This command will generate .aar file from the current code. To import that file to Android Studio is pretty simple:

  • File ➤New ➤New Module ➤Import .JAR or .AAR package
  • File ➤Project Structure ➤app ➤Dependencies ➤Add Module Dependency
  • Add import: import go.logpackermobilesdk.Logpackermobilesdk

Note: In Java the name of the package for import always starts with go.

Similar command is used for building Objective-C/Swift code.

gomobile bind --target=ios .

The folder .framework will be created in the current repository.

This works for both Objective-C and Swift. Transfer .framework folder to Xcode’s file browser and add import to project:

#import "Logpackermobilesdk/Logpackermobilesdk.h"

Note: Go allows you to build not only SDK but also to compile the application to apk/ipa file from main.go file only without native mobile Ul. No doubt, it’s a very interesting experiment of Go community.

Connected packets use

Gomobile bind automatically build getSomething(), setSomething().function. More over all exported functions will be available to the view.

As an example here is our library use in Android Studio:

import go.logpackermobilesdk.Logpackermobilesdk;
// ...
try {
    client = Logpackermobilesdk.NewClient("https://logpacker.mywebsite.com", "dev", android.os.Build.MODEL);

    msg = client.NewMessage();
    msg.setMessage("Crash is here!");
    // Use another optional setters for msg object

    client.Send(msg); // Send will return Cluster response
} catch (Exception e) {
    // Cannot connect to Cluster or validation error

The same library for Objective-C:

#import "ViewController.h"
#import "Logpackermobilesdk/Logpackermobilesdk.h"

@interface ViewController ()


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    GoLogpackermobilesdkClient *client;
    NSError *error;
    GoLogpackermobilesdkNewClient(@"https://logpacker.mywebsite.com", @"dev", [[UIDevice currentDevice] systemVersion], &client, &error);
    GoLogpackermobilesdkMessage *msg;
    msg = client.newMessage;
    msg.message = @"Crash is here!";
    // Use another optional setters for msg object
    GoLogpackermobilesdkResult *result;
    [client send:(msg) ret0_:(&result) error:(&error)];

As we can see from the examples above, we got standard libraries at the end. Library configuration of the application is quite simple and familiar to developers.


Everybody understands that separate commands development for every mobile platform – is not a cheap and easy task. But it is essential for creation a high-quality product at this time. Our task we did in terms of cross platform development and used all its advantages:

  • Minimal development resources.
  • High development speed.
  • Simple decision-support in the future.

The only minus we got was that we couldn’t build library for Windows Phone, but we knew that from the beginning.

We hope that in the near future there will be a simple way of building full applications and SDK in Golang.

You can get acquainted with our developments by forking our repository.