Home Screen alias: is script already running?
I used “Add to Home Screen” to put a link to my app on my iPad. If I use the link, it starts up the app fine; if I switch to something else, and then hit the link again, it starts up a second (or third, etc.) instance of my app on top of the previous instance.
If I use the X in the upper left corner to close the latest instance, the older instance is underneath, still working.
How can I tell whether or not my app is already running, and not open a new instance but rather just let the existing instance display?
I’ve looked at the list from
globals()and don’t see anything obvious there.
I like to know that too. Whenever I launch my ui.View app for example via url schema and it was already running then i have two views stacked on each other. I followed two approaches to solve.
I start a thread and checking every second wether the app is in background. If so then I close the view. This is working but of course with the disadvantage that the view also closes when leaving pythonista for something other then restarting the script a second time.
On start of my script I would try two identify all current views and close them before presenting the new view. But I did not succeed to address e.g. find the views.
You may be able to check for running instances as follows
import gc, ui running_views=[v for v in gc.get_objects() if isinstance(v,ui.View) and v.on_screen]
though the on_screen check won't work for views presented as panels.
You could also just set some flag in a global module when your view is on-screen, and clear it when the view is dismissed. Does this make sense?
I tried a mix of both suggestions with the global variable and the instance and onscreen test. But when I launch the app the second time then the global var is empty.
Now I did the trick with the bultins class. That works fine and solves the issue nicely . Thank you so much.
Here is the code
if name == 'main':
try: v=builtins.theview except: v=None if(isinstance(v,ui.View) and v.on_screen ): #console.hud_alert('reuse view') else: #console.hud_alert('create view') v = ui.load_view() v.present('sheet') builtins.theview=v
Thank you! It worked for me, too:
import builtins try: bookView = builtins.navigation except: bookView = None if bookView and isinstance(bookView, ui.View) and bookView.on_screen: print('Reusing existing book view') navigation = bookView inventoryView = builtins.inventory reviewView = builtins.reviews else: reviewView = ui.load_view('views/reviews') inventoryView = ui.load_view('views/inventory') reviewView.flex = 'WH' inventoryView.flex = 'WH' if isPhone: inventoryView.remove_subview(inventoryView['kinds']) titleView = inventoryView['titles'] titleView.width = inventoryView.width-12 navigation = StuffView(frame=inventoryView.frame, name='Books & Stuff') navigation.add_subview(reviewView) navigation.add_subview(inventoryView) navigation.present() builtins.navigation = navigation builtins.inventory = inventoryView builtins.reviews = reviewView
Nice! Can you also see
if 'bookView' in locals() or 'bookView' in globals():?
If you do stick with try/except then I would encourage you to avoid a naked exception (see PEP8) because it can hide syntax and other errors that may take precious time to find. In this case
except NameError:would be safer than
Thanks! I’d already checked in locals() and globals() looking for some place where the running view was still accessible; I couldn’t find it. I double-checked again and it still isn’t there.
Capturing only the necessary exception makes sense, but for me I needed to capture
Another thing I tried to do was check that
builtins.navigationwas an instance of
StuffView, my own subclass of
ui.View, so as to be even more certain that the saved view I’m finding is the view for this app. But
False; I’m assuming this is because the
StuffViewclass was not in locals/globals, and so I had to recreate it; but once recreated, it isn’t the same
StuffViewthat the previous run of Pythonista created
navigationfrom. Whereas it is the same
ui.Viewthat each incarnation’s
Here’s my current code to restore my views from a previous run if they exist:
try: navigation = builtins.navigation except AttributeError: navigation = None if navigation and isinstance(navigation, ui.View) and navigation.on_screen: reviewView = navigation.subviews inventoryView = navigation.subviews else: reviewView = ui.load_view('views/reviews') inventoryView = ui.load_view('views/inventory') reviewView.flex = 'WH' inventoryView.flex = 'WH' if isPhone: inventoryView.remove_subview(inventoryView['kinds']) titleView = inventoryView['titles'] titleView.width = inventoryView.width-12 navigation = StuffView(frame=inventoryView.frame, name='Books & Stuff') navigation.add_subview(reviewView) navigation.add_subview(inventoryView) navigation.present() builtins.navigation = navigation
One of the things I’m assuming here is that
.add_subviewwill always add subviews in the same order. I couldn’t find any means of getting a subview back by name that wouldn’t have been more work than just saving the subviews on