Write into a database stored in App Group container from extension - ios

I have a sqlite database stored in the App Group container in order to register custom shortcut.
I can read/write into it from the app, but not from the keyboard extension.
It seems that the database is in read-only mode from extensions.
I'm using the following code to access it:
let appGroupDirectoryPath = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(appGroupId)
let dataBaseURL = appGroupDirectoryPath!.URLByAppendingPathComponent("database.sqlite")
Is there a workaround to be able to write into the database from the extension keyboard, or is it completely impossible?
The database is writable from the simulator but not with real devices. I guess it's because permissions are managed differently on MacOS X and iOS.

Figured it out.
For keyboards, there is a property in the Info.plist file called RequestsOpenAccess. You can turn this on to enable write access to the shared container.
However, the end user will have to turn on "full access" in their settings for this keyboard, and they will be prompted with a scary message about how you could be logging their keystrokes.
Here's the Apple article that explains it:
Designing for User Trust for Custom Keyboard

Related

iOS Storage across Developers

I need to create an integration between my app and apps by another developer. There are several ways to store data for an app, some that allow only your app to access it, some that allow other apps by the same developer to access it. But is there an iOS API that allows you store data publicly on the device so that any other app can access it? This data is not secure and cannot be used maliciously.
May not work for your specific needs, but note you can share documents between apps using UISupportsDocumentBrowser. See also here.
UISupportsDocumentBrowser (Boolean - iOS) Specifies that the app is a document-based app and uses the UIDocumentBrowserViewController class.
If this key is set to YES, the user can set the document browser’s default save location in Settings. Additionally, the local file provider grants access to all the documents in the app’s Documents directory. These documents appear in the Files app, and in a Document Browser. Users can open and edit these document in place.
This key is supported in iOS 11 and later.
This would violate iOS security policies and is therefore not possible on device. The only way to enable this is on a jailbroken device.

Is it possible to access File Provider of another iOS app

I'm developing an app that needs to interact with other apps (that are developed by other persons). In order to do that, I wanted to use their File Provider to read and write from that.
I know the group they're using, but I don't know the URL of the File Provider. I need a way to copy some files programmatically.
I tried:
let provider = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.app.ish.iSH")
But it just doesn't work because I don't have the App Group in my App Id.
The iOS apps are sandboxed partly to specifically prevent this kind of thing from happening. Typically we use inter application URLs to communicate between apps. On a standard (non-jailbroken) device I don't believe there's way to read another application's files when you didn't develop that other app and can't control the app group

iOS11 check or change an app's storage location setting

I have recently discovered that an app that I am developing can run into issues if users have chosen that they want the apps storage location to be set to anything different from "Local Storage".
It seems that iOS11 allows any app that uses documents to change the Document Storage placement to any place, even if the app internally does not support iCloud storage, as a result I am getting bad reviews from frustrated users that are changing the default setting to iCloud (or some other cloud vendor) and then realizing that it does not work.
I would like to stop them from changing this setting as in my case it does not make any sense (you don't want to be constantly storing caches of temporary files on the cloud) but I can't seem to find a way to change this (it's an Apple Settings app thing) or at least check the value so I can inform about it's current setting.
Showing a message for all users regardless of what their setting is seems like an extreme solution, so I'd like to know if anyone has managed to find a way to either query the value or change it, any will do for me.

iOS8 custom keyboard accessing user defaults without requesting open access

I'm implementing a custom keyboard for iOS8. I have a containing app that sets a few keyboard specific values to NSUserDefaults so that the keyboard can read from them.
This works fine, however I must set requestsOpenAccess to yes to get this working on device.
This seems like overkill to me, I only want to read a few values from the containing app. I don't want any of the other features of the networked keyboard.
Does any one know if there is a way to read values set in the containing app without requesting open access?
There is no way to share content between host app and keyboard extension without requestOpenAccess.
You have to enabled a shared container for host app and keyboard extension, and use
[[NSUserDefaults alloc] initWithSuiteName:];
to access a shared NSUserDefaults.
Yes it is overkill, but this is the only way.

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.

Resources