@@ -155,7 +155,10 @@ enum State: Int, CustomStringConvertible {
155155 }
156156
157157 let manager = MageSessionManager . shared ( ) ;
158+ let methodStart = Date ( )
159+ NSLog ( " TIMING Fetching Observations for event \( currentEventId) @ \( methodStart) " )
158160 let task = manager? . get_TASK ( url, parameters: parameters, progress: nil , success: { task, responseObject in
161+ NSLog ( " TIMING Fetched Observations for event \( currentEventId) . Elapsed: \( methodStart. timeIntervalSinceNow) seconds " )
159162 guard let features = responseObject as? [ [ AnyHashable : Any ] ] else {
160163 success ? ( task, nil ) ;
161164 return ;
@@ -167,47 +170,72 @@ enum State: Int, CustomStringConvertible {
167170 return ;
168171 }
169172
173+ let saveStart = Date ( )
174+ NSLog ( " TIMING Saving Observations for event \( currentEventId) @ \( saveStart) " )
170175 let rootSavingContext = NSManagedObjectContext . mr_rootSaving ( ) ;
171176 let localContext = NSManagedObjectContext . mr_context ( withParent: rootSavingContext) ;
172177 localContext. perform {
178+ NSLog ( " TIMING There are \( features. count) features to save, chunking into groups of 250 " )
173179 localContext. mr_setWorkingName ( #function)
180+
174181 var chunks = features. chunked ( into: 250 ) ;
175182 var newObservationCount = 0 ;
176183 var observationToNotifyAbout : Observation ? ;
184+ var eventFormDictionary : [ NSNumber : [ [ String : AnyHashable ] ] ] = [ : ]
185+ if let event = Event . getEvent ( eventId: currentEventId, context: localContext) , let eventForms = event. forms {
186+ for eventForm in eventForms {
187+ if let formId = eventForm. formId, let json = eventForm. json? . json {
188+ eventFormDictionary [ formId] = json [ FormKey . fields. key] as? [ [ String : AnyHashable ] ]
189+ }
190+ }
191+ }
192+ localContext. reset ( ) ;
193+ NSLog ( " TIMING we have \( chunks. count) groups to save " )
177194 while ( chunks. count > 0 ) {
178195 autoreleasepool {
179196 guard let features = chunks. last else {
180197 return ;
181198 }
182199 chunks. removeLast ( ) ;
183-
200+ let createObservationsDate = Date ( )
201+ NSLog ( " TIMING creating \( features. count) observations for chunk \( chunks. count) " )
202+
184203 for observation in features {
185- if let newObservation = Observation . create ( feature: observation, context: localContext) {
204+ if let newObservation = Observation . create ( feature: observation, eventForms : eventFormDictionary , context: localContext) {
186205 newObservationCount = newObservationCount + 1 ;
187206 if ( !initial) {
188207 observationToNotifyAbout = newObservation;
189208 }
190209 }
191210 }
192- print ( " Saved \( features. count) observations " )
211+ NSLog ( " TIMING created \( features. count) observations for chunk \( chunks . count ) Elapsed: \( createObservationsDate . timeIntervalSinceNow ) seconds " )
193212 }
194213
195214 // only save once per chunk
215+ let localSaveDate = Date ( )
196216 do {
217+ NSLog ( " TIMING saving \( features. count) observations on local context " )
197218 try localContext. save ( )
198219 } catch {
199220 print ( " Error saving observations: \( error) " )
200221 }
222+ NSLog ( " TIMING saved \( features. count) observations on local context. Elapsed \( localSaveDate. timeIntervalSinceNow) seconds " )
201223
202224 rootSavingContext. perform {
225+ let rootSaveDate = Date ( )
226+
203227 do {
228+ NSLog ( " TIMING saving \( features. count) observations on root context " )
204229 try rootSavingContext. save ( )
205230 } catch {
206231 print ( " Error saving observations: \( error) " )
207232 }
233+ NSLog ( " TIMING saved \( features. count) observations on root context. Elapsed \( rootSaveDate. timeIntervalSinceNow) seconds " )
234+
208235 }
209236
210237 localContext. reset ( ) ;
238+ NSLog ( " TIMING reset the local context for chunk \( chunks. count) " )
211239 NSLog ( " Saved chunk \( chunks. count) " )
212240 }
213241
@@ -218,6 +246,7 @@ enum State: Int, CustomStringConvertible {
218246 NotificationRequester . observationPulled ( observationToNotifyAbout) ;
219247 }
220248
249+ NSLog ( " TIMING Saved Observations for event \( currentEventId) . Elapsed: \( saveStart. timeIntervalSinceNow) seconds " )
221250 DispatchQueue . main. async {
222251 success ? ( task, responseObject) ;
223252 }
@@ -550,12 +579,14 @@ enum State: Int, CustomStringConvertible {
550579 }
551580
552581 @discardableResult
553- @objc public static func create( feature: [ AnyHashable : Any ] , context: NSManagedObjectContext ) -> Observation ? {
582+ @objc public static func create( feature: [ AnyHashable : Any ] , eventForms : [ NSNumber : [ [ String : AnyHashable ] ] ] ? = nil , context: NSManagedObjectContext ) -> Observation ? {
554583 var newObservation : Observation ? = nil ;
555584 let remoteId = Observation . idFromJson ( json: feature) ;
556585
557586 let state = Observation . stateFromJson ( json: feature) ;
558587
588+ // NSLog("TIMING create the observation \(remoteId)")
589+
559590 if let remoteId = remoteId, let existingObservation = Observation . mr_findFirst ( byAttribute: ObservationKey . remoteId. key, withValue: remoteId, in: context) {
560591 // if the observation is archived, delete it
561592 if state == . Archive {
@@ -574,7 +605,7 @@ enum State: Int, CustomStringConvertible {
574605 }
575606 }
576607
577- existingObservation. populate ( json: feature) ;
608+ existingObservation. populate ( json: feature, eventForms : eventForms ) ;
578609 if let userId = existingObservation. userId {
579610 if let user = User . mr_findFirst ( byAttribute: ObservationKey . remoteId. key, withValue: userId, in: context) {
580611 existingObservation. user = user
@@ -662,7 +693,7 @@ enum State: Int, CustomStringConvertible {
662693 if state != . Archive {
663694 // if the observation doesn't exist, insert it
664695 if let observation = Observation . mr_createEntity ( in: context) {
665- observation. populate ( json: feature) ;
696+ observation. populate ( json: feature, eventForms : eventForms ) ;
666697 if let userId = observation. userId {
667698 if let user = User . mr_findFirst ( byAttribute: UserKey . remoteId. key, withValue: userId, in: context) {
668699 observation. user = user
@@ -752,15 +783,15 @@ enum State: Int, CustomStringConvertible {
752783 }
753784
754785 @discardableResult
755- @objc public func populate( json: [ AnyHashable : Any ] ) -> Observation {
786+ @objc public func populate( json: [ AnyHashable : Any ] , eventForms : [ NSNumber : [ [ String : AnyHashable ] ] ] ? = nil ) -> Observation {
756787 self . eventId = json [ ObservationKey . eventId. key] as? NSNumber
757788 self . remoteId = Observation . idFromJson ( json: json) ;
758789 self . userId = json [ ObservationKey . userId. key] as? String
759790 self . deviceId = json [ ObservationKey . deviceId. key] as? String
760791 self . dirty = false
761792
762793 if let properties = json [ ObservationKey . properties. key] as? [ String : Any ] {
763- self . properties = self . generateProperties ( propertyJson: properties) ;
794+ self . properties = self . generateProperties ( propertyJson: properties, eventForms : eventForms ) ;
764795 }
765796
766797 if let lastModified = json [ ObservationKey . lastModified. key] as? String {
@@ -785,7 +816,7 @@ enum State: Int, CustomStringConvertible {
785816 return self ;
786817 }
787818
788- func generateProperties( propertyJson: [ String : Any ] ) -> [ AnyHashable : Any ] {
819+ func generateProperties( propertyJson: [ String : Any ] , eventForms : [ NSNumber : [ [ String : AnyHashable ] ] ] ? = nil ) -> [ AnyHashable : Any ] {
789820 var parsedProperties : [ String : Any ] = [ : ]
790821
791822 if self . event == nil {
@@ -798,19 +829,29 @@ enum State: Int, CustomStringConvertible {
798829 if let formsProperties = value as? [ [ String : Any ] ] {
799830 for formProperties in formsProperties {
800831 var parsedFormProperties : [ String : Any ] = formProperties;
801- if let formId = formProperties [ EventKey . formId. key] as? NSNumber , let managedObjectContext = managedObjectContext, let form : Form = Form . mr_findFirst ( byAttribute: " formId " , withValue: formId, in: managedObjectContext) {
802- for (formKey, value) in formProperties {
803- if let field = form. getFieldByName ( name: formKey) {
804- if let type = field [ FieldKey . type. key] as? String , type == FieldType . geometry. key {
805- if let value = value as? [ String : Any ] {
806- let geometry = GeometryDeserializer . parseGeometry ( json: value)
807- parsedFormProperties [ formKey] = geometry;
832+
833+ if let formId = formProperties [ EventKey . formId. key] as? NSNumber {
834+ var formFields : [ [ String : AnyHashable ] ] ? = nil
835+ if let eventForms = eventForms {
836+ formFields = eventForms [ formId]
837+ } else if let managedObjectContext = managedObjectContext, let fetchedForm : Form = Form . mr_findFirst ( byAttribute: " formId " , withValue: formId, in: managedObjectContext) {
838+ formFields = fetchedForm. json? . json ? [ FormKey . fields. key] as? [ [ String : AnyHashable ] ]
839+ }
840+
841+ if let formFields = formFields {
842+ for (formKey, value) in formProperties {
843+ if let field = Form . getFieldByNameFromJSONFields ( json: formFields, name: formKey) {
844+ if let type = field [ FieldKey . type. key] as? String , type == FieldType . geometry. key {
845+ if let value = value as? [ String : Any ] {
846+ let geometry = GeometryDeserializer . parseGeometry ( json: value)
847+ parsedFormProperties [ formKey] = geometry;
848+ }
808849 }
809850 }
810851 }
811852 }
853+ forms. append ( parsedFormProperties) ;
812854 }
813- forms. append ( parsedFormProperties) ;
814855 }
815856 }
816857 parsedProperties [ ObservationKey . forms. key] = forms;
0 commit comments