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

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!

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!

UIDocumentPickerController access denied Cocoa Error 257

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?

Rewrite or delete existing .png file in IOS swift apllication

I would like to add the text on my .png image which exist in my swift application and REPLACE my old image with this edited image.
But when I am trying to remove old image I am getting the error message :
Error : Error Domain=NSCocoaErrorDomain Code=513 "“Background.png”
couldn’t be removed because you don’t have permission to access it."
UserInfo={NSFilePath=/var/containers/Bundle/Application/57134C17-50A5-
4709-9E3B-8013733175BA/SignatureApp.app/Background.png, NSUserStringVariant=(
Remove
), NSUnderlyingError=0x12cd8c150 {Error
Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
Code which I am using to remove my old png file is :
let path = NSBundle.mainBundle().pathForResource("Background", ofType: "png")!
let fileManager = NSFileManager.defaultManager()
do {
try fileManager.removeItemAtPath(path)
}
catch let error as NSError {
print("Error: \(error)")
}
Can anybody give an idea how is it possible to rewrite or delete existing .png file in IOS swift aplication?
I don't believe you can do this. The image is part of your app bundle. You would need to upload a new application.
Instead you could store the image in the documents or cache directory and in your code check if that file exists and load it instead of Background.png.

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. :)

iOS 9 read file permission

In iOS 9+ I get a nil on any attempt to read from file. The file in this case is a image file path.
using
NSData(contentsOfFile: stringpath, options: NSDataReadingOptions.DataReadingUncached)
or
NSData(contentsOfFile: stringpath)
Actions:
I have removed the "file://" from the path and it now has a permissions issue.
Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_0048.JPG” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/var/mobile/Media/DCIM/100APPLE/IMG_0048.JPG, NSUnderlyingError=0x13f978f50 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
I have added the NSAllowArbitraryLoads and set it to true.
I have tried to look for the file myself using "NSSearchPathDirectory" however the paths do not match in any way
I encountered this error because I was attempting to access multiple files in the same block. The fix that worked for me was changing the code structure such that each file url was obtained, then read from, before attempting to get the next file url.
You are most likely getting this error, because iOS apps only have access to files within its sandbox. See Apple documentation on file systems for details.
In your Application, you don't have permission to access the file of /var/mobile/Media/DCIM/100APPLE/IMG_0048.JPG, because of Sandboxing.
So, whatever you do, you can't initialize NSData or UIImage with the file path. But you can access the file of /var/mobile/Media/DCIM/100APPLE/xxx.mov with AVURLAsset. In my application, I extracted the data rather than URL from gallery by Photos kit and initialized UIImage with the data.
PHImageManager.default().requestImageData(
for: assetObject!, options: options,
resultHandler: {
data, _, _, _ in
if data != nil {
self.assetUrl = movieMaker.createMovieFrom(imageData: data!, duration: Int(CXPreparetValue.imageDuration))
}
})
it works for me! If you have other opinions, please tell me.
In my case, the file permissions were too restrictive, so I couldn't read the file.
Adding read+write permissions to the file before accessing it solved it.
do {
// Retrieve any existing attributes
var attrs = try FileManager.default.attributesOfItem(atPath: stringpath)
let existing = (attrs as NSDictionary).filePosixPermissions()
// Set the read+write value in the attributes dict
attrs[.posixPermissions] = existing | 0b110000000
// Update attributes
try FileManager.default.setAttributes(attrs, ofItemAtPath: stringpath)
// Read data from file
let data = try Data(contentsOf: URL(fileURLWithPath: stringpath, isDirectory: false), options: .uncached)
print("success: \(data.count)")
} catch {
print(error)
}
That works if you're in a folder with enough permissions, as you can change the files permissions even if you didn't had read permission on the file previously. This solution was applied at https://github.com/ZipArchive/ZipArchive/issues/293.

Resources