AKROGIS / Park-Observer

An iOS application for mapping observation in National Parks
Other
1 stars 1 forks source link

Unknown problem causing data loss #9

Open regan-sarwas opened 3 years ago

regan-sarwas commented 3 years ago

From Dylan Schertz:

On the sheep survey in GAAR we had my first significant data loss from Park Observer (we were able to patch things together from the pilot GPS). I wish I was more directly involved in the download so I would be more sure of somethings but they had loaded a POZ onto the computer and it wasn't giving them any data so they called me over. When I looked at it the POZ was about 24 kb (or so) so it seems like there was actually no data in the POZ. I did later confirm the POZ was empty by unzipping it and looking at all the tables. I looked at the iPad and saw data but also saw two duplicate error messages (something about mission not found unable to save). I switched the active survey to see if the other one also had data from the same day or it was all recorded on the one, there was nothing in the other survey and when I switched back to the first survey the data that was previously there had disappeared. I took this iPad outside collected data multiple times and exported that data successfully. I am not sure what happened that one time.

The version number was the full release of 2.0, iOS 14.5, and I was using the attached obsprot I wrote (a slight modification of the short form survey).

In the interest of not having this happen again I uninstalled park observer from that iPad, reinstalled it, and loaded the obsprot that I pulled from another iPad. I used this iPad on later days and had no issues with it.

I am curious if you have any thoughts as to what may have happened

sheep_medium_v1_30June2021.obsprot.txt

regan-sarwas commented 3 years ago

My initial guess is that for some reason the app was unable to create a "mission" in the database, and without that, all subsequent points were drawn on the screen, but not inserted into the database.

To clarify: the CoreData referential integrity (i.e. a missing mission) is not checked until the app tries to save the CoreData to disk. The app can draw GPS points and Observation on the map without a mission, but cannot be saved and will display an error message. This would explain the behavior seen above.

regan-sarwas commented 3 years ago

Assumption: Some object in the core data model requires a non-optional Mission and it's mission property is nil when CoreData tries to save, which causes an exception and the error message. Only three CoreData entities have a mission property and all three are required: 1) GpsPoint 2) MissionProperty 3) Observation

The ObjC interface requires that the mission property be a nullable on the three classes, so it is possible to create them without a mission. However, the managed objects can only be created in CoreData with the NSManagedObject.init(context:) constructor, the NSManagedObject.init(entity: insertInto:) constructor, or the NSEntityDescription.insertNewObject(forEntityName: into:) method. ParkObserver provides no additional init() constructors. Searching the code for (context: and (entity:, reveals that it the CoreData classes are never constructed this way. Similarly insertNewObject is only called 7 times, once within each of the 7 coredata classes, and always in the static new(in:) function provided by the class.

Therefore it appears impossible to create an object that requires a mission without a mission. Maybe one of the mission properties is set to nil after creation

a search for .mission = in the code base reveals that outside of the tests, these three classes never have the mission property changed. It is only set in the functions identified above. Of note the ObservationPresenter has an optional mission property, but as expected, there is a guard against a null value before it is used.

Conclusion: It appears impossible for any of the 3 core data classes that require a non-null mission to be in a state without a mission when the app tries to save the core data objects.

regan-sarwas commented 3 years ago

Two new assumptions: 1) The error is a red herring. there is still a referential integrity problem (we can check), but it is not with the mission. 2) Something in the app is triggering a rare bug in Apple's core data code. This is highly unlikely and will be impossible to pursue without a reproducible test case.

The other required CoreData properties are:

AdhocLocation.map/latitude/longitude AngleDistanceLocation.observation/angle/distance/direction GpsPoint.latitude/longitude/timestamp Map.name

regan-sarwas commented 3 years ago

Continuing the search for a referential integrity problem with CoreData that could cause the save to fail.

The following discussion ignores exceptions in the test code

regan-sarwas commented 3 years ago

Solution may be to save more often. However, I am already saving more than I remembered. Saving is done in the following conditions:

The code could also do a save after every N GPS points in the track log. where N represents a few minutes of data collection.

The error messages are not erased, so they will accumulate if the user cannot save. This should be enough of an annoyance to get their attention that something is wrong.