How to send a file out to other apps on iOS?

336 views
Skip to first unread message

Henrik R.

unread,
Dec 10, 2020, 2:39:37 PM12/10/20
to Kivy users support
Hi!

An expert, Robert 'Planck', here on kivy-users helped me on how to send a file to other apps on Android. But he doesn't have the same knowledge about iOS, and I would like my app to work on both platforms. So, can anyone tell me something about how my Kivy/Python app can 'export' a file on iOS so it can be opened by other apps?

My concrete task is to send a KML file with geographic information to Google Earth to be shown to the user (on iPhones and iPads).

Thank you for any information or hints on that subject!

PS: I don't have an iOS device at the moment to test it on. :-)

Henrik R.

unread,
Dec 14, 2020, 9:16:05 AM12/14/20
to Kivy users support
Are noone using Python/Kivy for iOS apps?

If I can't send a file out of my Kivy app so it can be opened with Google Earth on iOS, then I think it was the wrong decision to develop my app in Kivy to begin with...
I am a bit shocked that something I regard as fundamental for an app seems out of reach when it comes to Python/Kivy apps!

By the way: According to https://support.google.com/earth/thread/87413940 Google Earth doesn't currently have an API so apparently you cannot send the KML file directly to Google Earth. But logically it must be just as good simply getting the file out where other apps can see it.

Thank you in advance.

Henrik R.

unread,
Mar 12, 2021, 3:12:39 PM3/12/21
to Kivy users support
I am still VERY interested in how to export a file from a Kivy app for other apps to open it, in iOS!
It's the only crucial part of my app that only works on Android. I am willing to pay someone for this job.

Henrik R.

Henrik R.

unread,
Mar 26, 2021, 8:49:52 AM3/26/21
to Kivy users support
I am still struggling with how to export a file on iOS so that other apps can open it. In my case my Kivy app creates a KML-file (text file) with geographical data. That file has to be opened with Google Earth.
Is it true, that the only way to do it is to first write it in Objective C and then convert it to calls to PyObjus?

bad.idea

unread,
Mar 26, 2021, 3:12:47 PM3/26/21
to Kivy users support
Try looking at these links. The first is one that I had found in my own searches on this topic, the second is from my own blog.


Regarding your question, I have not found the answer yet to share files between apps, but I do know how to at least create a file and save it to an accessible location. You will need to add two permissions to your info.plist file, and set them to YES, which you access inside XCode:
  • Application supports iTunes file sharing
  • Supports opening documents in place
Then, if you create a file at the  App.get_running_app().user_data_dir in your app, it will be visible in the file browser. That's a start at least, I suspect for your question of how to share between apps (without the files app in-between), that would require Objective-C as you note. I never got there myself. Getting you on that path though, believe that you will have to modify info.plist in XCode before you do anything, until you do that iOS will have you "sandbox'ed" so that nothing enters or leaves.

Note - the Android section of that page is out of date, as best as I can tell it does not work anymore ... I'm aware.

Henrik R.

unread,
Mar 26, 2021, 3:32:35 PM3/26/21
to Kivy users support
Thank you very much! I will look into that.

Henrik R.

unread,
Apr 6, 2021, 10:34:06 AM4/6/21
to Kivy users support
Sorry for not responding earlier. I asked someone to look at it, but they haven't returned.

But it worked! Thank you!

There are some disadvantages though:

1. App.get_running_app().user_data_dir becomes public, so you have to find another place for all the files you don't want to share or to be visible to the user or other apps. I guess I will simply choose App.get_running_app().directory for the internal files.

2. iOS does not only create a folder in the Files App under "On My iPhone". It also creates a folder inside that folder, where the files are put. That's a bit cumbersome!

The advantage is that you don't need Objective C or PyObjus!

On Friday, 26 March 2021 at 20:12:47 UTC+1 bad.idea wrote:

Henrik R.

unread,
Apr 7, 2021, 5:32:58 AM4/7/21
to Kivy users support
Well... Putting my internal files in App.get_running_app().directory did NOT work. I don't have write permission there.
So where can/should I put my internal files, now that App.get_running_app().user_data_dir is 100% public? Should I try one of the Plyer StoragePath-s.

Henrik R.

unread,
Apr 7, 2021, 3:21:39 PM4/7/21
to Kivy users support
I experimented with the Plyer.StoragePath-s and found ONE I can write to where the files continue to be hidden for the user: storagepath.get_home_dir()

I haven't fully tested the following yet. Is it impossible to preserve the Python indentation (and colors)?:

class RootLayout(FloatLayout):

def __init__(self, **kwargs):
super().__init__(**kwargs)

# iOS: How to at least create a file and save it to an accessible location:
# You will need to add two permissions to your info.plist file, and set them to YES, which you access inside XCode:
#
# Application supports iTunes file sharing
# Supports opening documents in place
#
# Then, if you create a file at the App.get_running_app().user_data_dir in your app, it will be visible in the file browser.
# The key UISupportsDocumentBrowser may also be relevant.

app = App.get_running_app()

global configfilename, targetsfilename, internal_files_path, shared_files_path, app_dir_readonly
app_dir_readonly = app.directory
if platform == 'ios': internal_files_path = storagepath.get_home_dir()
else: internal_files_path = app.directory
shared_files_path = app.user_data_dir
configfilename = os.path.join(internal_files_path, configfilename1)
targetsfilename = os.path.join(app_dir_readonly, targetsfilename1)

Robert

unread,
Apr 7, 2021, 9:06:57 PM4/7/21
to Kivy users support
Hendrick
This post is a flashback to the related Android discussion we had a few months ago.
Back then the Android approach was a custom p4a.
Time passed....more time passed....

It is based on my newer understanding of Android storage across all versions
But it does require the file to be in a public place (which the app could delete when it resumes).

Any way, its off the current topic, just FYI if you ever want to go back there 😲 🤣

Henrik R.

unread,
Apr 8, 2021, 6:08:06 AM4/8/21
to Kivy users support
Hi Robert!
Thank you for the information! But there are so many important things in life and so extremely little time, so I will not spend more time on that Android file share as long as it still works! :-)

Henrik R.

unread,
Apr 8, 2021, 3:05:45 PM4/8/21
to Kivy users support
Strange!
I am quite sure my small test app could copy a file to Plyer.storagepath.get_home_dir() on a physical iPhone 7 when running from Xcode - yesterday. But today it doesn't work! Neither after restarting the Mac nor after creating a 'new' identical project in Terminal using "toolchain create <app-name> <path-to-app-name>"
WHAT...?

Henrik R.

unread,
Apr 9, 2021, 12:14:15 PM4/9/21
to Kivy users support
I don't know what happened last night... Now it works again, in a more thorough test...

Henrik R.

unread,
Apr 10, 2021, 2:27:08 PM4/10/21
to Kivy users support
Finally solved!
Conclusions:
1. Plyer.storagepath.get_home_dir() is writeable in the iPhone 7 SIMULATOR in Xcode, but NOT on a physical iPhone 7...
2. Plyer.storagepath.get_home_dir() + 'Library/' is writeable on both!

Henrik R.

unread,
Jul 8, 2021, 2:43:08 AM7/8/21
to Kivy users support
Oops! Error!:

internal_files_path = app.directory

On Android, these files are deleted when the app is updated!
I have changed it to the following. But I am not 100% sure if this preserves the files in internal_files_path when the app is updated on iOS?:

app = App.get_running_app()
print("1. app.directory = ", app.directory)
print("2. app.user_data_dir = ", app.user_data_dir)

global internal_files_path, shared_files_path, app_dir_readonly

app_dir_readonly = app.directory
print("4. platform = ", platform)
# The following changed July 5th, 2021:

if platform == 'ios':

     print("3. storagepath.get_home_dir() = ", storagepath.get_home_dir())
     internal_files_path = storagepath.get_home_dir() + 'Library/'
     print("5. storagepath.get_home_dir()/Library/ = ", internal_files_path)
     shared_files_path = app.user_data_dir

else: # == Android for any practical purposes...

     internal_files_path = app.user_data_dir # Used for 'cur-ref-point'-files and other internal files.
     shared_files_path = app.user_data_dir

On Wednesday, 7 April 2021 at 21:21:39 UTC+2 Henrik R. wrote:
Reply all
Reply to author
Forward
0 new messages