Forum Archive

How do I perform ios “open with” from python code?

djl

With Pythonista I can easily produce a file which will be saved in the Pythonista file system. If it has the appropriate file ending, in this case ".gpx", accessing that file will call up the ios dialog "open with" and a list of possible apps.

Is it possible, using the x-callback-url system, to open the ios app (in this case gaiagps://) with the above file directly from the python code, saving the extra step of clicking on the file?

This line is surely close:
webbrowser.open('gaiagps://demofile.gpx?action=run')

cvp

@djl Sorry if I didn't correctly understand but is that what you want:

console.open_in(file_path)

See also here

cvp

@djl Perhpas you can send the file to Shortcuts app which has the feature "Open in" with only one app...

Edit

Gpx is a text file
Your script could set the file content in the clipboard and start a shortcut script like
- get the clipboard
- open in a particular app

cvp

@djl this works, tested with another app because I don't have gaiagps

import webbrowser
import clipboard

with open(file_path,'rt',encoding='utf-8') as f:
    clipboard.set(f.read())
webbrowser.open('shortcuts://run-shortcut?name=my_shortcut&input=clipboard')

# my_shortcut only contains one command: open in one app

djl

I'm sure there is a complicated work-around, but I'm convinced the is an easy solution. I think two problems are that I don't know the pathname of a file in the Pythonista file which is appropriate in the x-callback-url syntax, and I don't know whether "run" is the action which is routinely sent by ios when the "open in.." dialog of ios is initiated.

djl

@cvp This would probably work, except my shortcut, even though it claims to accept "anything" renames my file "test.gpx" to "test.txt" which is not accepted by the intended app.

sulcud

do you want to copy a file to gaiagps?
Sorry but I don’t understand your question

sulcud

What is the content of that file? Latitude, longitude? I check that the url scheme can recieve
gaiagps://map?lat=value&lng=value&z=value

sulcud

@cvp said:

@djl this works, tested with another app because I don't have gaiagps
```
import webbrowser
import clipboard

with open(file_path,'rt',encoding='utf-8') as f:
clipboard.set(f.read())
webbrowser.open('shortcuts://run-shortcut?name=my_shortcut&input=clipboard')

my_shortcut only contains one command: open in one app

```

Probably this is the simplest answer to your question
But you are right, I download the app and I try that shortcut with that app, and the shortcut app create a txt file with the content of the original file

djl

@sulcud Don't worry about the content of the file, it always works when the file is clicked and "open with" is selected. The problem is the file name must end in ".gpx"

cvp

@djl Add the command "define name" in your shortcut script (I don't know the name in English)
I've installed gaiagps and tested with success

cvp

@djl I think that you never could be able to transmit a Pythonista file name to another app because other app would never be authorized to access (even in read) to the Pythonista Files. "Open in" sends a temporary copy of your file (I think).

cvp

@djl I think it should be possible to use Objectivec UIActivityViewController to "open in" a specific application, see here

cvp

@djl see also this topic

djl

@cvp Beautiful script. It works great for my purposes when "all" is chosen. I wonder whether it could be added to my script with the dialog omitted, automatically popping up the choice of apps after my script has ended.

cvp

@djl In this case, is this not sufficient ?

console.open_in(file_path)
cvp

@djl or

import ui
import time
import dialogs
from objc_util import *

def open_in_with_specified_activities(path_in,uiview):
    global handler_done,SUIViewController_service
    handler_done = False
    SUIViewController_service = None
    def handler(_cmd,obj1_ptr,_error):
        global handler_done,SUIViewController_service
        # obj1_ptr = None if no service selected
        if obj1_ptr:
            obj1 = ObjCInstance(obj1_ptr)
            SUIViewController_service = str(obj1)
        handler_done = True
        return

    vo = ObjCInstance(uiview)
    SUIViewController = ObjCClass('SUIViewController')
    root_vc = SUIViewController.viewControllerForView_(vo)
    main_view = root_vc.view()
    handler_block = ObjCBlock(handler, restype=None, argtypes=[c_void_p, c_void_p, c_void_p])
    if type(path_in) is list or type(path_in) is tuple:
        path = path_in
    else:
        path = [path_in]        
    url_array = []
    for elem in path:
        url_array.append(nsurl(elem))
    UIActivityViewController = ObjCClass('UIActivityViewController').alloc().initWithActivityItems_applicationActivities_(url_array,None)

    UIActivityViewController.setCompletionWithItemsHandler_(handler_block)

    UIActivityViewController.popoverPresentationController().sourceView = main_view
    UIActivityViewController.popoverPresentationController().sourceRect = CGRect(CGPoint(10,10), CGSize(uiview.width,uiview.height))

    root_vc.presentViewController_animated_completion_(UIActivityViewController, True, None)

    while not handler_done:
        time.sleep(1)

    if SUIViewController_service == None:
        SUIViewController_service = 'None'  # for checking at return and use in alert       

    return SUIViewController_service

v = ui.View()
v.frame = (0,0,600,400)
v.background_color = 'white'
v.present('sheet')

service = open_in_with_specified_activities('sample.gpx', v)
print(service)
v.close()
cvp

@omz I always try to understand how the Shortcuts app is able to "open in" a particular application while sending it a file.
I've tried with UIDocumentInteractionController or UIActivityViewController but without success, it always needs an user action in the "open in" menu.
I just tried with Pythonista, passing it a .txt file and Shorcuts has launched Pythonista and has opened the txt file in a tab, thus Pythonista has imported the file.
Is there a Pythonista URL scheme to do that or is that proving that Shortcuts really shares the file?
The shortcut file contains

is.workflow.actions.openin
_WFOpenInAskWhenRun
_WFOpenInAppIdentifier_com.omz-software.Pythonista3¡&XWatchKit

Edit: for info, I've asked it by a email to the old address of Workflow support but without answer, of course because became Apple 😢

I also asked to gaiaGPS how Shortcuts could open a .gpx file into their app and they answer they don't have any integration with Shortcuts nor any URL Scheme for that...
Big mystery

cvp

@omz try this shortcut

Perhaps can you, at start of Pythonista, know how it has been called...

cvp

But, if via share, you would need to choose which script to run...

djl

@cvp I think your code above is fabulous, but I have not been able to strip it down to the bare minimum, without the GUI, and assuming 'all' as the default choice so that the code goes immediately to the "open with" dialog. Could you possibly provide a minimal version of your code? For me it would be perfect if it goes directly from a file name mentioned in the code to the "open with" popup.

cvp

@djl I'm really sorry, but obviously due to my English, I don't understand your request..
The last little script I posted is the minimum code to display the standard open_with of a file, without removing any service, but in this case, it is equivalent to the standard Pythonista console.open_in.

djl

@cvp Thanks! It turns out that console.open_in is the only additional code I need for my project. As a beginner, I was unaware of this statement.

cvp

@djl My first post on this topic already gave it 😂