GeoTecINIT / nativescript-task-dispatcher

NativeScript-based mobile background task scheduler and dispatcher

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Requesting Information: Support for iOS and Autostarter

red-game-dev opened this issue Β· comments

Hi, hope you're well.

First of would like to start to say, that this plugin quite interesting, very helpful and opens a lot of doors, so very well done! Hopefully more developers will contribute to provide help to this plugin as it does deserve it! (In fact I did star it myself on both of my Github accounts).

Now going through the information I am requesting, which could be helpful if I get an answer for them, as it is crucial for us.

AutoStarter

The link (https://github.com/GeoTecINIT/nativescript-task-dispatcher/blob/master/docs/disable-android-battery-saving.md) << AutoStarter
Github repo (https://github.com/judemanutd/AutoStarter)

I've read through the Disable battery saving in non-stock Android phones which is quite informative and was able to learn more through. In fact thanks to this I was able to find this plugin and was able to learn deeper on this issue, but tackled the most already.

It mentions that "We are investigating if it can be integrated into this plugin", which was wondering if it will be possible near the future or if any change of plans regards to it. Since it would be a best addition, myself I tried to give it a try to integrate with our app + nativescript-task-dispatcher, but so far couldn't. Perhaps I was missing something, further on we can speak about as well. I've already integrated with jitpack.io on gradle, so could send how I did integrate that.

Please do not be bothered to check the issues below, they're probably from my end which something I did not correctly initialized. But you can know where I was running as in device, version and few errors.

Details:
NS Version: 8.0.2
Device: Samsung S8+ Plus (Didn't yet try on iOS)
Few of the Errors:

android.util.AndroidRuntimeException: Calling startActivity() from outside of an Ac
 flag. Is this really what you want?`. 

Yes, I did try to make an intent as well, and it doesn't recognize, both programmatically through NS and AndroidManifest.

Error: java.lang.Exception: Failed resolving method startActivity o
n class android.content.ContextWrapper

This one still have no clue what's wrong yet, but seems following the documentation through NS.

iOS

Link https://www.npmjs.com/package/nativescript-task-dispatcher << Prerequisites << iOS

On the readme on the plugin, under the Prerequisites section, it mentions that This plugin does not support iOS at its full extent which I need to know few questions about.

  • What it doesn't support to the full extent?
  • Will it be supporting them to full extend later? If so, there is a road map when this can be possible?
  • Does on iOS there is issues like android that it does force close the background service sometimes? Through I search a bit, but couldn't find any relevant issue, perhaps I didn't search correctly if there was.

Hopefully these requests can be integrated through the repository as it could be quite great addition and would make the plugin much more valuable than already is. Cheers 🍻

Best regards,
Red

Hi Red (@red-game-dev),

Thank you very much, we really appreciate your words about our work. What you mention is our strong belief also. We think this can end up opening many possibilities in terms of smarter apps which run automated processes on behalf of the user.

Regarding your questions. I can confirm both things you are requesting are in our plans, however it saddens us we cannot commit to any estimated time to make them available in the plugin. We are a very small team which already works far above its capacity, but if there is a strong request from the community we will do our best to implement them as soon as possible. We'll leave this issue open with that aim in mind.

About the AutoStarter integration

It is highly probable that this feature will come in first place. We will try to investigate its integration in the following weeks. There is already an idea in mind about where it could be placed. The idea is to integrate it here.

However there are a few things we have to check first. The AutoStarter library is Kotlin-based and we do not know how the TypeScript typings generator will work with that. It is our first time trying to integrate a Kotlin-based native library with NativeScript, although we know it is possible.

Another thing is how to handle the user interaction. Requesting to disable battery savings is an automated process in our library, which gets triggered when a prepare request happens and it has been configured to run at least one task at a frequency higher than 15 minutes. AutoStarter has no UI to inform the user about what to do once the settings screen becomes displayed. The first idea we can think of is to add an informative dialog right before the settings screen will be open, whose text could be taken from a key in the strings.xml file. This way its content could be adapted to every app. Would that be sufficient for your use case?

About the errors you get after trying to integrate our plugin with AutoStarter. Would it be possible for you to share a sample project with us, to be able to see where are you getting those errors? That could help reducing the time this will take to implement.

In summary, depending on the difficulties we could face during the integration of AutoStarter in our plugin, this functionality could be added in the following months. However, with great regret, if more urgent tasks arise on our side, we will have to delay its implementation.

About iOS support

Many thanks for these questions, all of them make a lot of sense. I'll try to give you an answer to each one of them:

  • What it doesn't support to the full extent?

The logic of the plugin itself works in iOS. What we are missing is a mechanism to schedule and execute arbitrary code (tasks) in an instant in the future.

This is implemented for Android for tasks to be run in 60 seconds and beyond. And enabled here, but the iOS counterpart is still missing. Mainly because in the current stage of our apps, iOS support is completely optional and low priority,

Unfortunately, our team does not have a lot of experience programming for iOS. We have an slight idea about that it could be done similarly to what they do at the Herald Project. Where they use DispatchQueues for a similar purpose. All of this in combination with very specific background modes.

Another thing that is missing is a mechanism to run tasks immediately in a safe manner. By "in a safe manner", we mean: ensuring the task runs successfully no matter if the user closes the app right after performing some action. We do that in Android using services. Again, enabling this mechanism here.

We vaguely intuit that this could be done in iOS by listening to the ApplicationDelegate background transition callbacks, but have not checked in detail yet.

  • Will it be supporting them to full extend later? If so, there is a road map when this can be possible?

This is our plan. The thing is we are focusing first in other features for our apps to be able to release them to our beta users. Once that becomes stable, we will return to the different pieces that compound our apps (this is one) to add new features to them like the ones being requested here. As I said, we are a small team and our feature delivery is not expected to slow down until the beginning of the next year, unless iOS support becomes a high priority before that.

The thing is that it would take a lot of time from us (a month as a minimum) to learn everything we have to learn about iOS, test that the implementation works evenly compared to its Android counterpart and catch and solve all the possible major bugs. We could go a lot faster if someone with a lot more experience in iOS than us could help us developing the iOS features thought. Any help will be greatly appreciated and we could save some time of our office hours to review and help in the implementation process.

  • Does on iOS there is issues like android that it does force close the background service sometimes? Through I search a bit, but couldn't find any relevant issue, perhaps I didn't search correctly if there was.

Indeed. To the best of our knowledge, there are no intermitent issues in iOS in this regard. iOS is quite different from Android in this sense. iOS apps don't have services, they run in background, if allowed. This has good and bad things. Programming is in theory a lot simpler. The problem is OS restrictions with apps running in the background. Special permissions are needed and in some cases, Apple's authorization right before the app gets published. Depending on your use case, you will be allowed to run an app in the background or not.

As it can be seen there are a lot of implications. We almost have to follow the same lengthy process we followed to get something working in Android, but fo iOS. Hence, unfortunately, we cannot provide a clear roadmap regarding to this feature due to the huge amount of uncertainty that exists. Notwithstanding, we are open to reduce that uncertainty with some help from outside our project, but that is usually very rare to get πŸ˜‰.


Red, I hope I have solved all your concerns with this message. I am afraid for some questions I have not given you the answer you wanted to read (neither the one I wanted to give you, given I would really like to start working on this improvements right now, but that is not possible) and I apologize for that. I wish we could do more, but this escapes our capacity at the moment.

We hope to encourage someone to lend a hand and help in pushing this plugin forward. We have some more ideas to improve it, but not enough time to make them a reality.

Do not hesitate to contact us if you have any further questions. We'll be eager to see a sample project from your side, which could aid in solving the integration problem with the AutoStarter library that you mention in your message.

Many thanks for your support.

Best regards,
Alberto

Hi @agonper, hope you're well.

Glad my words gives positive energy, as well glad that the questions I've asked are considered in your plans. Team size, knowledge in some areas, time is all understandable, and especially time as it could be quite time consuming doing certain improvements and integrations, will try to provide as much support as I can from my end.

About the AutoStarter integration
That is very glad to hear, as well thanks for the detailed information given as it is quite informative.

Integration file in Power Saving Manger
Link: https://github.com/GeoTecINIT/nativescript-task-dispatcher/blob/master/src/internal/tasks/schedulers/time-based/android/alarms/power-savings-manager.android.ts#L20-L44

Sounds interesting, though I've few questions regards to that -

  • I assume that we do require to forcefully ask the user to accept the permission for power saving mode?
  • If yes, I assume this functionality in this case won't be available for smaller tasks as well? Since in case the task is executed, is running but is killed, that may be a problem, as not every Android phone may behave the same. Unfortunately as we got too many phone circulating nowadays and may be quite hard to cover all scenarios I believe in this case.
  • If not, then I assume the AutoStarter will be there for rare scenarios for certain manufacturers or perhaps future-proof if they reduce the timer from 15 minute to lesser.

Typescript generator
I did use jitpack.io with gradle, and can say I could get any sort of typing's interfaces from it. Perhaps I need to configure something additionally, but have no clue regards to that, as jitpack.io does the rest of the job upon building the app.

You can find further on that in app.gradle in the example TestApp using jitpack.io how it works.

FYI on Jitpack.io: Jitpack provides a lot, as you could import other native libraries as well, both natively and on NS. I assume you may already know about this, since is same as maven, instead it does import from Github.

Interactions
I think as long there are exposed API for us to use, we can do GUI ourselves. We should keep the repository to minimum, without any GUI being involved as a suggestion.

Few reasons why -

  • We could do through strings.xml, but maybe a problem for those who wish a dynamic text
  • Those devs that requires a different GUI it could be quite a problem.

For our case it could ease some work for us, yet thinking in a general broad for other people who are and will use this package.

Functionality period to be added
I fully understand if any other issue or task arise the functionality could be delayed, hopefully with the same app could ease the integration complexities.

About iOS support
Thank you for very well detailed questions, they answered for us a lot of queries.

Follow up of What it doesn't support to the full extent?
Quite interesting, which would be quite good features to have in place, especially when running the task in a safe manner, that will raise better credibility as the ideal solution to use. I've checked Herald Project, I believe DispatchQueues is interesting to be used in this case, which probably would make sense. At the time being, I am not sure yet if is the only way or if there are other efficient.

I understand for experience in iOS programming, unfortunately neither I as I would have done some sample or perhaps contributed to solve this issue.

Meanwhile, sharing a small article link from NS docs, which can be used for ApplicationDelegate, but unfortunately is a bit old of documentation, couldn't find any other relevant information yet. Personally still haven't started the investigation on iOS, but if I will have further information or perhaps a solution, I will comment in here.
Link: https://v6.docs.nativescript.org/core-concepts/ios-runtime/how-to/backgroundexecution

Follow up of Will it be supporting them to full extend later? If so, there is a road map when this can be possible?
Interesting, glad is part of the plans!

I understand, would be great if can be prioritized anytime sooner, from my end will give the information necessary if I encounter anything during my research, especially any relevant samples. Hopefully more other people would be interested after reading the thread and could contribute more.

I believe at some point near Android, iOS might be tiny bit more easier, for the fact of the manufacturer could kill the service. Yet, researching, building, testing, fixing issues that could be quite time consuming as well, so is understandable.

Follow up of Does on iOS there is issues like android that it does force close the background service sometimes? Through I search a bit, but couldn't find any relevant issue, perhaps I didn't search correctly if there was.
I see, in the real end is all about Apple's authorization if they allow you to run the background service or not. I believe I need to research further into this, what sort of authorization could potentially be a problem for us, and how to get pass through them and being complaint. I understand, on the uncertainty point and indeed usually is quite hard to get some contribution.


App Sample

As requested I've added an app sample, which hopefully could help you further for the integration. Should you have any questions, feel free to contact. :)

TestApp.zip

Composition of files & purpose
app.ts - In here you will find the logic regards to taskDispatcher. Each .then() does include a block that can reproduce the errors mentioned below

First .then()
This is clear which just dispatch the event to start the task for taskDispatcher, according to what tasks is assigned in app\services\background\tasks.ts and their events in app\services\background\graph.ts

Second .then()
This unfortunately throws this error, which will stop the execution in this case for AutoStarter, but can be commented in order to reproduce the other mentioned in the previous comment

Error: java.lang.Exception: Failed resolving method startActivity o
n class android.content.ContextWrapper

Third .then()
This is the problem why I did aim to start a new intent with the flag neccessary, yet apparently it returns to the previous error mentioned on second .then()

android.util.AndroidRuntimeException: Calling startActivity() from outside of an Ac
 flag. Is this really what you want?`. 

I made a background service, which could be perhaps helpful for you to try different approaches. My apologies if they may not be best practice, but mainly was made for testing so we could find a proper way of dealing with this.

app\services\modules\BackgroundService.android.ts - This is a background service which is already applied in webpack activity, as I was trying to run this intent + AutoStarter in a background service at the back. Unfortunately, seems not fully working, at least couldn't get any sort of notification through it, while tried various of methods according to the docs. The aim of this it should throw a notification upon the specific event has been triggered to know if the service is properly running or not.


You've been really helpful, you've wrote in detail as possible, so very appreciated. No worries, we can improve it, from my end will provide you more research information, and if possible further samples. Unfortunately time is something we cannot control, and we cannot either do everything, which I understand and I hope for others to do more contribution as well, in any way that they could help

Hopefully the sample project, the replies for your answers would help us further progress this.

Cheers 🍺

Best regards,
Red

Hi @red-game-dev, I hope this finds you well too.

First of all, my apologies for the late reply. There was a lot to process in your message and its been hard to find the time to read everything with the peace of mind that this deserves πŸ˜‰

I'm going to reply over your message.

Glad my words gives positive energy, as well glad that the questions I've asked are considered in your plans. Team size, knowledge in some areas, time is all understandable, and especially time as it could be quite time consuming doing certain improvements and integrations, will try to provide as much support as I can from my end.

Many thanks for your understanding, really appreciate that.

About the AutoStarter integration

That is very glad to hear, as well thanks for the detailed information given as it is quite informative.

You are welcome :)

Integration file in Power Saving Manger

Sounds interesting, though I've few questions regards to that -

  • I assume that we do require to forcefully ask the user to accept the permission for power saving mode?

Yes, this decision is not arbitrary. As per Android docs, in order to run anything at a higher frequency than 15 minutes (every 9, 5 or 1 minute, for example) that functionality needs to be core to the app. We take that and we understand that the user needs to accept this for the app to work properly. That's why we don't let the plugin to work if this permission is not accepted. Although if needed, we could consider adding a configuration option to bypass this behaviour, it is something that could be added at some moment.

  • If yes, I assume this functionality in this case won't be available for smaller tasks as well? Since in case the task is executed, is running but is killed, that may be a problem, as not every Android phone may behave the same. Unfortunately as we got too many phone circulating nowadays and may be quite hard to cover all scenarios I believe in this case.

By smaller tasks, do you mean tasks which are meant to run after more than 15 minutes? If that's the case, yes a single task to run in, let's say, 20 minutes won't force the request of disabling power saving for the app. However if what you meant is that you plan to run a single task at some point in less than 15 minutes without repeating, then yes, the permission will be asked here too to ensure reliability.

  • If not, then I assume the AutoStarter will be there for rare scenarios for certain manufacturers or perhaps future-proof if they reduce the timer from 15 minute to lesser.

Yes that's true. However, I see your point. AutoStarter is going to be needed even if the task has to be run at a lower frequency than 15 minutes. What's more, for certain manufacturers, it is going to be needed in order to run any task in background reliably. That changes a bit the idea we had in mind, but for a good reason. Perhaps it should be in a separate plugin which can be optionally used in conjunction with this one during the initialization phase (before calling the NativeScript Task Dispatcher isReady / prepare methods. Another option is to include it and forcefully call its methods at the beginning of the aforementioned methods. Both options look good to me, although I think giving other devs the freedom to use it or not would be preferable, an integral solution looks appealing too. I would like to hear your opinion here, both options involve a similar implementation complexity for us.

Typescript generator
I did use jitpack.io with gradle, and can say I could get any sort of typing's interfaces from it. Perhaps I need to configure something additionally, but have no clue regards to that, as jitpack.io does the rest of the job upon building the app.

You can find further on that in app.gradle in the example TestApp using jitpack.io how it works.

FYI on Jitpack.io: Jitpack provides a lot, as you could import other native libraries as well, both natively and on NS. I assume you may already know about this, since is same as maven, instead it does import from Github.

Didn't know about jitpack.io. Looks interesting, indeed. We will investigate it. About the typings, we used this for other plugins involving a native library integration. What we have to test is if works with Kotlin too. Nevertheless, AutoStarter API is small enough to generate the typings manually, no big problem here.

Interactions
I think as long there are exposed API for us to use, we can do GUI ourselves. We should keep the repository to minimum, without any GUI being involved as a suggestion.

Good point here. I don't see anything wrong in your arguments, I think you're right. If that's the case then we'll use a callback-based approach to allow to optionally execute some arbitrary code before redirecting the user to the settings screen. This way, there will be freedom to implement virtually any mechanism to inform the user about what's going to happen next, perhaps they can even decline going to settings if the callback returns a boolean from its execution.

Functionality period to be added
I fully understand if any other issue or task arise the functionality could be delayed, hopefully with the same app could ease the integration complexities.

For the moment, our conversation by itself its already pushing the developtment forward thanks to the feedback you're providing to us :)

About iOS support

Thank you for very well detailed questions, they answered for us a lot of queries.

You're more than welcome πŸ˜‰

Follow up of What it doesn't support to the full extent?
Quite interesting, which would be quite good features to have in place, especially when running the task in a safe manner, that will raise better credibility as the ideal solution to use. I've checked Herald Project, I believe DispatchQueues is interesting to be used in this case, which probably would make sense. At the time being, I am not sure yet if is the only way or if there are other efficient.

I understand for experience in iOS programming, unfortunately neither I as I would have done some sample or perhaps contributed to solve this issue.

Meanwhile, sharing a small article link from NS docs, which can be used for ApplicationDelegate, but unfortunately is a bit old of documentation, couldn't find any other relevant information yet. Personally still haven't started the investigation on iOS, but if I will have further information or perhaps a solution, I will comment in here.
Link: https://v6.docs.nativescript.org/core-concepts/ios-runtime/how-to/backgroundexecution

This is what I meant in my previous message with the application delegate callbacks to ensure that a task is being executed no mater the UI state at the moment it is being executed (General Purpose Tasks section). However, the second section (Long-running tasks section), although it looks like a good fit for our plugin at first doesn't seems to give the freedom we need to control when the code will be executed, and this is something we require to offer an even functionality in iOS and Android. Anyway, we'll further investigate this possibility, thanks for reminding us about that resource.

Follow up of Will it be supporting them to full extend later? If so, there is a road map when this can be possible?
Interesting, glad is part of the plans!

I understand, would be great if can be prioritized anytime sooner, from my end will give the information necessary if I encounter anything during my research, especially any relevant samples. Hopefully more other people would be interested after reading the thread and could contribute more.

Thanks for that, any new information will be more than appreciated.

Follow up of Does on iOS there is issues like android that it does force close the background service sometimes? Through I search a bit, but couldn't find any relevant issue, perhaps I didn't search correctly if there was.
I see, in the real end is all about Apple's authorization if they allow you to run the background service or not. I believe I need to research further into this, what sort of authorization could potentially be a problem for us, and how to get pass through them and being complaint. I understand, on the uncertainty point and indeed usually is quite hard to get some contribution.

Yes, this is something we have yet to investigate for our use cases too. If we get any relevant information regarding to this, we'll share them with you too as we think it can be interesting for everybody developing this kind of functionalities.

App Sample

Thank you very much for this sample and for the detailed information about its inner workings. This is going to help us a lot in our way to integrating the AutoStarter library. We'll try to try it out during this week.


You've been really helpful, you've wrote in detail as possible, so very appreciated. No worries, we can improve it, from my end will provide you more research information, and if possible further samples. Unfortunately time is something we cannot control, and we cannot either do everything, which I understand and I hope for others to do more contribution as well, in any way that they could help

Hopefully the sample project, the replies for your answers would help us further progress this.

Of course that will help, and so will any further information you can provide us :)

We we'll inform via this channel of any advancements we make in this sense.

Thanks for your support, feedback and interest.

Best regards,
Alberto

Hi @agonper , I'm well thank you! πŸ˜„

My apologies as well, lately been busy with a lot of things and couldn't reply earlier. In fact, was writing it and lost the note by mistake, so I hope I will not forget anything throughout this comment. Will go through your comment and process all the requirements needed, a long with the opinions & suggestions.

About the AutoStarter integration πŸ”‹

Yes, this decision is not arbitrary. As per Android docs, in order to run anything at a higher frequency than 15 minutes (every 9, 5 or 1 minute, for example) that functionality needs to be core to the app. We take that and we understand that the user needs to accept this for the app to work properly. That's why we don't let the plugin to work if this permission is not accepted. Although if needed, we could consider adding a configuration option to bypass this behaviour, it is something that could be added at some moment.

That's interesting part of the docs, I didn't know myself of this specific section, even throughout heavy research was going through. Probably I must have missed this part, and this open further information to learn further. Perhaps that functionality of bypass can be added, yet there should be an important note like the one you've on battery performance part, as I would say really important option.

Permissions as long we would have exposed API that we can do a dialog ourselves or something custom, it would be quite good!

By smaller tasks, do you mean tasks which are meant to run after more than 15 minutes? If that's the case, yes a single task to run in, let's say, 20 minutes won't force the request of disabling power saving for the app. However if what you meant is that you plan to run a single task at some point in less than 15 minutes without repeating, then yes, the permission will be asked here too to ensure reliability.

I see, so perhaps having some sort of exposed API to show this dialog would make it safe for all the plugin users, as well would be perhaps good that we can make it to have the ability to become whitelisted, yet I think is quite hard to achieve that, but could be possible through https://github.com/WanghongLin/CRomAppWhitelist. Possibly that this repo you've seen it as well, as was one of the first repo's found throughout our research, along with Autostarter.

If not, then I assume the AutoStarter will be there for rare scenarios for certain manufacturers or perhaps future-proof if they reduce the timer from 15 minute to lesser.

Yes that's true. However, I see your point. AutoStarter is going to be needed even if the task has to be run at a lower frequency than 15 minutes. What's more, for certain manufacturers, it is going to be needed in order to run any task in background reliably. That changes a bit the idea we had in mind, but for a good reason. Perhaps it should be in a separate plugin which can be optionally used in conjunction with this one during the initialization phase (before calling the NativeScript Task Dispatcher isReady / prepare methods. Another option is to include it and forcefully call its methods at the beginning of the aforementioned methods. Both options look good to me, although I think giving other devs the freedom to use it or not would be preferable, an integral solution looks appealing too. I would like to hear your opinion here, both options involve a similar implementation complexity for us.

Having it as sperated plugin is not a problem, could be done and then need to install them both, like we usually do for @nativescript/{plugin}. Yet the option should be available, but certainly must mention that requires this plugin to be installed in order to X option from configuration to be actually working, without it would not be.

Now I've two approaches here

Approach A
That would make sense, ye we could have it at the .init method, as the following

taskDispatcher.init(appTasks, AppTaskGraph, {
    enableLogging: true,
    enableAutostarter: true,
}).&&

Approach B
Other options that I've in mind and what would I suggest perhaps, can be dependent on the specified task, as a task maybe you do wish it to run long run, but doesn't matter if is killed, some other task the same but you wish it to keep running.
We could have it something like the following

on('startEvent', run('normalTask').every(1, 'minutes').withAutoStarter())

or with a 2nd *arg on run. I wouldn't suggest to be part of on event, I thought about it and in this case I don't think would be good idea. Unless you've a reason, but we can discuss further if you've any opinions regards to that.

on('startEvent', run('normalTask', true).every(1, 'minutes'))

But, this could raise quite some complexity so, perhaps at the beginning we could go with approach A.

Didn't know about jitpack.io. Looks interesting, indeed. We will investigate it. About the typings, we used this for other plugins involving a native library integration. What we have to test is if works with Kotlin too. Nevertheless, AutoStarter API is small enough to generate the typings manually, no big problem here.

It is really, in fact I didn't know about it much until sometime ago, when I started on Autostarter and some others, that I was heavily studying on trying to find a solution for background services, as it is quite crucial for us and the importance of it, is the entire whole system dependent on.

I am not sure if you can extract through typings through that jitpack, since myself I do not get any sort of typings and nor intellisense about. Would say requires some sort of typescript generator, but as you mentioned AutoStarter API is quite small, which could be easily created manually. If I find something related to that that can be done in a native level, along with jitpack, will let you know!

Good point here. I don't see anything wrong in your arguments, I think you're right. If that's the case then we'll use a callback-based approach to allow to optionally execute some arbitrary code before redirecting the user to the settings screen. This way, there will be freedom to implement virtually any mechanism to inform the user about what's going to happen next, perhaps they can even decline going to settings if the callback returns a boolean from its execution.

To be honest, I would really go a callback approach, why not we use Promise in this case? It could ease it up, plus you would have an async possibility, since you may would like to wait until X change is done, before continue further on. Maybe setting up state, or maybe doing something, like some sort of custom modal change. But rest of the reason mentioned on your end, make sense as well, but we could be missing the fact of using async until as specific criteria's are done, before proceed.

About iOS support πŸ“±

This is what I meant in my previous message with the application delegate callbacks to ensure that a task is being executed no mater the UI state at the moment it is being executed (General Purpose Tasks section). However, the second section (Long-running tasks section), although it looks like a good fit for our plugin at first doesn't seems to give the freedom we need to control when the code will be executed, and this is something we require to offer an even functionality in iOS and Android. Anyway, we'll further investigate this possibility, thanks for reminding us about that resource.

You're welcome, and thanks for explaining further on detailed information both for sections

Yes, this is something we have yet to investigate for our use cases too. If we get any relevant information regarding to this, we'll share them with you too as we think it can be interesting for everybody developing this kind of functionalities.

Thanks, very appreciated, it would be very helpful, the same will do on my end!

App Sample
Thank you very much for this sample and for the detailed information about its inner workings. This is going to help us a lot in our way to integrating the AutoStarter library. We'll try to try it out during this week.

You're welcome and please if you encounter any issue, information needed, please feel free to contact!


Of course that will help, and so will any further information you can provide us :)
We we'll inform via this channel of any advancements we make in this sense.

Thank you for all the detailed information given, it was helpful a lot as well for me, as I've done further more research from the links you shared, which gave me more knowledge about more area's to this. Should there be something not understanding from my end, please let me know πŸ˜„

Best regards,
Red

Hi @red-game-dev, hope you are well!

I've been diving in the test app you attached in a previous comment in order to figure out where those errors came from and if the AutoStarter could be integrated in a NativeScript App.

Reported exceptions

Exception 1

android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the  
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

My first though with this exception was that it was generated due to trying to start an activity from app.ts, where the view is not yet materialized. As a rule, the code you add in the app.ts is for initialization purposes, not for interacting with view related processes. So in this case, the app.ts shoud contain:

// imports

taskDispatcher.init(appTasks, AppTaskGraph, {
    enableLogging: true,
})

// Vue initialization

Then, after cleaning that file and move your code to the Welcome.vue component (where the view is materialized, and then there should be no problems when trying to start an activity) and the exception was still there, so I moved to the next exception to see if there were any problems with the activity starting.

Exception 2

Error: java.lang.Exception: Failed resolving method startActivity on class android.content.ContextWrapper

Here the problem was that you were using the wrong methods. The main mistake was to use Application.android.context.startActivity(mPendingIntent) because that startActivity does not exist in context. The correct way (there are others) to start an activity could be:

Application.android.foregroundActivity.startActivity(intent);

Then, in order to use the above method, an Intent must be used (not a PendingIntent). Therefore, the full snippet would be:

// Welcome.vue

const intent = new android.content.Intent(Application.android.context, (com as any).tns.NativeScriptActivity.class);

// Important to add this flag or you will face the Exception 1
intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);

Application.android.foregroundActivity.startActivity(intent);

With this snippet, the activity was started successfully. The interesting part is that if we remove the FLAG_ACTIVITY_NEW_TASK, we get the Exception 1, so my hypothesis was that this flag was missing in the AutoStarter library. I dived into AutoStarters code and I saw that, effectively, the FLAG_ACTIVITY_NEW_TASK` was missing in v1.0.9, but was added to v1.1.0 (they've also changed methods interface). I tried to use that new version but Jitpack's build was failing.

In the end I had to clone the project, build and manually add the AutoStarter v1.1.0 to the application, and after some struggling I was able to make it work:

// Welcome.vue

import AutoStarter = com.judemanutd.autostarter.AutoStartPermissionHelper // From typings

...

const autoStarter = AutoStarter.Companion.getInstance()

const onlyIfSupported = true
const available = autoStarter.isAutoStartPermissionAvailable(Application.android.context, onlyIfSupported)
console.log("AutoStarter available -->", available)

if (available) {
    console.log("Going to launch AutoStarter");
    const openScreen = true
    const newTaskFlag = true
    autoStarter.getAutoStartPermission(Application.android.context, openScreen, newTaskFlag)
}

I hope this has not come to late, but we have been busy those last days. The important thing is that we have seen that the AutoStarter works, yet some problems with Kotlin could arise (I had some indeed, had to downgrade Kotlin version because the functions were not visible). If you have any doubt or any advances let us know πŸ˜„.

Best regards,
Miguel.

Hi @matey97, I'm good, hope you are well as well!

Awesome, glad you had the time to check this out as it is really helpful!

Reported exceptions

Exception 1

My first though with this exception was that it was generated due to trying to start an activity from app.ts, where the view is not yet materialized. As a rule, the code you add in the app.ts is for initialization purposes, not for interacting with view related processes. So in this case, the app.ts shoud contain [...]

Interesting, thought this process is only required throughout the initialization of it, though make sense to be in other views, since is an ongoing process at the end of the day.

Then, after cleaning that file and move your code to the Welcome.vue component (where the view is materialized, and then there should be no problems when trying to start an activity) and the exception was still there, so I moved to the next exception to see if there were any problems with the activity starting.

Yes, this case I've already tried previously even with direct intent, without the pending intent, yet was always throwing the following errors

  • java.lang.Exception: Failed resolving method startActivity on class android.content.ContextWrapper
  • undefined startActivity
  • Unable to start activity com.tns.NativeScriptActivity

Later on the thread, you will see other errors I've seen and how I had to fix, yet this doesn't fix some new errors that has appeared. (From Exception 2 will get into more details)

Exception 2

Here the problem was that you were using the wrong methods. The main mistake was to use Application.android.context.startActivity(mPendingIntent) because that startActivity does not exist in context. The correct way (there are others) to start an activity could be [...]

Yes, I've tried that as well, yet was still undefined the startActivty from my end, which perhaps I am still missing the piece of puzzle in this case. Though, I managed to fix it as the following

(Application.android.foregroundActivity || Application.android.context).startActivity(intent)

Then, in order to use the above method, an Intent must be used (not a PendingIntent). Therefore, the full snippet would be [...]

I've tried that in Welcome.vue, as well as I thought somehow it cannot run through app.ts, and perhaps important parts aren't yet initialized. This simplifies it, which doesn't require pending intent's.

With this snippet, the activity was started successfully. The interesting part is that if we remove the FLAG_ACTIVITY_NEW_TASK, we get the Exception 1, so my hypothesis was that this flag was missing in the AutoStarter library. I dived into AutoStarters code and I saw that, effectively, the FLAG_ACTIVITY_NEW_TASK` was missing in v1.0.9, but was added to v1.1.0 (they've also changed methods interface). I tried to use that new version but Jitpack's build was failing.

Yes, quite awhile ago I've researched that pat, and apparently is a must to do FLAG_ACTIVITY_NEW_TASK, as well this can be set from AndroidManifest.xml on launchMode. Yes, I tried latest as well, which was released circa to 20 days ago, yet apparently for me did remain same issue.

In the end I had to clone the project, build and manually add the AutoStarter v1.1.0 to the application, and after some struggling I was able to make it work

I've tried this part, but couldn't get it to work properly yet, even after applying all these changes mentioned on the comment, I believe I am missing something.

As you mentioned I've applied these in Welcome.vue + The upgrade part that is necessarily
`
import AutoStarter = com.judemanutd.autostarter.AutoStartPermissionHelper // From typings
(This part had to change it into const AutoStarter = com.judemanutd.autostarter.AutoStartPermissionHelper)

...

const autoStarter = AutoStarter.Companion.getInstance()

const onlyIfSupported = true
const available = autoStarter.isAutoStartPermissionAvailable(Application.android.context, onlyIfSupported)
console.log("AutoStarter available -->", available)

if (available) {
console.log("Going to launch AutoStarter");
const openScreen = true
const newTaskFlag = true
autoStarter.getAutoStartPermission(Application.android.context, openScreen, newTaskFlag)
}
An error is thrown as the following, sinceCompaniondoesn't havegetInstance` declared as function, though funnily enough throughout the source of AutoStarter v1.1.0 it has it defined on >> https://github.com/judemanutd/AutoStarter/blob/ea5fca55457facb6f97555e20dcd231b39c6995e/autostarter/src/main/java/com/judemanutd/autostarter/AutoStartPermissionHelper.kt#L352

 TypeError: AutoStarter.Companion.getInstance is not a function

Further on, I tried directly as it was before, without the Companion, which yet throws other errors, such as the following

Perhaps would be possible to have a sample app with these changes, and also it will be possible that this will be integrated with the repository since you were able to get it working properly?

I hope this has not come to late, but we have been busy those last days. The important thing is that we have seen that the AutoStarter works, yet some problems with Kotlin could arise (I had some indeed, had to downgrade Kotlin version because the functions were not visible). If you have any doubt or any advances let us know πŸ˜„.

Thank you for being so helpful, and going through each error mentioning what is the reason behind the error, and as well providing samples of how to be integrated. Although with all the things I've tried, few of them before and now as well again with your changes, there was no luck. Perhaps a sample app would probably be able to provide the solution, yet if this will be integrated with the repository and having the ability of turning it off or on, it would be very helpful as well for other developers. πŸ˜ƒ

The kotlin issue is interesting, cheers for sharing the thread of the issue!

Best regards,
Red.

Hi @red-game-dev, I'm fine!

First of all, I forgot to attach the sample app in the previous message πŸ˜…, so here you have it: TestApp_AutoStarter1.1.0.zip

A couple of things to take in mind:

  • The v1.1.0 AutoStarter is added directly as an aar, located at App_Resources/Android/libs/. I will explain later how I built this aar, in case you also want to do it. Note that the dependency is not added in the App_Resources/Android/app.gradle.
  • AutoStarter typings have been added in native_declarations. Therefore, there is no need to use the (com as any).etc

Now, about the exceptions:

Exception 1

Yes, this case I've already tried previously even with direct intent, without the pending intent, yet was always throwing the following errors

  • java.lang.Exception: Failed resolving method startActivity on class android.content.ContextWrapper
  • undefined startActivity
  • Unable to start activity com.tns.NativeScriptActivity

The first to errors, as I commented in the previous message are caused by trying to use a method that does not exist. The later one could be caused by trying to start the activity (using the correct method) when you are not able to do so, for example, if the main view is not ready. If you moved the code to the Welcome.vue under one of the Vue lifecylce events, that could be the problem. I had problems to make it work from that methods (first time I worked with Vue), and in the end I had to use buttons.

Exception 2

I've tried this part, but couldn't get it to work properly yet, even after applying all these changes mentioned on the comment, I believe I am missing something.

To build the v1.1.0 aar make it working I followed these steps:

  • Clone AutoStarter repository from GitHub
  • Downgrade ext.kotlin_version to 1.4.10. This was the first version I found which made the methods accessible.
  • Add lintOptions { abortOnError false } in android property in build.gradle(Autostarter.autostarter). This is because, in my case, the linter was messing around causing the build to abort.
  • Execute gradle build command for AutoStarter:autostarter, not for AutoStarter:app, which is the demo app.
    gradle_build
  • Locate the generated aar in Autostarter/autostarter/build/outputs/aar/

And to add it to the app as dependency:

  • Place generated aar in App_Resources/Android/libs/
  • Remove previous dependecy from App_Resources/Android/app.gradle. If you don't remove the implementation 'com.github.judemanutd:AutoStarter:1.0.9' from the gradle, I suspect that version will be used.
  • Execute ns clean or remove platforms folder to ensure the new dependency is added to the build.
  • Build the app.

An error is thrown as the following, since Companion doesn't have getInstance declared as function, though funnily enough throughout the source of AutoStarter v1.1.0 it has it defined on...

As I said before, this could be that the method getInstance() is not visible due to compiling in kotlin 1.5.+ (even latests 1.4.X).
One thing I did to check if the methods were available was to use console.dir(object), which prints the methods of the object.

Further on, I tried directly as it was before, without the Companion, which yet throws other errors, such as the following

  • isAutoStartPermissionAvailable doesn't hold 2nd parameter to check if is supported...
  • getAutoStartPermission doesn't hold 2nd and 3rd parameter either...

If the method is found (you can use the console.dir) and the other parameters are not supported is because the v1.1.0 is not being used, which makes sense because you said you had problems building that version and Jitpack is not working for that version. Then I suppose you are using v1.0.9, where the methods were only holding the context, and where getAutoStartPermission fails by not using the required flag.

Thank you for being so helpful, and going through each error mentioning what is the reason behind the error, and as well providing samples of how to be integrated. Although with all the things I've tried, few of them before and now as well again with your changes, there was no luck. Perhaps a sample app would probably be able to provide the solution, yet if this will be integrated with the repository and having the ability of turning it off or on, it would be very helpful as well for other developers.

You're welcome πŸ˜‰. I really hope the sample app attached is helpful. We will try in the near future to integrate the AutoStarter in the plugin, but as said before, we need to take care with Kotlin.

Best regards,
Miguel.

Hi @matey97!

First of all, I forgot to attach the sample app in the previous message πŸ˜…, so here you have it: TestApp_AutoStarter1.1.0.zip

No worries, I understand, sometimes we do write a comment and we forget most important parts! Happens to me as well :)!

A couple of things to take in mind:

The v1.1.0 AutoStarter is added directly as an aar, located at App_Resources/Android/libs/. I will explain later how I built this aar, in case you also want to do it. Note that the dependency is not added in the App_Resources/Android/app.gradle.
AutoStarter typings have been added in native_declarations. Therefore, there is no need to use the (com as any).etc
Now, about the exceptions

Cheers for the in-depth information!

Exception 1 [βœ”οΈ Solved]

The first to errors, as I commented in the previous message are caused by trying to use a method that does not exist. The later one could be caused by trying to start the activity (using the correct method) when you are not able to do so, for example, if the main view is not ready. If you moved the code to the Welcome.vue under one of the Vue lifecylce events, that could be the problem. I had problems to make it work from that methods (first time I worked with Vue), and in the end I had to use buttons.

Understood, now seems it is all fixed that :)

Exception 2 [βœ”οΈ Solved]

To build the v1.1.0 aar make it working I followed these steps
Followed your amazing guide and is all working perfectly fine now!

As I said before, this could be that the method getInstance() is not visible due to compiling in kotlin 1.5.+ (even latests 1.4.X).
One thing I did to check if the methods were available was to use console.dir(object), which prints the methods of the object.

Yes, in fact that was the main issue. I tried to navigate deeper why this happens, and couldn't find much about it unfortunately what is causing the error per se. Yet, I've read your previous thread and as well few others around, regards Kotlin 1.5 few known issues.

If the method is found (you can use the console.dir) and the other parameters are not supported is because the v1.1.0 is not being used, which makes sense because you said you had problems building that version and Jitpack is not working for that version. Then I suppose you are using v1.0.9, where the methods were only holding the context, and where getAutoStartPermission fails by not using the required flag.

Yeah I was using 1.0.9, now is all solved these matters as well!


[βœ”οΈ] Integration done

You're welcome πŸ˜‰. I really hope the sample app attached is helpful. We will try in the near future to integrate the AutoStarter in the plugin, but as said before, we need to take care with Kotlin.

Yes, it was really helpful that I was able to implemented, for my case I just switched off the openScreen, yet everything else is the same. Cheers for the huge help given about this query!

iOS πŸ“±

I believe the next step, is the iOS full extent, will be hard a bit I believe, but I will try to go through it soon after I finish few things related to core of the app, then I can check further this part of iOS and reply with the details. Should there be any details, would be good we keep in sync, as well would encourage others to do the same :)

Reference about iOS discussion
#23 (comment)

Best regards,
Red