UIDocumentPickerController access denied Cocoa Error 257 - ios

I'm trying to import a custom file from one of my apps to another one (let's call them App_A and App_B). If I export the file directly from App_A and in the share sheet I select App_B everything works fine.
My problem is that the file is saved in iCloud Drive so the user can access it through the system's File app. When I try to select the same file from Files app or in App_B through UIDocumentPickerViewController.
In both cases I run the following code (inside UIDocumentPickerDelegate or AppDelegate):
let access = url.startAccessingSecurityScopedResource()
var error: NSError? = nil
NSFileCoordinator().coordinate(readingItemAt: url, error: &error) { (coorURL) in
do{
let data = try Data(contentsOf: coorURL)
}catch{
print("manage error: \(error.localizedDescription)")
}
if access{
url.stopAccessingSecurityScopedResource()
}
}
The error I get is always the same:
Error Domain=NSCocoaErrorDomain Code=257 ... NSUnderlyingError=0x2803e07b0 {Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"}} and url.startAccessingSecurityScopedResource() returns always false.
I'm doing this on Xcode 11.4.1, Swift 5, iOS 13.3.1 on device and 13.4.1 on simulator, but the result doesn't change.
Do you have an idea about this weird error? I suppose that if the user select a file and an app to open it the permission would be granted, but probably I'm missing something. Could you help?

Related

iOS App Group Directory write not permitted

When my app is launching I am creating the directory to store some files that later can be shared with extension.
To get the directory I am calling:
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "com.poster")
Afterwards I am trying to create a custom caches directory.
let posterCachesURL = containerURL.appendingPathComponent("PosterCaches")
do {
try FileManager.default.createDirectory(at: posterCachesURL, withIntermediateDirectories: true)
} catch {
// ... logging error
}
This works just fine, however in production environment some users get this error:
Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file "PosterCaches" in the folder ***folderID***."
UserInfo={NSFilePath=.../PosterCaches,
NSUnderlyingError=0x2401a00c0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
Have anyone faced this issue?
Thank you in advance!

My custom keyboard can't share data because filecoordinationd is crashing (on device)

While this works fine in the Simulator, on device, when my custom keyboard extension tries to open a UIDocument in the shared container written by the containing app, it fails to do so. The following is logged to the Console:
2019-05-10 15:39:09.640305-0700 TagManagerKeyboard[15249:1890026] [claims] 528516A6-B168-43EA-8AAF-B7B1754EE42E grantAccessClaim message failed: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.FileCoordination was invalidated." UserInfo={NSDebugDescription=The connection to service named com.apple.FileCoordination was invalidated.}
2019-05-10 15:39:09.640891-0700 TagManagerKeyboard[15249:1890026] A process invoked one of the -[NSFileCoordinator coordinate...] methods but filecoordinationd crashed. Returning an error.
The error reported to UIDocument.handleError(:userInteractionPermitted:) is not very helpful:
Error Domain=NSCocoaErrorDomain Code=256 "The file “MyFile” couldn’t be opened." UserInfo={NSURL=file:///private/var/mobile/Containers/Shared/AppGroup/3A486D56-F897-4B13-A09F-0B4183686E2C/MyFile}
I open the document in viewDidLoad() of my UIInputViewController subclass:
if let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.mycompany.MyApp")
{
let containerPath = Path(container.path)
let file = containerPath + "MyFile"
self.doc = MyDocument(fileURL: file.url)
debugLog("Extension doc at \(file)")
self.doc.open
{ (inSuccess) in
debugLog("Opened doc: \(inSuccess)")
NotificationCenter.default.post(name: .dataUpdated, object: nil)
}
}
This crash occurs 100% of the time. RequestsOpenAccess is YES in the Info.plist. And again, this works in the simulator. I also tried it on an iOS 9.5.3 iPad I have, and it has a similar crash.
Any ideas why it crashes on device?
This happens because my keyboard did not have “Allow Full Access” to be set.

UIManagedDocument not opening

If you create a new document and a file with same name does not exist in the current directory, then the app freezes. In particular the open function for the UIManagedDocument class does not call its completion handler.
On the other hand if the file does already exist in the current directory, then the open function does call the completion handler. In this case, however, there is a Core Data error printed to console.
I am testing on the iOS 12 Simulator with Xcode 10. Also tested on device.
CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/ruben/Library/Developer/CoreSimulator/Devices/####/data/Containers/Data/Application/####/tmp/mydoc.doccy/StoreContent/persistentStore options:{
NSPersistentStoreRemoveStoreOnCleanupKey = 1;
} ... returned error Error Domain=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={NSUnderlyingException=Can't add the same store twice} with userInfo dictionary {
NSUnderlyingException = "Can't add the same store twice";
}
Example project
Turns out after creating the document and saving to a temporary location, you need to call close first, before importing and opening it.

Unable to read data from Realm file

I want to use realm file with implicit data in my app (In separate project I filled it with data, then made copy of it. Model object is same in both apps).
On simulator, everything is just fine. But when I run app on iPhone, Xcode throws me error.
let path = (NSBundle.mainBundle().pathForResource("testLevel", ofType: "realm"))!
let config = Realm.Configuration(path: path)
let realm = try! Realm(configuration: config) // also tried try! Realm(path: path)
When I print path to .realm file, everything's fine - no nil -
Dont know how to handle it, any ideas? (iOS9)
Error:
fatal error: 'try!' expression unexpectedly raised an error: Error
Domain=io.realm Code=2 "Operation not permitted" UserInfo={Error
Code=2,
NSFilePath=/var/containers/Bundle/Application/7DE151B5-42EE-45C6-8245-B57683EA64D8/sneakers.app/testLevel.realm,
NSLocalizedDescription=Operation not permitted}: file
/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-703.0.18.1/src/swift/stdlib/public/core/ErrorType.swift,
line 54
The Resources folder of your app is read-only, so you can't directly open a writeable Realm file from there.
You'll need to copy it to a directory in which your app has write access (e.g the 'Documents' or 'Application Support' directories) and then try and open it from there. :)

Can I save files/folders in NSSearchPathDirectory.ApplicationDirectory? NSSearchPathDirectory.DocumentDirectory is not ideal for me

iOS 8.4 | Swift 2.1
When I was tried to create a new folder in NSSearchPathDirectory.ApplicationDirectory, I followed with this error on device (in simulator it did worked, though):
code:
let docuPath:NSURL = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.ApplicationDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0])
ConstantsVO.imagePath = docuPath.URLByAppendingPathComponent("imagegallery")
if !NSFileManager.defaultManager().fileExistsAtPath(ConstantsVO.imagePath.path!)
{
do
{
try NSFileManager.defaultManager().createDirectoryAtPath(ConstantsVO.imagePath.path!, withIntermediateDirectories: true, attributes: nil)
}
catch let error as NSError
{
NSLog("\(error.localizedDescription)")
}
catch
{
print("general error - \(error)", terminator: "\n")
}
}
error
2015-11-02 10:53:21.114 Elmo[218:5055] You don’t have permission to
save the file “imagegallery” in the folder “Applications”. fatal error:
'try!' expression unexpectedly raised an error: Error
Domain=NSCocoaErrorDomain Code=4 "The file “imagegallery” doesn’t
exist."
UserInfo={NSURL=file:///var/mobile/Containers/Data/Application/48D90635-0D66-44C2-81CE-F67BAFDA819A/Applications/imagegallery,
NSFilePath=/var/mobile/Containers/Data/Application/48D90635-0D66-44C2-81CE-F67BAFDA819A/Applications/imagegallery,
NSUnderlyingError=0x16e7d540 {Error Domain=NSPOSIXErrorDomain Code=2
"No such file or directory"}}: file
/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-700.0.59/src/swift/stdlib/public/core/ErrorType.swift,
line 50
However, using NSSearchPathDirectory.DocumentDirectory did worked for me and worked expectedly. But in my application, I've feature to share/import through iTunes, so I have the "Application supports iTunes file sharing" TRUE in my info.plist - this exposed NSSearchPathDirectory.DocumentDirectory in iTunes. I don't want the files/folders that I'm saving through my app to be expose to the user in iTunes. Then where should I save the files/folders yet can able to use file sharing through iTunes by exposing NSSearchPathDirectory.DocumentDirectory?
I found the answer from this post is helpful:
Path directory usable in iOS
As far as I know only these are usable on iOS:
NSDocumentDirectory is Documents/ (persistent, backed up, may
be visible in iTunes) NSLibraryDirectory is Library/
(persistent, backed up, not visibe to the user) NSCachesDirectory is
Library/Caches/ (not backed up, may be cleared by system)
Now after I'm using NSSearchPathDirectory.LibraryDirectory the I'm having no NSFileManager error on device nor the directories/files I'm storing inside NSSearchPathDirectory.LibraryDirectory are exposed to the users in iTunes sharing tab.
Great!

Resources