-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
proposal: expose ObjC API to gomobile bind programs #17102
Comments
CL https://golang.org/cl/29175 mentions this issue. |
CL https://golang.org/cl/29174 mentions this issue. |
CL https://golang.org/cl/29173 mentions this issue. |
This is nice. |
The objc package adds a parser that uses the clang -cc1 -ast-dump command to extract type information about ObjC classes and protocol. The resulting type information is needed to generate ObjC API wrappers in Go. This is the first part of the implementation of proposal golang/go#17102. For golang/go#17102 Change-Id: I8382b54c0bd315703ec5a62cc177e1a2ace061e9 Reviewed-on: https://go-review.googlesource.com/29173 Reviewed-by: David Crawshaw <crawshaw@golang.org>
Using the new ObjC type analyzer API, scan the bound packages for references to ObjC classes and protocols and generate Go wrappers for them. This is the second part of the implementation of proposal golang/go#17102. For golang/go#17102 Change-Id: I773db7b0362a7ff526d0a0fd6da5b2fa33301144 Reviewed-on: https://go-review.googlesource.com/29174 Reviewed-by: David Crawshaw <crawshaw@golang.org>
There is some documentation and an Android example incoming in https://go-review.googlesource.com/c/31170/ There is not iOS app example yet, but you can check out |
@eliasnaur thanks for reply. Ok good to know. i see from the docs its called "direct integration mode" Which leads me to ask this side question: |
I don't see why not.
|
@eliasnaur |
hey all is there an example for the gobind command to generate reverse bindings? I am looking into generate bindings for NSFoundation classes, not necessarily ios stuff |
There are no examples per se, but take a look at the golang.org/x/mobile/bind/testpkg/objcpkg package that contains test code for the iOS reverse bindings. |
Hey @eliasnaur thanks for pointing that out. I am still a little confused on how to get the bindings. I am invoking gobind directly on the package like so: "gobind -lang objc -outdir ObjC golang.org/x/mobile/bind/testpkg/objcpkg", but that's failing (package "golang.org/x/mobile/bind/testpkg/objcpkg": no buildable Go source files in /Users/eginez/repos/goland/src/golang.org/x/mobile/bind/testpkg/objcpkg). Any ideas? |
Why are you not using the gomobile command?
Den lør. 1. jul. 2017 17.00 skrev Esteban Ginez <notifications@github.com>:
… Hey @eliasnaur <https://github.com/eliasnaur> thanks for pointing that
out. I am still a little confused on how to get the bindings. I am invoking
gobind directly on the package like so: "gobind -lang objc -outdir ObjC
golang.org/x/mobile/bind/testpkg/objcpkg", but that's failing (package "
golang.org/x/mobile/bind/testpkg/objcpkg": no buildable Go source files
in /Users/eginez/repos/goland/src/golang.org/x/mobile/bind/testpkg/objcpkg).
Any ideas?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#17102 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAgCDC-qxzwieq1_7KMr2t25Ua1R_ktnks5sJl8PgaJpZM4J8600>
.
|
I am not trying to create a mobile app I am trying to use nsfoundation in my go app for mac os, happy to get some directions if it's better to use the gombile command |
@eliasnaur I hope you can give me a bit of guidance. I am trying to create a UIViewController in Go using gomobile bind and the UIViewController ViewDidLoad method is being called as expected, but I want to programmatically add a webview (or label or anything) to the UIViewControllers view property and I just can't figure out how to do it. I have done a lot of gomobile sdk style apps and I am somewhat familiar with reverse bindings, but failing to see what is wrong in my case. The commented out code is what I am trying to do: ` ) type MainViewController struct { func (vc *MainViewController) ViewDidLoad(self gopkg.MainViewController) { } ` |
What happens if you try using that code?
Den tor. 6. jul. 2017 23.34 skrev Casey Manus <notifications@github.com>:
… @eliasnaur <https://github.com/eliasnaur> I hope you can give me a bit of
guidance. I am trying to create a UIViewController in Go using gomobile
bind and the UIViewController ViewDidLoad method is being called as
expected, but I want to programmatically add a webview (or label or
anything) to the UIViewControllers view property and I just can't figure
out how to do it. I have done a lot of gomobile sdk style apps and I am
somewhat familiar with reverse bindings, but failing to see what is wrong
in my case. The commented out code is what I am trying to do:
`
import (
//"fmt"
"ObjC/UIKit"
//"ObjC/Foundation"
gopkg "ObjC/GoExcite"
)
type MainViewController struct {
UIKit.UIViewController
}
func (vc *MainViewController) ViewDidLoad(self gopkg.MainViewController) {
self.Super().ViewDidLoad()
//webview := UIKit.UIWebView.NewWithFrame(self.View().Bounds())
//url := Foundation.NSURL.URLWithString("https://google.com")
//request := Foundation.NSURLRequest.RequestWithURL(url)
//webview.LoadRequest(request)
//self.View().AddSubView(webview)
}
func (vc *MainViewController) DidReceiveMemoryWarning(self
gopkg.MainViewController) {
self.Super().DidReceiveMemoryWarning()
}
`
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#17102 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAgCDCm4rUBYUcvnC3zs5XDv4kWd7QBsks5sLVLigaJpZM4J8600>
.
|
but the other problem seems to be that UIKit.UIWebView.NewWithFrame doesn't exist. Also "New" doesn't exist either. I thought that initWithFrame would be translated to "NewWithFrame", Overall, it seems like the mapping of method names isn't what I expect from the documentation. I'll help update the documentation if we get this working. Here is full set of code. |
Ah, https://developer.apple.com/documentation/uikit/uiview/1622580-bounds is a CGRect. Unfortunately, go mobile doesn't (yet) support value structs; this applies to reverse bindings as well as regular bindings. |
@eliasnaur well that pretty much means you can't build anything GUI related with reverse bindings. It is interesting though that it said UIView was a interface with no methods, is it possibly due to the fact that nothing in UIView is mappable? |
That's true, I'm afraid. The Android reverse bindings are advanced enough to enable GUI programming in Go. The iOS reverse bindings never progressed as far. |
@eliasnaur do you know if it would be possible to generate the objc bindings on macOS? I'm looking for the ability to have something similar to PyOBJC on macOS. |
Not much (if any) of the generators themselves are specific to iOS and it should be possible to generate macOS bindings. However, go mobile doesn't support anything else than iOS and Android so I don't know how much work is needed in practice. |
@eliasnaur I'd really like to get those C structures exposed, admittedly my knowledge of cgo is pretty limited, but it seems like it would be possible to reference them that way, then just make the bind utility aware of them. Perhaps I am completely off on that assumption. Anyway if I wanted to tackle that, where should I start, and do you think it is possible without deep knowledge of everything else? |
You'll need some knowledge of the binding machinery. The problem with cgo
is that the C.* types don't cross package boundaries.
Den fre. 7. jul. 2017 19.45 skrev Casey Manus <notifications@github.com>:
… @eliasnaur <https://github.com/eliasnaur> I'd really like to get those C
structures exposed, admittedly my knowledge of cgo is pretty limited, but
it seems like it would be possible to reference them that way, then just
make the bind utility aware of them. Perhaps I am completely off on that
assumption. Anyway if I wanted to tackle that, where should I start, and do
you think it is possible without deep knowledge of everything else?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#17102 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAgCDFuRX2KMwZWrwGXEtcWaWCW6_c8Hks5sLm68gaJpZM4J8600>
.
|
Guys. All the things you've done is really great! I have a Go interface I have to subscribe on that event OnResult from ObjC using this interface. ObjC bind gives me a corresponding protocol and a basic class (instancetype)initWithRef:(id)ref;
Any way to solve my issue? Or I just red the doc not very accurately? Please help me |
Accept ObjC API wrapper types as arguments and return values from bound Go package functions and methods. Also, allow Go structs to extend ObjC classes and implement ObjC protocols as well as override and implement methods. This is the third and final part of the implementation of the golang/go#17102 proposal. Fixes golang/go#17102 Change-Id: I601d90fb6d22b8d6f8b7d5fe0130daa1a4dd4734 Reviewed-on: https://go-review.googlesource.com/29175 Reviewed-by: David Crawshaw <crawshaw@golang.org>
Accept ObjC API wrapper types as arguments and return values from bound Go package functions and methods. Also, allow Go structs to extend ObjC classes and implement ObjC protocols as well as override and implement methods. This is the third and final part of the implementation of the golang/go#17102 proposal. Fixes golang/go#17102 Change-Id: I601d90fb6d22b8d6f8b7d5fe0130daa1a4dd4734 Reviewed-on: https://go-review.googlesource.com/29175 Reviewed-by: David Crawshaw <crawshaw@golang.org>
Abstract
Today, gomobile bind can take a set og Go packages and expose their public API to Java or ObjC apps. The proposal is to support the reverse, exposing ObjC API to the bound Go packages.
This is the twin proposal to #16876, describing how ObjC API is accessed from Go.
Motivation
The motivation for this functionality is the same as for Java: to allow more of a mobile app to be written in Go in a convenient way that reduces boiler plate.
Proposed features
Importing ObjC classes and protocols from Go
The Go wrappers for the ObjC API references by the bound packages are generated each time gomobile bind is called. To access a ObjC type, use import statements on the form:
Which is the Go equivalent to
@import Module
in ObjC.To access the static methods on a ObjC class, use
Static methods
After importing, the resulting packages NSSomeClass will contain the static methods of its ObjC counterpart. For example
will allow Go code to use call
NSDate.Date()
, which is equivalent to[NSDate date]
in ObjCObjC classes and protocols
The package
"ObjC/Module"
contains Go interfaces wrapping every referenced ObjC type in the module. The wrapper types represent their wrapped ObjC types across the language barrier and can be used to call methods on wrapped instances. For example, the following Go function takes an ObjC NSDate instance and returns its description:Creating new ObjCinstances
To create a new instance of a Java class, use the
New
functions defined in the class package. There is a constructor function for every ObjC instance method whose name starts withinit
. For example the following function performs the equivalent of[[NSObject alloc] init]
:Errors
ObjC methods that return errors are automatically converted to return a Go
error
result.Inheriting from ObjC classes or conform to ObjC protocols in Go
Gomobile already exposes exported Go structs to ObjC; this proposal adds support for constructing Go structs directly from ObjC. In addition, Go structs will be able to extend ObjC classes and implement ObjC protocols.
To declare a Go struct that extends or implements ObjC types, use the form:
New instances of S are created in ObjC with
[[GoPkgS alloc] init]
. The defaultinit
initializer results in the ObjC instance referring to a new(S) from Go.Overriding ObjC methods
To override a method from a super class or implement a method from a protocol, declare a Go method with the same name and its first letter capitalized. For example, to override the description method in GoObject:
Exposing
this
Whenever an foreign object is passed across the language barrier, a proxy is created to represent it. In the example above, there is a GoObject ObjC instance created in ObjC, and it contains a reference to its counterpart GoObject Go instance in Go. That means that when a Go method is called from ObjC, its method receiver contains the Go instance, while the ObjC instance is only accessible to Java.
To access the Java instance (for passing back to other ObjC APIs), any Go overriding method can declare a
this
argument with one of the Java types the enclosing class extends or implements. For example, to access thethis
from the description method, use:The
this
variable will behave just as if it were a pure ObjC NSObject, and if passed or returned to ObjC, will have the same identity as the ObjC reference.Calling
super
In Go, delegation is achieved through delegation, but in ObjC, the keyword
super
is needed to access overridden methods. To call a super method from Go, use the Super() method on thethis
variable:Type name mangling
In ObjC, classes and protocols have difference namespaces. For example, there is both a
NSObject
class and aNSObject
protocol. In such cases, the Go names for the class has "C" appendded and the protocol has "P" appended. Thus,Foundation.NSObjectC
is the name for the GoNSObject
class, whileFoundation.NSObjectP
is the name for the protocol.Method names
In ObjC, the parameters are named and part of the function signature. The Go name for a method is the upper case first part of the method signature. If that is ambiguous, the full signature is used with colons removed and parameter names upper-cased. The final fallback is the ObjC signature with colons replaced with underscores, resulting in guaranteed unique, albeit ugly, names. For example, the ObjC methods
are translated to the following Go method names:
The text was updated successfully, but these errors were encountered: