Is there a way to keep some action rolling in the background of the app to prevent the phone screen from automatically locking?I mean some way to avoid the automatic screen lock that occurs on cell phones
R works normally in a single thread, meaning that if you have some long task running, the shiny interface will not be updated until the task is completed (wherever the user is on a mobile device or not).
You should probably explore the use of the libraries future and promises in conjunction with shiny in order to split the workload between different threads and keep the user interface responsive.
Using promises with Shiny is a good primer on the subject.
Related
I have created a shiny app on the backbone of {golem} + {brochure}, both fantastic packages by #ColinFay. When using single R sessions as suggested in Chapter 16, it is better to use inner-session asynchronous code, so that users aren't blocked waiting for a render function.
In my case I have four modules that output a plot on a dashboard. I would like to send this plotting logic elsewhere while the user interacts with the app. Since brochure is natively a multi-session app infrastructure, is cross-session async capable of keeping users seperate being that it is two separate sessions, or will there still be issues between users on the same endpoint (session)?
TL;DR
Is each brochure page session restricted to one user? or as the docs say, is each page opened a new session and unique (thus only needing cross-session async) -- scroll down to design pattern here to see brochure structure
Do I need to implement inner-session async code blocks with promises + future?
I know this isnt the best SO question but I really could use some lexical insight!
I just created a mobile game with flutter and would like to extend that to a multiplayer online game. So I thought about making it with firebase. I'm rather new to this domain so I hope my questions don't sound too stupid.
As the characters in my game move around fluidly I need to update their positions at least once per frame, so in case of using firebase I would need a cloud function that runs like 60 times per seconds and never ends. This function would then take all the objects in the game (which are stored in the realtime database) and update their positions according to their speed. The updated values are written back to the database to which the clients listen. They update the values in the game and render the objects at the correct positions. Whenever a player interacts with the game somehow another cloud function is called to handle that and update whatever is needed.
Is it possible to make something like this and does it make sense? It does not sound very smooth to me using cloud functions in this way but I don't have another idea of implementing it. And how would it affect the costs? Sound like a lot of function invocations and db reads/writes..
If this is totally unthinkable what could be alternatives? I wouldn't mind too much using another db and or framework to make the game itself.
Thank you very much
Communicating positions etc through a database won't be fast enough for you to do it 60 times per second. You'll have to use some form of mixed UDP and TCP solution and unfortunately that doesn't exist pre-built for Flame like it does for some game-engines, but it might not be too complicated to build one yourself depending on how complex your use-case is.
Like #Fattie suggests, it could be a good idea to try out if PubNub works for you.
Update: There is now an early stages Nakama (Open source game server) integration for Flutter here.
Firebase has utterly no connection to what you are trying to do.
You just use Unity and one of the realtime-multiplayer services - like Photon.
It is inconceivable that as a hobbyist you'd start from scratch and try to write realtime, interframe, predictive quat. networking!
In five minutes ...
https://doc.photonengine.com/en-us/pun/v2/demos-and-tutorials/pun-basics-tutorial/intro
It takes 5 minutes to download the Photon/Unity demo and be playing a realtime multiuser game with robots running around.
You then just learn how to add guns or whatever and add your own models.
Flame ...
Flame is spectacular BTW. To do a R/T MP demo with Flutter/Flame, I'd suggest just using PubNub, which would take no time.
http://pubnub.com/developers/demos/codoodler (all of the demos are terrific). It's the world's major realtime backbone, nothing is faster, they do Flutter so - that's about it.
As described in RStudio reference docs,
shiny server functions can optionally include session as a parameter (e.g. function(input, output, session)). The session object is an environment that can be used to access information and functionality relating to the session.
I never use this parameter in my apps and could be missing something.
What are the practical uses of the session parameter?
Here is my attempt for an overview:
List of use cases:
Customised user interfaces
chat room
games
Javascript communication
Trigger a function when session is ended
global reactive values for modularised shiny apps
updating inputs
Trigger a function when session is ended
E.g. close a database connection, see
How to implement a cleanup routine in R Shiny?.
Stopping a shiny app when browser / session is closed:
How to stop running shiny app by closing the browser window?
Customising the user interface
The user interface will be dependent on the device from which its called.
Is it a mobile or pc, which screen resolution is used etc.
Using fluid pages in the ui will help, but certainly has there limits as well.
With session$clientData$output_{OUTPUT_ID}_height and session$clientData$output_{OUTPUT_ID}_width
you can track how your outputs are rendered for your user.
You could make live adjustments (dont insert my huge title if the plot is too small). Or you can track
the data and adjust your ui after finding the most common ui settings of your users.
User interactions
You can create a local/secret reactiveValue() within that session / for that user and you can set
reactiveValues() outside the server function for "global infos" that are accessible across users/sessions.
That way you can share infos across sessions, but also hide specific values for certain users.
Use Case example: Chat room
https://shiny.rstudio.com/gallery/chat-room.html
Use Case example: Games
Can R Shiny display different views for two simultaneous users, interacting with one another?
Share data between modules
As mentioned in the comment, there is a current open bounty where it is asked to have
global reactive values for modularised shiny apps.
See Shiny modules: Destroy module ui if server-function fails
and
https://appsilon.com/super-solutions-for-shiny-architecture-1-of-5-using-session-data/?nabe=4634331497365504:0.
Finally, there is Some functionality you indirectly use, since there are good wrapper functions / packages for that.
Sending messages to Javascript
(There are good wrappers for this. E.g. shinyjs package).
If you want to integrate javascript in your app and send a message from shiny to javascript you can do it with
session:sendCustomMessage().
See, e.g.
http://www.blog.rdata.lu/post/2017-09-16-communication-between-r-and-d3js/ and
https://shiny.rstudio.com/articles/js-send-message.html.
Updating inputs
You could use session$sendInputMessage(inputId, message) to update inputs.
But again there are already more convenient wrapper functions for this, e.g. updateTextInput().
But it´s interesting to keep in mind for inputs that dont have a helper function.
General overview:
https://shiny.rstudio.com/reference/shiny/latest/session.html
Im learning about using NSOperation, NSOperationQueue for my networking calls to deliver a more responsive UI in my apps' table view.
The result of the networking operation get stored into the realm and displayed in the table view.
This is an infinite scroll table view and as the user gets the end, more data is pulled into the app.
I am wondering what is the best design paradigm to use here, and where is the best spot to clear the realm. I don't want to inflate the app with useless data. I just want them to have data if they log back in with no network (airplane mode).
I also would like to know where the best spot to trigger these networking operations is? cellForRowAtIndexPath perhaps? I am not to sure since I usually just use Alamofire and trigger a network request in viewDidLoad. But these are not cancellable calls.
I've gone through the great tutorials on ray wenderlich but other then the playground examples, I am still not getting a real world application tutorial. If anyone knows of a good one on this subject let me know
thanks
This might be tricky to answer since it all depends on your app, the size/type of data it's displaying and how often you want to perform network fetches. In the end, it will be most likely be a compromise between what 'feels good' and how many system resources need to be consumed to make it happen.
In this particular scenario, Realm is being used as a caching mechanism and nothing more, so when to clear it should probably depend on how aggressively you wish to clear it.
If I was building a system like this, I would decide on a set number of the latest items I would always want to have available and save them in Realm. If the user then decided to start scrolling down beyond that limit, more data would be downloaded and appended to the Realm database as they went. Eventually the user will get tired and scroll back to the top (Or they might even just quit the app and restart from the top). At that point, it would be appropriate to trigger an operation to review the size of the Realm cache and remove as many items as necessary to bring it back to the desired size. If they start scrolling down again, then it's appropriate to just re-download that data.
Unlike SQLite, where items are copied into memory, Realm is very good at lazy-loading resources mapped from disk, so it's not necessary to worry about the number of Realm items in memory, more just the size of the Realm file on disk, which again depends on how big the data you're downloading is.
As for when to trigger another network operation to request more data, it's probably best to do it in tableView(_:willDisplay:forRowAt:). Depending on how large the data to download is (and the size of your table cells are), you should play with it until it feels natural when scrolling at a pretty normal speed. As a starting point, I'd recommend starting at maybe a whole screen-worth of table cells before hitting the bottom of the scroll view.
Good luck!
in my iOS application, I am calling a method called loadData in my viewDidLoad method.
loadData takes data from a local SQLite database and populates an array of items.
In another method, showData, I take the loaded data and show it on the actual screen.
- (void)viewDidLoad {
[super viewDidLoad];
[self loadData];
[self showData];
}
- (void)loadData {
//connects to local SQLite database
//data is loaded into a NSMutableArray called 'myData'
}
- (void)showData {
UIImage *myImage = [UIImage imageNamed:[myData objectAtIndex:0]];
self.imageView.image = myImage;
}
However, this currently does not work because it takes some time for the method loadData to populate my array.
I would like to show a custom progress indicator view that pops up on the screen with a spinning image that I made. This would appear until the method loadData completes, and then showData would be run.
Could someone point me in the right direction or link me to a way to do this? Thank you so much!
The way to do this is to do your database retrieval asynchronously, in a background queue. This can be tricky to do multi-threaded database operations and one simple solution is to simply create a dedicated serial background queue in which you'll do all of your database interactions (thus the database operations, themselves, are running on a single thread). Thus your background process that loads the data will dispatch database operations to this queue, as will any database interactions you would otherwise do from the main queue.
If you're using FMDB, you can do this with FMDatabaseQueue, which handles all of this for you. Or you can write your own. (I'd encourage you to check out FMDB, though. If nothing else, look at how it's doing FMDatabaseQueue and adopt this pattern in your own code.)
If you do this, dispatching the initial load to a background queue that will do all database interactions through this separate dedicated serial database queue, just make sure to dispatch the UI updates of your progress indicator back to the main queue, because all UI interactions should take place on the main queue.
Having said that, there's absolutely no reason why database queries for a user interface should be so slow as to necessitate this, though. I wonder whether it's worth digging into why your database code is so slow, and you may be able to cut the Gordian knot altogether.
A typical example of inefficient database operations is when you store images in the database. Unless you're dealing with very small thumbnail images, SQLite is notoriously inefficient when dealing with BLOB data. The typical solution is to store the images in persistent storage (e.g. your Documents folder), and only save references to those paths in the database. This offers all sorts of potential optimizations.
In your comment, you mention that the database maintains URLs of images. Well, in that case, you can refrain from retrieving the images in your loadData routine, and instead employ "lazy loading" of the images, namely load the images in a just-in-time manner, only as they're needed. You can achieve this using a UIImageView category that does asynchronous loading, such as SDWebImage or, if you're already using AFNetworking, you can use its UIImageView category. If you google "lazy loading UIImage", you'll probably find tons of wonderful links, tutorials, etc. But both of these categories provide not only a easy "lazy loading" mechanism, but also provide caching of images, etc.
But the ideal scenario, rather than designing a progress view for a slow loading process, just refactor your design, completely eliminating this performance bottleneck. It would be a shame to go through the work of designing a progress view for an inefficient loading interface.