Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/mobile/bind: support slices of supported structs #13445

Open
scisci opened this issue Dec 1, 2015 · 38 comments · May be fixed by golang/mobile#101
Open

x/mobile/bind: support slices of supported structs #13445

scisci opened this issue Dec 1, 2015 · 38 comments · May be fixed by golang/mobile#101
Labels
mobile Android, iOS, and x/mobile
Milestone

Comments

@scisci
Copy link

scisci commented Dec 1, 2015

Just want to know if it will ever be possible to support slices of supported. I currently have to write a wrapper object around an array to pass it back and forth between IOS and Go.

@bradfitz
Copy link
Contributor

bradfitz commented Dec 2, 2015

/cc @crawshaw @hyangah

@hyangah
Copy link
Contributor

hyangah commented Dec 3, 2015

It will not be impossible and eventually it should be supported. I don't know anyone who's currently working on this problem.

@hyangah hyangah changed the title x/mobile/cmd/gomobile: support slices of supported structs x/mobile/bind: support slices of supported structs Dec 3, 2015
@hyangah hyangah added this to the Unreleased milestone Dec 3, 2015
@dcu
Copy link

dcu commented Jan 5, 2016

yeah this is the most frustrating issue for me right now

@weitzj
Copy link

weitzj commented Jan 13, 2016

Do you have any ideas when this will be done? What I could do?

I tried and failed using: https://golang.org/pkg/container/list/ as an alternative

@ioArchman
Copy link

+1
Would highly recommend this as currently falling short without this.

@mpiannucci
Copy link

This is stopping me from using gomobile in anything worthwhile at the moment

@ioArchman
Copy link

@scisci - If you don't mind can you please share across a gist on how you handle the problem currently as said? My requirement would be to return an array/slice of custom modal class objects with 4 string properties.

@scisci
Copy link
Author

scisci commented Jan 21, 2016

hi @ioArchman, I made a quick repo here:

https://github.com/scisci/go-mobile-collection

If you think it can work for you, you will probably want to fork it and modify the render.go function to add/remove the methods you want on your collection wrapper. Feel free to make a comment on the project if you have any questions. Its pretty directly adapted from another tutorial on go generics, which you can find here http://www.onebigfluke.com/2014/12/generic-programming-go-generate.html

Keep in mind, I don't consider this a good solution. It feels hacky working with a wrapper on the objective-c/swift side, but it does work. Really would prefer something that feels more natural.

@ioArchman
Copy link

Thanks @scisci. Will look into this and try utilizing for now. Agreed on your last point too.

@scisci
Copy link
Author

scisci commented Jan 26, 2016

hi @hyangah, do you have any hints on how this would be technically implemented in case someone wanted to attempt it from outside the gomobile team?

@anacrolix
Copy link
Contributor

👍

@anacrolix
Copy link
Contributor

This is very limiting.

@kmcrawford
Copy link

Is this still on the road map? I found this library and would like to use it, but this issue may be keep me from using gomobile.

@gopherbot gopherbot added the mobile Android, iOS, and x/mobile label Jul 20, 2017
@kliron
Copy link

kliron commented Jan 5, 2018

It seems this is a show-stopper for many people. Are there any plans to support this?

@4h0q
Copy link

4h0q commented Jun 29, 2018

What's the status of this issue? It has been around for quite a while. It looks like the main show stopper for many people.

CC: @hyangah @crawshaw

@dradtke
Copy link

dradtke commented Sep 14, 2018

I just ran into this, and it would be great to be able to support slices.

@saurabha5
Copy link

@nhatlee
Copy link

nhatlee commented Oct 26, 2018

have any update for this issue?

@gituser9
Copy link

gituser9 commented May 2, 2019

Will there be any news?

@hyangah
Copy link
Contributor

hyangah commented May 2, 2019

Currently no one is working on the x/mobile project and adding this feature is not a small project.

Not ideal but need to work around by writing a wrapper package for binding, or using what @scisci mentioned for now.

@gituser9
Copy link

gituser9 commented May 3, 2019

Does the project have a future?

@bradfitz
Copy link
Contributor

bradfitz commented May 3, 2019

It's community supported at this point, so its future depends on you. There are others from the community working on it, but not full time.

@MariusVanDerWijden
Copy link

Anyone currently working on this? If not, could you give some pointers where to start with this?

@makivlach
Copy link

As a really slow and dumb bypass, you could serialize the data into JSON, pass the string and unserialize it on the other side. Use this only as a last resort, though.

@korovan-software
Copy link

korovan-software commented Oct 11, 2021

A workaround from my real project. Maybe will helpful for someone.
On Go side:

type Field struct {
    Key       string
    Value     string
    Protected bool
}

type FieldReceiver interface {
    Add(field *Field)
}

func GetEntryFields(receiver FieldReceiver) {
    for _, v := range entry.Values {
        field := Field{
            Key:       v.Key,
            Value:     v.Value.Content,
            Protected: v.Value.Protected}
        receiver.Add(&field)
    }
}

Android side:

val fields = mutableListOf<Field>()
Mylib.getEntryFields() { field ->
    run {
        fields += Field(field.key, field.value, field.protected)
    }
}

@nrobi144
Copy link

nrobi144 commented Sep 9, 2022

A workaround with String as an example:

type StringCollection interface {
	Add(s string) StringCollection
	Get(i int) string
	Size() int
}

// TODO solve this with generics
type StringArray struct {
	items []string
}

func (array StringArray) Add(s string) StringArray {
	array.items = append(array.items, s)
	return array
}

func (array StringArray) Get(i int) string {
	return array.items[i]
}

func (array StringArray) Size() int {
	return len(array.items)
}

Usage in go:

func GetExampleStringArray() *StringArray {
	strings := []string{"example1", "example2"}
	return &StringArray{items: strings}
}

On Android you can use this extension to convert it to a List<String>:

fun StringArray.toStringList(): List<String> {
    val list = mutableListOf<String>()
    for (i in 0 until size()) {
        list.add(get(i))
    }
    return list
}

fun main() {
    GoPackage.getExampleStringArray().toStringList()
}

@tex0l
Copy link

tex0l commented Dec 5, 2022

Is there any news? I was very surprised that this isn't implemented by default, I need to make very ugly workarounds to make my binding work.

@coder-free
Copy link

Is there any news?

kevmo314 added a commit to kevmo314/mobile that referenced this issue May 5, 2024
Adds code generation for supporting slices of structs in gobind.

Fixes golang/go#13445

NOTE: This PR isn't quite done yet, I'm having some trouble getting the testing environment set up. It seems like the default test environment is a bit outdated? In any case, could I use this PR's CI to iterate on test failures? Open to other suggestions as well.
@kevmo314 kevmo314 linked a pull request May 5, 2024 that will close this issue
@kevmo314
Copy link

kevmo314 commented May 5, 2024

I've implemented most of the work required for slices of structs here: golang/mobile#101

I could certainly use some help on the final stretch though, especially if you've managed to get the gobind test environment working correctly. In particular, I think the last bits necessary are to:

  1. Update the go-side refnum marshalling
  2. Add an Obj-C implementation
  3. Test that it all works

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/583196 mentions this issue: bind: support slices of structs

@ezoushen
Copy link

@kevmo314 Hi, I’m willing to help finish the work on the Objective-C side. Could you provide me with some guidance on how to collaborate?

@dockerdavid
Copy link

@makivlach thank you, i fixed my code in gomobile

@JackieLeee
Copy link

I also encountered this issue, and due to this problem, I might not be able to use gomobile to achieve the functionality I want.

@Edw590
Copy link

Edw590 commented Dec 4, 2024

I'm not sure this is helpful for this thread as I think it's solely about structs, but maybe gives a light to someone?

Just as an idea, if it's an array of strings, one could put it all in the same string and separate each by a special character, like "|". Or a non-printable one, like the null character.

If it's numbers that's worse - but can still be done. With a byte array. You convert the numbers to bytes and you know each number has for example 4 bytes. Then you can divide them back to ints in whatever language you're using Go with. And to separate, you could use a combination of bytes that won't be a number for sure (for example 5 random bytes - if the numbers are 4 bytes, you'd use 5 bytes to separate).

Also works for random bytes. I separated a stream of bytes (output of a shell command: the exit code, stdout and stderr all sent in the same byte array out of Go to Java) by a random big array of bytes (50 random bytes I think?). Then in Java I just got the first 4 bytes and converted to int and separated the rest with the byte array and the first was the stdout and the 2nd the stderr.


Specifically for structs, an idea is to have a function add a new struct to a Go-internal array. So you'd have a function with as many parameters as the struct and that function adds to a Go array. Each struct must have an ID (or use its index). Then there's a getter for the struct by its ID. That's how I'm doing with an array of structs.

Maybe this can help someone (?).

@ezoushen
Copy link

ezoushen commented Dec 5, 2024

@Edw590 This approach feels somewhat like what protobuf does, doesn’t it? 🤔 But still interesting though.

@fingon
Copy link

fingon commented Dec 5, 2024

FWIW we're just using gomobile to start GRPC server, and then generate stubs for Swift side to talk with Go code using GRPC. This solved so many issues it is not even funny (e.g. gomobile default of 'if field is not supported, we ignore it' bit us in the ass so many times.. same also with some name mangling issues).

We get all datatsructures protobuf supports too ;-)

@ezoushen
Copy link

ezoushen commented Dec 5, 2024

@fingon Cool solution! Have you tested the overhead (both CPU and RAM) of running an additional gRPC server compared to using pure Gomobile?

@fingon
Copy link

fingon commented Dec 5, 2024

@fingon Cool solution! Have you tested the overhead (both CPU and RAM) of running an additional gRPC server compared to using pure Gomobile?

It is quite performant. We have also backup plan of defining GRPC channel which just calls the gomobile'd function (instead of using TCP+HTTP/2) with arbitrary byte arrays to avoid networking, but so far it has not been necessary.

We have heavy Go backend + lightweight Swift (and eventually Android) UI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mobile Android, iOS, and x/mobile
Projects
None yet
Development

Successfully merging a pull request may close this issue.