0

I'm facing an issue with my app where I receive a lot of crashes at the line try Realm(configuration: config).

In my code, I'm using the following approach to read the Realm database from both the main app and the widgets:

var config = Realm.Configuration(schemaVersion: 1)
let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.me.myapp")
let newRealmURL = container?.appendingPathComponent("database.realm")
config.fileURL = newRealmURL!

#if TARGET_IS_WIDGET
    config.objectTypes = [EOperationParams.self, ESocketMessage.self, EActivity.self]
#endif

try! Realm(configuration: config)

To ensure data consistency, I have placed the realm file in the app group so that both the app and widgets can access the same data. However, when the target is a widget, I'm adding config.objectTypes with all the objects in my database. This approach has helped reduce memory usage for reading the realm database within the widgets.

While this code usually works fine, I am seeing numerous crashes at the line try Realm(configuration: config) in the "Crashes" section of Xcode's Organizer. Surprisingly, I haven't received any user feedback regarding this issue except from TestFlight users who encounter a crash notification upon launching the app. This crash appears to occur when the app is in the background and triggered by the widget. I am only experiencing this crash when running the widget target. Can someone please assist me in resolving this issue?

UPDATE 1

I added crashlytics and I found a lot of crashes like this:

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=2 "Unable to open a realm at path '': Invalid top array (top_ref, [0], [1]): 17776, 399336, 431888 Exception backtrace: 0...

Or like this:

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=2 "Unable to open a realm at path '/private/var/mobile/Containers/Shared/AppGroup/335A9037-C38C-5D95-AC07-69D3B23BB4B2/database.realm.lock': open() failed: Operation not permitted Path: /private/var/mobile/Containers/Shared/AppGroup/335A9037-C38C-5D95-AC07-69D3B23BB4B2/database.realm.lock Exception backtrace: 0

UPDATE 2

I've made some progress with my issue and have followed the official guide from Realm to downgrade the file protection of the folder containing the Realm files. I've added this code as per their suggestion:

try! FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.completeUntilFirstUserAuthentication],
                                       ofItemAtPath: folderPath)

The previous errors are now resolved, but I'm encountering two new errors:

  1. I'm getting a fatal error: try! expression unexpectedly raised an error:
Error Domain=io.realm Code=20 "Failed to memory buffer:Invalid top array size (ref: 20160, array size: 3236197) file size: 12824, read lock size: some(32768), read lock version: some(2)" UserInfo={Error Code=20, NSFilePath=, Error Name=InvalidDatabase, NSLocalizedDescription=Failed to memory buffer:Invalid top array size (ref: 20160, array size: 3236197) file size: 12824, read lock size: some(32768), read lock version: some(2)}
  1. I've managed to get it sent only from the macCatalyst version, and it says:
Realm file '/.../group.com.me.myapp/database.realm' is currently open in another process which cannot share access with this process. This could either be due to the existing process being a different architecture or due to the existing process using an incompatible version of Realm. If the other process is Realm Studio, you may need to update it (or update Realm if your Studio version is too new), and if using an iOS simulator, make sure that you are using a 64-bit simulator. Underlying problem: Architecture mismatch: SharedInfo size is 1440 but should be 1456.

I would greatly appreciate any insights or suggestions to help resolve this issue. Since it only occurs when the app is in the background, it makes it particularly challenging to debug. If you need any additional information or code, please let me know.

Thank you in advance for your help!

7
  • Realm is very memory efficient so even huge datasets will have very low memory impact due to objects being lazily loaded. So if you're going through extra steps to 'conserve' memory - that may not be needed. Also this try Realm(configuration: config) is not valid code and should be throwing a compiler error "Errors thrown from here are not handled" Commented Jul 16, 2023 at 12:57
  • Does group.com.me.myapp" exactly match one of the strings in the app's App Groups Entitlement? Also, the question states "a lot of crashes" which is vague. One issue is that optionals (which could be nil) are not being handled. This let newRealmURL = container? and this config.fileURL = newRealmURL! are asking for trouble as those optionals could be nil and unexpectedly crash your code. You should handle those as if they could be nil guard let container =... else { print("URL ERROR")... return } for example. Please do more troubleshooting to determine the nature of the crash. Commented Jul 16, 2023 at 13:05
  • Thank you for your response, Jay. In my case, when I used Realm without specifying config.objectTypes, the widget consumed approximately 25 MB of memory out of the 35 MB allocated by iOS for widgets upon initial launch. However, after adding config.objectTypes, the memory usage dropped to around 15 MB. This observation prompted me to include config.objectTypes as it significantly reduced the memory footprint of the widget upon startup. Commented Jul 17, 2023 at 7:45
  • @Jay , the string "group.com.me.myapp" mentioned in the code is not the actual app group used in my app. I cannot share the real app group for privacy reasons, but the value in the code matches the one set in the App Groups Entitlement. As for the use of "a lot of crashes," it indicates a significantly higher number compared to the normal crash rate. Typically, I experience either no crashes or just one per day among 25,000 monthly active users. However, I receive around 25 crashes per day specifically from the widget. Unfortunately, I haven't been able to recreate this crash in any way. Commented Jul 17, 2023 at 7:53
  • Seeing that Realm Objects are lazily loaded, it would surprise me that limiting the Realm Object models would have that much of an impact. I would guess more-so it's something in your code causing memory to be gobbled up. More importantly though, here on SO, questions should include a Minimal, Reproducible Example - e.g. if you can't duplicate it, how can you expect us to? The code in the question is "fine" so I would look elsewhere; casting Realm objects to an Array or using high-level Swift functions often leads to issues. Commented Jul 17, 2023 at 17:33

1 Answer 1

0

We've run into this many times. The error

Invalid top array

is caused by a version mis-match in your Realm file(s).

What that means specifically is that Realm has an underlying file format version and the SDK you're using cannot read that version of the file.

The fix is to update the SDK to a version that can read the file - that will in turn upgrade the file itself.

Without knowing which specific version are installed, I can't say what's needed but often times, ensuring the lastest SDK is installed and then opening the file with Realm Studio will often force an update and 'get them on the same page"

Realm Swift Releases

and

Realm Studio Releases

Be sure to read the release notes in case there any code changes.

For the other error

Unable to open a realm at path

It's possible your dealing with a File Protection issue and this is addressed in the documentation - here is is for reference

Use Realm When the Device Is Locked

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you so much for your response. I appreciate your time and effort in helping me out. I have always used the latest version of Realm, and yet users are still experiencing this error, even if they are new to the app. Looking at the crash history, the start actually coincides with the date I moved realm to the appgroup space. According to a solution proposed on Stack Overflow, the error could be caused by the data protection enabled in the application. stackoverflow.com/questions/47144604/…. What do you think about?
And at the following link I found someone that has the same problem of mine: github.com/realm/realm-swift/issues/6096#issuecomment-742913231
Someone solved in this way: github.com/realm/realm-swift/issues/7596
@Meroelyth Interesting. That seems slightly different than your errors but could be related. Trying to access a file that the app doesn't have permissions on could certainly lead to one of the errors but in general, it won't work one time and then not another. If it doesn't have permissions, it will never have permission. Do you alter file permissions anywhere in your app or have them changed or changed in XCode?
We just implemented this solution, but haven't published it yet. I will keep you up to date. However, it is a solution that seems to be included in the official realm documentation as well: mongodb.com/docs/realm/sdk/swift/realm-files/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.