Developing a library for iOS / Android on Golang



    Cross-platform mobile application development was very popular at the time. This approach was used by most companies during the development of the mobile industry. The main reasons for using cross-platform development were simple - the lack of professional personnel in the market, the speed and cost of development. Unfortunately, in most cases, this approach has not paid off.

    But why not give him a second chance? Technology has stepped forward and theoretically we can get a very high-quality product. In this article, we will examine in practice how to develop a library for IOS / Android in the Golang language and see what limitations and problems we encountered in the development process.

    Our main task is to develop an SDK for building logs and crashes from mobile applications, while the SDK must connect and work with both Android and iOS applications. At the same time, the library should interact with the main LogPacker service , which aggregates and analyzes data.

    We decided to use the new features of the Go language to create a cross-platform library. Firstly, our main application is written in Go, and it was easier for us to use this language and not to attract Java / Objective-C developers. Secondly, we saved development time and tried the old approach with new features.

    What is gomobile?


    The gomobile project provides developers with tools for building code for the Android and iOS mobile platforms.

    Now there are two ways to integrate Go into a mobile environment:

    • Writing a complete Go application without a UI.
    • Generate Java / Objective-C / Swift code from Go.

    This feature is supported since Golang version 1.5. The new gomobile utility helps compile Go into mobile applications or compile Java / Objective-C / Swift code.

    First, we will choose one of the implementation methods. The first method is not suitable for us because of the statement of the problem - we need a small library, and not a separate application. Although the method is very interesting and promising due to the speed of go applications and minimizing the consumption of resources of mobile devices.
    We will choose the second method, and generate the Java / Objective-C / Swift code from Go.

    Environment setting


    To begin, prepare the environment for development. We need Go version 1.5 or higher (the higher the better, the Go community is constantly improving Go Mobile).

    Next, install the gomobile utility and the Android SDK library. Let's start by installing gomobile:
    go get golang.org/x/mobile/cmd/gomobile
    

    Note: On OS X, you must have Xcode Command Line Tools installed.

    Next, initialize gomobile, this can be done once in any working directory:
    gomobile init
    

    Note: this command may take several minutes.

    To build Java code, we need the Android SDK and Java installed (OpenJDK is enough).

    Download and unpack the Android SDK into the home directory, for example ~ / android-sdk, and execute the following command to install the version API:
    ~/android-sdk/tools/android sdk
    

    Next, set the environment variable:
    export ANDROID_HOME=$HOME"/android-sdk"
    

    The environment for developing and building the library is ready. Let's go directly to writing the code, and see what limitations we encountered.

    Generic Go Code for Android and iOS


    The same code can be used for further compilation for Android and iOS. Writing such a cross-platform Go code has its limitations. Currently, we can use only some set of data types. When developing an application on Go, this must be taken into account. Consider the supported types in more detail:
    • int and float;
    • string and boolean;
    • byte []. The current implementation does not allow the use of [] byte as an argument to a function ( https://golang.org/issues/12113 );
    • the function should return only supported types, may not return a result, return one type or two types, despite the fact that the second type must be error;
    • interfaces can be used if they use a supported type during export;
    • type struct, only when all fields comply with the constraints.

    Therefore, if the type is not supported by the gomobile bind command, you will see a similar error:
    panic: unsupported basic seqType: uint64
    

    Undoubtedly, the set of supported types is very limited, but this is quite enough to implement our SDK.

    Build and import in Java / Objective-C / Swift


    Gobind generates Go code equivalent to Java, Objective-C, or Swift code. Unfortunately, gomobile does not work for Windows Phone and this must be taken into account at the planning stage.

    Usually gobind is not used directly, instead, the code is generated automatically and wrapped in a package with the `gomobile bind` command. This is described in more detail here golang.org/x/mobile/cmd/gomobile .

    Consider some of the commands and features of the compilation process for each platform.

    Let's start with the -target flag, which defines the platform to generate. Example for Android:
    gomobile bind --target=android .
    

    This command will generate a .aar file from the current code . Importing this file into Android Studio is very 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 to import always starts with go.

    A similar command is used to build Objective-C / Swift code:
    gomobile bind --target=ios .
    

    A .framework folder will be created in the current directory.

    This works for both Objective-C and Swift. Move the .framework folder to the Xcode file browser and add the import to the project:
    #import "Logpackermobilesdk/Logpackermobilesdk.h"
    



    Note: Go allows you to create not only the SDK, but also compile the application itself into apk / ipa files from the main.go file, though without the support of the native mobile UI. Undoubtedly this is a very interesting experiment of the Go-community.

    Using Connected Packages


    Gomobile bind automatically creates getSomething (), setSomething () functions. Also, all exported features will be publicly available.

    For example, using our library 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
    }
    

    She is for Objective-C:
    #import "ViewController.h"
    #import "Logpackermobilesdk/Logpackermobilesdk.h"
    @interface ViewController ()
    @end
    @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 you can see from the examples above, in the end we got standard libraries. The configuration of libraries in the application is extremely simple and familiar to developers.

    Conclusion


    Everyone understands that creating separate development teams for each mobile platform is not the easiest and cheapest pleasure. But to create a quality product, this is necessary at this stage of time. On the other hand, we were able to complete our small task as part of cross-platform development and took advantage of all its advantages:
    • Minimum development resources.
    • Development speed.
    • Simple solution support in the future.

    The downside is that we could not build the library under Windows Phone, but we knew about this beforehand.
    We hope that soon there will be an easy way to write full-fledged applications and SDKs in the Golang language.

    You can familiarize yourself with our achievements by cloning our repository .

    Also popular now: