Using Document Provider extension without iCloud and DocumentPicker - non UI variant - ios

I recently found some articles and information on using Document Provider extension introduced in iOS 8 to share data between iOS apps.
But almost all the articles and tutorials made use of either iCloud or DocumentPicker.
I am basically looking to save some huge amount of data by creating a, say, Sample.txt file in say an app A. I was wondering from an app B, can I read the contents of Sample.txt file leveraging Document Provider extension?
I would ideally not like to use iCloud and also want a seamless transition from app A to app B on click of a button without any kind of document picker, controller, etc.
Is this possible?

You can just use an App Group for this. Then you can access all files using [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:#"groupname"].
Of course, all apps must have the App Group entitlement added.

Related

How to access user selected folder in iOS

I'm looking for an iOS API that allows accessing a user-selected folder in place (without importing it). It seems to be possible with native frameworks from Apple. How I expect it to work:
User selects a folder using the native document picker.
App gets access to the folder and can read and write its content.
Access is persisted when the app is killed and restarted.
This functionality can be seen in the LumaFusion app. The feature is called "Linked Folders". It allows to add user-selected folders with a native document picker, which are then available for the app. The app can load assets from the previously selected folders. The content of the linked folders is not copied, so it's not an import. External changes to the content of linked folders are immediately visible in the app. Access to the folders is persisted, even if the app is killed and restarted, so the user won't have to choose the folder again.
Any hints of which API can be used to implement such a feature will be appreciated. I would also love to learn if there are any limitations, like the kind of the selected folders, will it work with any destination, including iCloud Drive and third-party file providers, etc. I believe it has to be documented somewhere but can't find the correct Apple Documentation page.
Not sure why I missed it previously, but it seems this documentation answers my question:
Providing Access to Directories
Use UIDocumentPickerViewController to get access to the user-selected directory URL.
Save the URL as a Bookmark for later using bookmarkData method.
Use startAccessingSecurityScopedResource and stopAccessingSecurityScopedResource methods when accessing the bookmarked URL content.

Import core data from free app to paid app in Swift

I have a free version of an app and a paid version. I'd like to give users the option to import their existing data from the free version into the paid version.
Currently the data is stored in Core Data.
I've looked at existing solutions across the internet and SO, the existing solutions suggest making a request from the free application to the paid application using a URL request that contains the data. (e.g. http://mobileorchard.com/lite-to-paid-iphone-application-data-migrations-with-custom-url-handlers/)
So my question is, how is best to implement the solution in Swift:
Is the URL method still the best approach?
Are there any code samples available?
One idea I've had is to convert the entire DB to JSON, then to make a request with the JSON payload and deserialise it into Core Data the other side. Create json string from core data and vice versa?
What I'd do is set up an app group that both apps can access. Put your data in the app group folder and access it from both versions. You don't need to copy it, just leave it where it is.
To do this:
Set up an app group in the "App Groups" section of the target settings in Xcode. Use the same app group for both versions.
Find the location of the app group folder with:
NSURL *groupURL = [[NSFileManager defaultManager]
containerURLForSecurityApplicationGroupIdentifier:
#"GROUP_NAME_HERE"];
Or in Swift:
//swift
let groupURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("groupIdentifier")
Modify your Core Data setup code to put the persistent store file in the directory you found in the previous step.
Since you have existing apps, you probably want to move the existing data into the new app group directory. You'd do this by using migratePersistentStore:toURL:options:withType:error: to move the existing store to the new location from step 2.
At this point both apps can read and write the same directory. When people buy the paid app, the data is literally already there for it.
The keyword is Inter-App Communication. One straightforward way would be to write a URL scheme handler.
From: iPhone OS Programming Guide
Apps communicate only indirectly with other apps on a device. You can
use AirDrop to share files and data with other apps. You can also
define a custom URL scheme so that apps can send information to your
app using URLs.
Note: You can also send files between apps using a
UIDocumentInteractionController object or a document picker. For
information about adding support for a document interaction
controller, see Document Interaction Programming Topics for iOS. For
information about using a document picker to open files, see Document
Picker Programming Guide.
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html

Saving files from an iOS app extension to the containing app

I'm working on adding the ability to use the share button to allow users to save files for use with my main application. Multiple file types (image, video, audio, pdf, etc) need to be supported.
A general use case would be:
The user takes a picture with the standard Camera app or audio recording using the Voice Memos app.
User clicks the Share button and selects my extension from the share list.
Dialog opens up giving the user to opportunity to give a description for the file.
File is saved to where my main app (the containing app) can later access and process it.
I've been able to get to the point where I am prompted to share the file, but I have not been able to find a location to successfully save to that my main app can later read from. Is this even possible? Is there a better way to handle this scenario?
I am currently doing this using Xamarin so debugging is not supported (and logging is minimal). If someone has an answer in Objective C, that would at least help point me in the right direction.
There are a few things that you need to do.
First, your app and your app extension should belong to the same app group:
https://developer.apple.com/library/prerelease/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW19
Then you can access the shared storage with something like this:
var groupUrl = NSFileManager.DefaultManager.GetContainerUrl ("stackoverflow.com.mygroup")
Now you can access files in the directory pointed by groupUrl.
Xamarin's guide to creating Share extensions for iOS: http://developer.xamarin.com/guides/ios/platform_features/introduction_to_extensions/

How to show all apps receives strings in "Open In.." menu?

I'm totally new in iOS development. I'm developing an app processing some strings in UItextview. After the process, I want show "Open In.." menu with all applications can receive text values.
To explain more. What I mean is like this in Android http://developer.android.com/training/sharing/send.html
I took a quick look at the link you posted.
Apple enforces a "sandbox" around apps which greatly limits what you can do.
Off the top of my head here are a few ways to do it:
Define a custom URL scheme in each of your apps. One app would open a URL using the other app's URL scheme, and that would open the other app and pass it the URL.
For a family of apps from the same company you should also be able to set up a common base "bundle ID" and use that to read and write shared entries to the keychain. The keychain is limited to fairly short bits of data however. (It's intended for password strings and the like.)
I haven't used it before, but you should also be able to use the UIDocumentInteractionController class to pass a copy of a document between apps. As I understand it, the sending app presents a document and asks the user to pick an app with which to open the document. When the user picks a target app, the system creates a copy of the document in the target app's documents directory and then tells the target app to open it.

How can I transfer files from one application to another in the same iOS device?

I am writing an iOS application that performs conversion of a file saved by another application on the same device to another format. How can I transfer files from one application to another in the same device? Note that the files are non-textual files.
UIDocumentInteractionController is your friend.
Basically it works like this:
App 1 registers as being able to handle files of type XYZ
App 2 implements UIDocumentInteractionController and will give users the options to "send the file to App1" (I believe this has to be user activated)
App 1 implements -(BOOL)application:openURL:sourceApplication:annotation: and deals with the transferred file which will be saved in your Documents/Inbox directory. From there you can copy the file elsewhere and then manipulated it, making sure you clean up by getting rid of the original one saved on the Inbox folder.
Class reference available here
Document interaction programming guide available here
If you are developing both apps, you can store shared information in the keychain as long as your bundle identifiers conform to the same bundle seed id. See here for more info. Of course, if you are making both applications, you can use a URL scheme to pass in base64 encoded data as well.
Update: As rog said below, UIDocumentInteractionController is great, but it is only available for 4.2 and up, so you are cutting out a major portion of your users if you want to use it.

Resources