cgeo / cgeo

c:geo - The powerful Android geocaching app.
www.cgeo.org
Apache License 2.0
1.39k stars 567 forks source link

API for GC Wizard #12389

Open eddiemuc opened 2 years ago

eddiemuc commented 2 years ago

Would be nice to have an API for GC Wizard so that we can call its functions and get the calculated value as a response.

  1. User selects "calculate with GC Wizard"
  2. GC Wizard opens and provides a list of available functions
  3. User selects function, optionally mandatory "special" options
  4. GC Wizard returns a configuration string to c:geo containing
    • input variables and type
    • return type
    • name of function
    • some ID or encoded function that can be sent to GC Wizard to recall the function
  5. c:geo adds this data to a calculation step/variable
  6. User enters input variables
  7. c:geo calls the function in the background with the stored information whenever it is necessary

@S-Man42 What do you think, does this sound possible?

edit: There's already an issue for this: https://github.com/S-Man42/GCWizard/issues/489 Maybe my ideas from above are still helpful (for finding a protocol).

Originally posted by @SammysHP in https://github.com/cgeo/cgeo/issues/12386#issuecomment-1000218716

eddiemuc commented 2 years ago

Hi,

(as @SammysHP already edited) there are several thoughts about such things as a Public API. https://github.com/S-Man42/GCWizard/issues/489

We'd be very proud of such an amazing partnership and we also believe, that it wouldn't make any sense to develop such functions in parallel.

However, tbh, I have absolutely no idea of inter-app communication. We would love to provide anything you need, but I guess, we need to find to solve the technical question of this issues: How to provide an interface between two apps (especially the on our Flutter-based side, we are currently without any skills), how should a good api look like and what functions do you need.

I am sure, this would be very useful for another use case, @capoaira was working on: Provide a public interface in the web version to combine it with websites or greasemonkey scripts. https://github.com/S-Man42/GCWizard/issues/488

Any thoughts and skills on that are appreciated.

Originally posted by @S-Man42 in https://github.com/cgeo/cgeo/issues/12386#issuecomment-1000236657

eddiemuc commented 2 years ago

I had an idea about GUI and process integration of an APi to GC Wizard (or other similar services).

IN var tab, there is a button "..." now which is supposed to help the user entering and getting to know available functions (it currently opens a list of available functions, user can click on it and function name is prefilled):

image

Since we decided in #12386 to rather restrict available functions, this might no longer be necessary. Instead, this button might be used to open a dialog querying GC Wizard, retrieving answers and then pasting the results of these calls into the corresponding var value field. That way, the asynchronity of the process and also maybe long APi call times are not a problem any more, because queries are only done once and on user request.

SammysHP commented 2 years ago

If we decide on a good API definition we may change the implementation in the future (automatic API requests in the background, when we don't need to update all variables often due to design changes) without changing the API itself.

Further GC Wizard is multi platform, so the Android specific part should be just a service we call and all data is encoded in an Android independent format (like JSON). Something like

I'm sure there are better ways to do this. Just see this draft as a motivation to do it better. :)

S-Man42 commented 2 years ago

The main question remains: Hiw to open a port/provide an api on our side... We have to do some research unless nobody here has experience on this.

For the specific API definition, I'd go with @SammysHP 's idea, which is close to something like OpenAPI (indeed for REST apis but we should do something quite similar)

eddiemuc commented 2 years ago

The main question remains: Hiw to open a port/provide an api on our side... We have to do some research unless nobody here has experience on this.

@S-Man42 Would you prefer to open a server API (e.g. a REST API which we query using http) or an API to another Android App (which then needs to be installed by the user on the same device as c:geo for this to work)?

If server API: would you make this an open API (usable by anyone) or would you implement some sort of authentication into it (I would recommend the later)?

I assume you won't provide the functions as Java Lib, correct?

S-Man42 commented 2 years ago

JAR lib: I had a quick look around. Unfortunately I found no way to extract Dart code INTO a JAR although I really believe, that it should be possible (because it's close to JVM based languages, especially Kotlin).

Is a REST service really an option? I mean, this would require internet access when using an app which you have already installed. Moreover that requires a way to extract to a JAR as well, or we need to find how to create a Dart based server.

In a perfect world I'd like to provide an offline API directly into the GCW. And in a more pefect world this is useable through all supported platforms.

Because we have no idea how to provide an API in Flutter, we have to dive in to this. On my first looks around, I found nothing, but I will ask several user groups. I can't imagine that there's no way. But because I am still on vacation, I can do this in a few days.

Meanwhile, could you tell me how you'd provide such an API on a pure Android system (or share a link). Maybe this could offer the correct search terms also for Flutter based cross-app data sharing...

eddiemuc commented 2 years ago

@S-Man42 I am also not an expert in how to best establish an API between android apps too. Googling found me the following link: https://developer.android.com/training/basics/intents

We use intents of course to interact with other apps, but as far as I know those are more suited to really pass control to another app (including e.g. displaying Dialogs from this other app) rather than just calling a well-defined interface in the background (without the user visually "knowing"). But maybe something like this can be reached via intents as well

ztNFny commented 2 years ago

https://play.google.com/store/apps/details?id=com.github.siggel.coordinatejoker sends a list of coordinates to locus, using an api provided by locus. Maybe that can be used as inspiration

moving-bits commented 2 years ago

IIRC background services are a way to provide such API on Android systems, similar to what BRouter does. ~(Can provide a link later, I'm on the road currently.)~ See https://developer.android.com/training/run-background-service/create-service as an example.

BRouter consumes and provides XML formatted data, but one could use JSON (or something else) as well.

ludoo0d0a commented 2 years ago

Hi, i made a POC to prove that comm between 2 apps via intent is possible. poc is Flutter to flutter, but I also tried with a native android intent tester, it has the same expected result. Not completely stable, and needs to unify kotlin plugins, but it can be done.

https://github.com/ludoo0d0a/app-to-app

ps : I played with new experimental var solver : great, I love it ! (especially scan listing, yet naive, but a great capability)

eddiemuc commented 2 years ago

HI @ludoo0d0a , I tried to quickly scan your example code but I am not sure I found the right place...

However such an APi looks like, it seems important to me that the app you are communicating with (e.g. c:geo) does not need to know anything about how your own app is build (e.g. via Flutter, native or some other way) and just has to use standard Android communication methods.

Another note: app-to-app-communication only works of course when both apps are installed on the device. Am I correct in assuming that this is something you want to enforce? (Otherwise it might make sense to offer services additionally via backend API)

ludoo0d0a commented 2 years ago

Yes, you're right. Intents and method channel are android protocol. So flutter or android native won't impact communication. It relies on os itself.

From what I understood, (correct me I'm wrong), the need is to have cgeo and gcw installed. Then from cgeo, user input values, variables and formulas and on "compute" click, a request is made to gcw to resolve computation (cross sum...) So yes, both apps should be installed (like brouter or cgeo contacts)

I can help to dig into code, if needed (pm, or ask me)