RealmSwift configuration url changing makes Fabric and Firebase integration to fail - ios

I've changed my realm files location cause LSSupportsOpeningDocumentsInPlace and UIFileSharingEnabled are enabled for my app and I don't want that user has the ability to delete realm files.
var configuration = Realm.Configuration.defaultConfiguration
var fileURL = FileManager.default.urls(
for: .applicationSupportDirectory,
in: .userDomainMask
)[0]
configuration.fileURL = fileURL
let realm = try? Realm(configuration: configuration)
Causes Firebase and Fabric fail:
6.1.0 - [Firebase/Analytics][I-ACS0...] Failed to recreate database file.
Error: Error Domain=NSCocoaErrorDomain Code=512 "The file “Application Support” couldn’t be saved in the folder “Library”."
UserInfo={NSFilePath=/Users/MyUser/Library/Developer/CoreSimulator/Devices/01E67E95-1/data/Containers/Data/Application/61B1CB70-1/Library/Application Support,
NSUnderlyingError=0x600001666d60{Error Domain=NSPOSIXErrorDomain Code=20 "Not a directory"}}
And a similar error for Fabric.
If I don't change realm configurations fileUrl then Everything will work.
Any idea why and how to fix.

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!

File not exists while copy from document folder to nsbundle app folder swift

I am trying to save xlsx file from document folder to app folder. Here is code but it showing error:
Error Domain=NSCocoaErrorDomain Code=260 "The file “file1.xlsx” couldn’t be opened because there is no such file." UserInfo={NSFilePath=file:///private/var/mobile/Containers/Data/Application/8AC91C23-3662-44FF-90EF-20F6A34AF61F/Documents/file1.xlsx, NSUnderlyingError=0x16169a60 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
let directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL( documentsUrl, includingPropertiesForKeys: nil, options: [])
let xlsxFiles = directoryContents.filter{ $0.pathExtension == "xlsx" }
let xlsxFileNames = mp3Files.flatMap({$0.URLByDeletingPathExtension?.lastPathComponent})
var fileManager = NSFileManager.defaultManager()
do {
try fileManager.copyItemAtPath(xlsxFiles[0].absoluteString, toPath: NSBundle.mainBundle().resourcePath! + xlsxFileNames[0] + ".xlsx")
}
catch let error
{
print(error)
}
You have two problems. The first one is causing the error you posted in your question.
Both parameters to copyItemAtPath need to be full file paths. Your first argument is just a file name. You need to append the file name to a full path to its location (similar to what you do for the second argument).
The app's bundle is read-only. You can't copy a file to your app's bundle. So even once you fix the first problem, you will have a new problem. If the file is already inside your app's Documents folder, why do you try to copy it to the bundle?

Realm exception Error Domain=io.realm Code=2 "Operation not permitted"

I am struggeling with using a new defaultConfiguration for Realm (I think so...)
So what do I try to achieve. I'd like to change the default Realm URL to an Apple App group based ID because I want to use the same Realm from both the Today Extension of my App as well as my App itself.
I found a (slightly outdated Realm tutorial for WatchKit Extension ) where thy put the following to the AppDelegate:
realmUrl: NSURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.net.exchange.On")!
realmUrl.URLByAppendingPathComponent("db.realm")
var config = Realm.Configuration.defaultConfiguration
config.fileURL = realmUrl
Realm.Configuration.defaultConfiguration = config
This works. But my coding to read from Realm, which was working before that, now crashes with the exeption:
This was working up to that change: `let realm = try! Realm()``
But now it creates this beautiful error ;-)
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm
Code=2 "Operation not permitted" UserInfo={Error Code=2,
NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/4E8402AD-89E4-4138-8B83-CA6B409BB238,
Underlying=n/a, NSLocalizedDescription=Operation not permitted}:
file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-703.0.18.8/src/swift/stdlib/public/core/ErrorType.swift, line 54
I am a bit lost. Hopefully anybody can help me out. TIA John
The problem is that the path fileURL you're setting on Realm's configuration is the path to your app group container, not the path to a file within it. This is due to the following piece of the code:
let realmUrl: NSURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.net.exchange.On")!
realmUrl.URLByAppendingPathComponent("db.realm")
NSURL.URLByAppendingPathComponent(_:) returns a new URL rather than mutating the existing one. Changing the code to something like the following should result in the correct URL being set on the Realm's configuration:
let groupContainerUrl = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.net.exchange.On")!
let realmUrl = groupContainerUrl.URLByAppendingPathComponent("db.realm")

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