Flutter SIP call from background service - flutter

I'm making a Flutter SIP call application using dart-sip-ua https://github.com/flutter-webrtc/dart-sip-ua.
I need to use PUSH messages to wake up the application and set the call.
I was able to wake up the application, but how to connect with the current call?
According to the documentation, when making a call, a Call object is created and it has an answer() method.
But when the Call object wakes up, we do not have, respectively, the answer() method either.
I tried to find a solution using SIPUAHelper.findCall(callUUID), but without success: callUUID is generated when the call is initialized, and we do not know it in advance to pass it via PUSH.
That is, I show my CallScreen, but I don’t have a Call object...
Is there really only one option? Wait until the SIP connects itself? It could be 5, 10, 30 seconds...
Help me please. What is the approach to accomplish this task? I feel that my approach is not correct.
Thank you!

One possible solution to your problem could be to store the Call object in a persistent storage, such as a database or a file, whenever it is created. Then, when the application wakes up and receives the PUSH message, you can retrieve the Call object from the storage and pass it to the CallScreen. To do this, you can use a database library like "sqflite" or a file library like "path_provider" to store and retrieve the Call object as a serialized object.
Another option could be to use the "callUUID" of the Call object as a key to store and retrieve it from the storage. You can pass the "callUUID" via PUSH message, and use it to retrieve the Call object from the storage. However, you need to make sure that the "callUUID" is unique and persistent across sessions, so you may need to use a combination of the SIP call ID and the local session ID.
A third option could be to use a global state manager like "Provider" or "Redux" to store the Call object and share it across the application. This way, you can access the Call object from any widget, even if it is not passed directly as an argument. However, you need to be careful with the performance and complexity of using a global state manager, especially if you have a large and complex application.
I hope these suggestions can help you solve your problem

Related

Can i call cubit from another cubit?

i'm working on an application that uses cubits, to manage the state.
Very often when i need to make an api request i need to get my current localization (handle possible exceptions) and then send it to backend. So i guess i should use cubit for the requests and for getting my current localization.
So now my question is how should i handle that? Can i somehow call gpsLocalizationCubit from another cubit? Should i call gpsLocalizationCubit and on success call requestCubit with the use of bloc listener? But then how should i manage loading screen that should be visible for both getting localization and api request?
Another problem is that i have multiple similiar request (that need to use current localization) in single view.
Thanks for the answers :D

ObjectBox Dart/Flutter multi-isolate access

Creating a separate thread for a question stated in a comment...
How does ObjectBox handle concurrent(by different threads/isolates) write requests? example of my use case: FCM "onBackgroundmessage" call runs in a different isolate, the same time multiple write requests might happen. "Hive" is failing in this case completely. Is there any inbuild solution in ObjectBox?
ObjectBox for dart is based on a native ObjectBox core library that handles concurrency using Transactions. Let me pick out few points relevant to the question:
Transactions manage multi-threading; e.g. a transaction is tied to a thread and vice versa.
Read(-only) transactions never get blocked or block a write transaction.
There can only be a single write transaction at any time; they run strictly one after the other (sequential).
As for the isolates in Dart/Flutter - yes, they can safely access the same store, you just need to make sure it really is the same native store instance. To do so, you do the following steps:
Create a Store() instance in your main isolate, as you normally would.
Get ByteData store.reference which contains the information about the native store.
Send this reference to another isolate, via a SendPort.
In another isolate, receive the reference and open a local Store instance, using Store.fromReference(getObjectBoxModel(), msg as ByteData).
Now both isolates have their own Dart Store instances which internally use the same underlying native store. Therefore, their transactions are synchronized, they both see the same data and get notifications on data changes. 🎉
You can see the code I've just described this test case: https://github.com/objectbox/objectbox-dart/blob/461a948439dcc42f3956b7d21b232eb9c2bc26e1/objectbox/test/isolates_test.dart#L50
Make sure you don't close the store while another isolate is still using it. Better not close it at all - that's best practice in normal applications without huge amounts of background work.

Does Firebase functions retain state for google assistant

The scenario is this. I want to show the user one or two items, but I don't want to keep showing the same items over and over again. I don't think Firebase functions will retain state because each function call will activate the function again. So how do I maintain state without having to store it in the database.
No, Firebase Functions don't retain state. In fact, you're not even guaranteed to be running on the same server in between calls to the same webhook.
If you want to maintain the state during the conversation, but between different parts of the conversation, you have two good ways to do it:
If you're using the actions-on-google JavaScript library, you can put data into the app.data field and it will be available in the same place in the next call. (I can't find documentation on this, but its reported in https://plus.google.com/105458329026934344336/posts/Xr1KPiMPzpH)
Since you're using Dialogflow, you can add the state as parameters to a Context. These parameters will remain in the Context, and available to future Intents that expect it as an incoming Context, as long as the Context is active.
If you need to maintain state between conversations, you will need to save that state, probably associated with the anonymous UserID that is passed to you with each request.
These methods are similar to what you have when you're working with web requests for a user.

Asynchronous Calls (specifically iOS geocoding)

I'm wondering how to deal with this particular issue:
I'm creating a place object, which gets initialized with a geographical lat-long pair. Then I use the iOS geocoder to get an address for that coordinate. I want to set that address to one of my instance variables. However, this asynchronous call doesn't get completed in time, so when I instantiate my object and try to display the address, it hasn't been done yet. What are some strategies to deal with this and similar problems?
Thanks! Merry Christmas!
I don't feel like creating an extensive answer on Christmas Eve so I'll give a brief answer here for now, and edit it later if you've got questions and/or want more details.
Asynchronous requests all have delegate/protocol methods that let you know when the request has failed or succeeded. You should use the NSNotification API and register any object that needs the address for a notification that's triggered when the object completes the request. When the object receives the notification, it can then configure its views or whatever it needs to do. In the requestDidFinish (or whatever) method, you should send the notification.
Check out this article for details (as well as some cool stuff about threading!): http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial

iphone RESTful webservices

Not even sure if the title is correct, however, what I'm trying to do is use the standard NSURLConnection class to handle responses from calling my webservice. I am using the POST method to update a database and the GET method to retrieve rows from the database. The problem I have is that these 2 actions may occur simultaneously so that the methods to handle the request may step on each other. In other words in my "connection didReceiveData" method I have 2 paths through the code depending on whether I'm handling a response from a GET or POST request.
I keep track on which request in being processed by an instance variable called requestType. The problem is that since the requests are being executed simultaneously the instance variable is being changed from GET to POST before the GET completes (or vice-versa). My question is how do I maintain 2 separate requests in this scenario? Do I synchronize the requests? Is there a way for threads to work here? Do I create 2 separate objects for each of the requests and have the logic in "didRecieveData" query for which object is being processed? Any help would be much appreciated!!
Dealt with a similar issue in one of our apps. The solution involved creating a class that represents a webservice call, responsible for calling its own url, loading its own data, etc. The call class had a delegate that would handle parsing the responses (in our case, a web service controller). Wound up getting rather complicated, but prevented the issue of NSURLConnections stepping on each other.
Seems like you've created a messy problem by having a class that tries to do too many things. I would suggest taking one of the following three approaches:
1) Write two classes, one for updates and one for retrievals. Each class creates it's own private NSURLConnection object and acts as the delegate for the async notifications received from the NSURLConnection. The classes could possible share some utility parsing code or extend a base object that has that parsing code in it. But the key being that the code calling these classes would instantiate one of them, make the call, and then release it. This will keep your code cleaner and will insure that the event notifications don't get intermingled.
2) Create a single class that, depending on initialization, does either a post or a get with it's own private instance of NSURLConnection. When a call needs to be made, instantiate the class, get the results, and then release the class.
3) Write your connection handling classes so they use the synchronous NSURLConnection method and call that call that class in a background thread.
Either way, clean code and clear object orientation will prevent messy scenarios like the one you're describing.
Create separate objects that handle the calls. If you want to issue multiple requests at once I would strongly recommend looking at NSOperationQueue, and making these objects subclasses of NSOperation... much nicer way to deal with multiple background requests.
A good example is here:
http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/
The idea there is that you use the non-asyncronous web calls, in operations that are run on separate threads. You can still use asynch calls in NSOperation as well, but doing so is a little trickier and for simple calls you probably do not need to.