Experiences when use Gomobile to build framework.

When you build a mobile native application for Android and iOS, you cannot avoid the duplicate code.
For example: the network module which use need to write in Java/Kotlin for Android and Objective-C/Swift for iOS.
However, you can use Gomobile to write this module and export to a framwork for those platform, when you need update somethings, you also just need to update once and export update framework for both Android and iOS.
Have many tutorials instruct you how to build it. So I don't want to do it again. I just want to shared some my experiences when working with GoMobile.

  • Setup Gomobile
    1. Install Gomobile
    2. After you run $ go get golang.org/x/mobile/cmd/gomobile successful. Then you need run next command $ gomobile init
      ... oh ooh: command not found: gomobile
      With me it take about an hour to resolve this :(. So long, but finally, I fixed it by run the command: export PATH=$PATH:'/Users/nhatle/go/bin'. That is the path to parent Go directory into my computer. You got the error command not found: gomobile because you are not in the bin directory, which contain gomobile.

    3. Problem with mutile Xcode version in application folder
    4. With me I have two Xcode versions into the application folder: 9.4.1(name Xcode.app) and 10(name Xcode copy.app).
      So that I failed to run the command gomobile bind -target ios -o ../../frameworks/CoreLib.framework
      Why?
      The problem is my command line tools point to Xcode copy.app. So I think the white space into the name Xcode copy.app is the problem. I decide to solved the problem with run the command: sudo xcode-select -s /Applications/Xcode.app.
      After that I can export the framework successful :).

  • Slices array:
  • Let suppose I have a method func getItemsFromKey(keys: []string) ([]string error) which passing a list of keys with type string and return list values with type string too. But the problem is that your method will be skepping when you try to export framework for iOS/Android. So I try to change this method which allow passing json string contain list keys {"data" : [{"key": "a"}, {"key": "b"}]}. And use struct like below to parse it:

    type Data struct {
    Data []*Response `json:"data"`
    }

    type Response struct {
    Key string `json:"key"`
    Value string `json:"value"`
    }

    func parseJSONString(jsonString string) []string {
    list := &Data{}
    json.Unmarshal([]byte(jsonString), &list)
    keys := make([]string, 0)
    for _, item := range configs.Data {
    keys = append(keys, item.Key)
    }
    return keys
    }

  • Completion callback:
  • It's easy to make callback method in Go, however when you export to *.framework to use in mobile will having a problem that Gomobile still not support export callback function, so your method will be skipping when export to lib file.
    So I resolved this problem by having an interface to make call back method like delegate pattern.
    type ResponseHandler interface {
    ResponseResult(response []byte, err error)
    }
    func CallAPI(responseHandler ResponseHandler) {
    //Do something here to get data
    responseHandler.ResponseResult(data, err)
    }

    Will update more ...