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")
Related
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.
I tried link to my account with this code
let storageAccount : AZSCloudStorageAccount;
try! storageAccount = AZSCloudStorageAccount(fromConnectionString: config.getAzureConnection())
let blobClient = storageAccount.getBlobClient()
var container : AZSCloudBlobContainer = (blobClient?.containerReference(fromName: config.getContainer()))!
the "config.getAzureConnection()" contains the right path because i used the same for android app.
In this line try! storageAccount = AZSCloudStorageAccount(fromConnectionString: config.getAzureConnection()) the app crash without error, only (lldb) .
Can someone help me.
Does your error look like this?
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=com.Microsoft.AzureStorage.ErrorDomain Code=1 "(null)": file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-802.0.53/src/swift/stdlib/public/core/ErrorType.swift, line 182
(lldb)
Code=1 is AZSEInvalidArgument, which means that your connection string is invalid. I am a bit confused why you said "the right path", since fromConnectionString takes the string directly, not the path to a file. To see an example of what a correct connection string looks like, please refer to the Getting Started Guide. Basically it looks like this:
"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here"
We will document the error codes properly very soon. Sorry for the confusion!
the app crash without error, only (lldb) .
I am sorry for that SWIFT blob client haven't provide error-handling code whatsoever currently. I will provide some clues to track your issue based on your code.
Before building the storage code, make one change in the project. Go to 'Azure Storage Client Library' -> Build Settings, search for the "Defines Module" setting, and change it to 'YES'.
Please check whether the issue is caused by bad network connection.
You could get error code of this issue by putting your code in a do-catch code block.
do {
//put your code here
} catch let error as NSError {
print("Error code = %ld, error domain = %#, error userinfo = %#", error.code, error.domain, error.userInfo);
}
The SWIFT blob sample has been tested and work well targeting iOS 9.0 and using XCode 7. If you have a different setup, the sample may not run properly. I suggest you use Blob Storage REST API as a workaround.
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. :)
I am trying to use a bundled realm file without success. I know that my realm file was copied successfully to my application’s Directory but I ca not read it.
fatal error: 'try!' expression unexpectedly raised an error: "Unable
to open a realm at path
'/Users/…/Library/Developer/CoreSimulator/Devices/…/data/Containers/Data/Application/…/Documents/default-v1.realm'.
Please use a path where your app has read-write permissions."
func fullPathToFileInAppDocumentsDir(fileName: String) -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,NSSearchPathDomainMask.UserDomainMask,true)
let documentsDirectory = paths[0] as NSString
let fullPathToTheFile = documentsDirectory.stringByAppendingPathComponent(fileName)
return fullPathToTheFile
}
In didFinishLaunchingWithOptions:
let fileInDocuments = fullPathToFileInAppDocumentsDir("default-v1.realm")
if !NSFileManager.defaultManager().fileExistsAtPath(fileInDocuments) {
let bundle = NSBundle.mainBundle()
let fileInBundle = bundle.pathForResource("default-v1", ofType: "realm")
let fileManager = NSFileManager.defaultManager()
do {
try fileManager.copyItemAtPath(fileInBundle!, toPath: fileInDocuments)
} catch { print(error) }
}
And setting the configuration used for the default Realm:
var config = Realm.Configuration()
config.path = fileInDocuments
Realm.Configuration.defaultConfiguration = config
let realm = try! Realm(configuration: config) // It fails here!!! :-)
As the documentation suggests, I have tried as well to open it directly from the bundle path by setting readOnly to true on the Realm.Configuration object. I am not sure if this is something related to Realm or if I am overlooking something with the file system…. I have also tried to store the file in the Library folder.
Realm 0.97.0
Xcode Version 7.1.1
I tried to open the realm file using Realm's browser app and the file does not open anymore. It has now new permissions: Write only (Dropbox). So, I decided to change the file permission back to read/write using file manager’s setAttributes method. Here is how I did it:
// rw rw r : Attention for octal-literal in Swift "0o".
let permission = NSNumber(short: 0o664)
do {
try fileManager.setAttributes([NSFilePosixPermissions:permission], ofItemAtPath: fileInDocuments)
} catch { print(error) }
The realm file can now be open at this path.
That exception gets thrown whenever a low level I/O operation is denied permission to the file you've specified (You can check it out on Realm's GitHub account).
Even though everything seems correct in your sample code there, something must be set incorrectly with the file location (Whether it be the file path to your bundle's Realm file, or the destination path) to be causing that error.
A couple of things I can recommend trying out.
Through breakpoints/logging, manually double-check that both fileInDocuments and fileInBundle are being correctly created and are pointing at the locations you were expecting.
When running the app in the Simulator, use a tool like SimPholders to track down the Documents directory of your app on your computer, and visually ensure that the Realm file is being properly copied to where you're expecting.
If the Realm file is in the right place, you can also Realm's Browser app to try opening the Realm file to ensure that the file was copied correctly and still opens properly.
Try testing the code on a proper iOS device to see if the same error is occurring on the native system.
If all else fails, try doing some Realm operations with the default Realm (Which will simply deposit a default.realm file in your Documents directory), just to completely discount there isn't something wrong with your file system
Let me know how you go with that, and if you still can't work out the problem, we can keep looking. :)
This will occur if you have your realm file open in Realm Studio at same time you relaunch your app. Basically in this case Realm can't get write permissions if Studio already has them.
To add to the solution based on what I've discovered, make note of what error Realm reports when it throws the exception, as well as the type of Error that is passed.
As of writing, Realm documents their errors here:
https://realm.io/docs/objc/latest/api/Enums/RLMError.html
What this means is that you can find out if your Realm file has permissions problems and react to those based on Realm passing you a RLMErrorFilePermissionDenied. Or if the file doesn't exist with RLMErrorFileNotFound.
The tricky thing I'm finding is when you get a more generic RLMErrorFileAccess, but that's for another question on Stack Overflow...
I had the same issue and tried too many ways to fix it. The easiest way to fix this problem is manually creation of the folder XCode cannot reach '/Users/…/Library/Developer/CoreSimulator/Devices/…/data/Containers/Data/Application/…/Documents/...' as explained at https://docs.realm.io/sync/using-synced-realms/errors#unable-to-open-realm-at-path-less-than-path-greater-than-make_dir-failed-no-such-file-or-directory
Once you created this folder and run the project, XCode creates the Realm files inside this folder automatically.
The following code works under iOS-8.x / Swift-1.2 / WatchKit-1.0
// create Realm_DB-File in shared App-Groups Folder
let directory: NSURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(AppConstants.APP_GROUP_IDENTIFIER_KEY)!
let realmPath = directory.path!.stringByAppendingPathComponent(AppConstants.REALM_FILENAME_KEY)
playerRealm = Realm.init(path: realmPath)
But it doesn't work under iOS-9.0.1 / Swift-2.0 / WatchOS-2.0
The two error messages are:
1.) 'stringByAppendingPatchComponent' is unavailable: Use URLByAppendingPathComponent on NSURL instead
2.) Call can throw, but it is not marked with 'try' and the error is not handled
Any help appreciated !
To fix your first issue, you need to cast:
directory.path as NSString
since the path is returning as a String, which in Swift doesn't offer the stringByAppendingPathComponent method.
Second, Swift 2.0 has new error handling, so methods that can throw an error are labeled throws. These methods then require you to add try before the call. See Apple's docs on this: Swift Error Handling
To disable the error handling if you know that the path is guaranteed to work you can simple write:
playerRealm = try! Realm(path: realmPath)