I'm hoping someone can explain what is going on under the hood when I create an AGSGDBGeodatabase (runtime 10.2.5) object using the geodatabaseWithPath method.
Is there any caching of the file going on? I ask because we have run into frequent enough issues with ArcGIS Server that our apps now contain a "Reset" switch to archive runtime geodatabase and downloads a fresh copy. In recent months (since iOS11) I've noticed some very strange behavior related to this. When the geodatabase file is reset the current .geodatabase, .geodatabse-wal, and .geodatabse-shm files are added to a zip file and deleted. A new version is then downloaded and copied to the same location (with the same name). After this is completed our Map View and various list/table views are rebuilt.
The new geodatabase is downloaded, placed in the correct locations, with the correct name, but when a new AGSGDBGeodatabase object is created using the geodatabseWithPath method it appears to be using the information from the old version of the file. Worse yet, new data saved to an AGSGDBFeatureTable created from the AGSGDBGeodatabase is not written to the file, but appears to only exist in memory somehow. Re-starting the app results in that cached data disappearing and the app correctly builds AGSGDBGeodatabase objects using the downloaded replacement file. It is pretty obvious this is happening when looking at the file system in the simulator. The .geodatabase-wal and .geodatabase-shm files are never created when the map is rebuilt, but are instantly created for other .geodatabase files as soon as AGSGDBGeodatabase and AGSGDBFeatureTable objects are created.
Is there someone at ESRI that can shed some light on what is happening behind the scenes when an AGSGDBGeodatabase object is created? I know the stock answer is probably "you should be using v100, but this is a three year old app and this code had been working fine up until the shift to iOS 11 (and the new APFS file system).
We have been having the same issue since the beginning working with the ESRI Runtime SDK (v2.3.2)... We have had to force our apps to restart or ask users to restart the apps once a new database file is downloaded. We think the SDK caches the database file in memory and keeps using it...
That is what I'm suspecting as well. The strange thing is that the SDK seems to be having trouble letting go of the cached copy even if we switch to using a completely different database.
For example we have a wetland determination app where every project has a dedicated SDE/Feature Service. Users are able to switch between projects by checking one in a list view. When that happens the app rebuilds our map and list views to point at the new data source. When we get into our "phantom database" state after a reset the user can switch to a different project and then back and it will still use the phantom in-memory geodatabase instead of the one that is actually living in the file system.
Currently the only way to stop that behavior is to kill and re-lauch the app. I've tried rolling through our code and invalidating every AGSGDBGeodatabase and AGSGDBFeatureService variable to see if that frees up the in-memory object but no luck yet.
We've had this problem as well in 10.2.5. After migrating to 100.3 this problem thankfully went away, but it could be the result of some lingering file or layer references you need to set to nil.
I follow the pattern of downloading a pregenerated .geodatabase in a zip file, overwriting the previous file during the unzip, and then registering it with the server for sync support. During testing of my migrated app, 100.3 registration of the .geodatabase file with the server for sync support proved more finicky than 10.2.5, failing with an error about trying to write a read only file. I found that my code had all sorts of leftover layer and file references into the previous .geodatabase file that needed to be set to nil, and then sync registration ran smoothly. I also had to implement the singleton pattern for the .geodatabase so that load from file was only ever executed in one place rather than various modules. That was how I had multiple references to the file - each module had its own module level variable rather than reusing a static shared instance.
The old 10.2.x Sdk didn't care about those variables so I never cleaned mine up. It also didn't care if you had multiple loads from file for the .geodatabase (100.3 will let you run the load from file command more than once, but then the duplicated layers can't reach a loaded state). I can't help but wonder if this problem you're having would have gone away for me back at 10.2.x had I implemented the singleton pattern and cleaned up my variables.
That makes sense. In some of my other apps (that only have one editable geodatabase to manage) I side-step the issue by naming the downloaded file with the project name and a timestamp and storing the result in NSUserDefaults. If they need to reset their database I just download a new file with a new timestamp and update the stored value.
I was really hoping to avoid having to go that route with the apps that have multi-project support, but maybe that's what I'll have to do.