@@ -36,7 +36,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3636 GMSServices . provideAPIKey ( Keys . googleMaps. value)
3737 GMSPlacesClient . provideAPIKey ( Keys . googlePlaces. value)
3838
39- migrationToNewPlacesModel ( )
39+ // v1.3 Data Migration
40+
41+ print ( " Begin Data Migration " )
42+ if VersionStore . shared. savedAppVersion <= WhatsNew . Version ( major: 1 , minor: 2 , patch: 1 ) {
43+ migrationToNewPlacesModel { ( success, errorDescription) in
44+ print ( " success: \( success) , error: \( errorDescription) " )
45+ let payload = DataMigrationOnePointThreePayload ( success: success, errorDescription: errorDescription)
46+ Analytics . shared. log ( payload)
47+ }
48+ }
4049
4150 // Update shortcut items
4251 AppShortcuts . shared. updateShortcutItems ( )
@@ -109,98 +118,102 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
109118 // MARK: Helper Functions
110119
111120 /// Convert BusStop and PlaceResult models to new unified Place model.
112- func migrationToNewPlacesModel( ) {
113-
114- // Potentially check version to make sure this only fires once.
121+ func migrationToNewPlacesModel( completion: @escaping ( _ success: Bool , _ errorDescription: String ? ) -> Void ) {
115122
116- //
117- // allStops
118- //
119-
120- // should overwrite existing values
121- // getBusStops()
123+ // "See All Stops" and App Shortcuts data is handled automatically
124+
125+ let dispatchGroup = DispatchGroup ( )
122126
123- //
124- // favorites
125- //
127+ var success = true
128+ var description : String ?
126129
130+ // Favorites Data
127131 let favoritesKey = Constants . UserDefaults. favorites
128132
129133 if
130134 let storedPlaces = userDefaults. value ( forKey: favoritesKey) as? Data ,
131135 let favorites = NSKeyedUnarchiver . unarchiveObject ( with: storedPlaces) as? [ Any ]
132136 {
133- // This will only fire on legacy models
134- convertDataToPlaces ( data : favorites ) { ( places ) in
135- do {
136- let encodedObject = try self . encoder. encode ( places)
137+ // This will only fire on legacy verisions and models
138+ dispatchGroup . enter ( )
139+ convertDataToPlaces ( data : favorites ) { ( places , error ) in
140+ if let encodedObject = try ? self . encoder. encode ( places) , error == nil {
137141 self . userDefaults. set ( encodedObject, forKey: favoritesKey)
138- } catch let error {
139- print ( error)
142+ } else {
143+ success = false
144+ description = " Favorites Conversion Failed: \( error ?? " Encoder " ) "
145+ print ( " [AppDelegate] dataMigration favorites " , error ?? " Encoder " )
140146 }
147+ dispatchGroup. leave ( )
141148 }
142149 }
143150
144- // Update shortcuts
145- // Done in main AppDelegate.swift function
146-
147- //
148- // recentSearches
149- //
150-
151+ // Recent Searches Data
151152 let recentSearchesKey = Constants . UserDefaults. recentSearch
152153
153- // This will only fire on legacy models
154154 if
155155 let storedPlaces = userDefaults. value ( forKey: recentSearchesKey) as? Data ,
156156 let recents = NSKeyedUnarchiver . unarchiveObject ( with: storedPlaces) as? [ Any ]
157157 {
158- convertDataToPlaces ( data: recents) { ( places) in
159- do {
160- let encodedObject = try self . encoder. encode ( places)
158+ // This will only fire on legacy versions and models
159+ dispatchGroup. enter ( )
160+ convertDataToPlaces ( data: recents) { ( places, error) in
161+ if let encodedObject = try ? self . encoder. encode ( places) , error == nil {
161162 self . userDefaults. set ( encodedObject, forKey: recentSearchesKey)
162- } catch let error {
163- print ( error)
163+ } else {
164+ success = false
165+ description = " Recent Searches Conversion Failed: \( error ?? " Encoder " ) "
166+ print ( " [AppDelegate] dataMigration recentSearches " , error ?? " Encoder " )
164167 }
168+ dispatchGroup. leave ( )
165169 }
166170 }
167171
168- // Should show a loading function until everything in here finishes. "Updating database"
172+ // Could show loading UI / "Updating databse" while this happens
173+ dispatchGroup. notify ( queue: . main) {
174+ completion ( success, description)
175+ }
169176
170177 }
171178
172- func convertDataToPlaces( data: [ Any ] , completion: @escaping ( _ places: [ Place ] ) -> Void ) {
179+ func convertDataToPlaces( data: [ Any ] , completion: @escaping ( _ places: [ Place ] , _ error : String ? ) -> Void ) {
173180 var places = [ Place] ( )
181+
174182 for item in data {
175183
176- var place : Place !
184+ var optionalPlace : Place ?
177185
178186 // Unwrap `Any` to `BusStop` or `PlaceResult`
179187 if let busStop = item as? BusStop {
180- place = Place ( name: busStop. name, latitude: busStop. lat, longitude: busStop. long)
188+ optionalPlace = Place ( name: busStop. name, latitude: busStop. lat, longitude: busStop. long)
181189 }
190+
182191 if let placeResult = item as? PlaceResult {
183- place = Place ( name: placeResult. name, placeDescription: placeResult. detail, placeIdentifier: placeResult. placeID)
192+ optionalPlace = Place ( name: placeResult. name, placeDescription: placeResult. detail, placeIdentifier: placeResult. placeID)
193+ }
194+
195+ guard let place = optionalPlace else {
196+ completion ( places, " Unable to retrieve busStop or placeResult data. " )
197+ return
184198 }
185199
186200 if place. type == . googlePlace {
187201 CoordinateVisitor . getCoordinates ( for: place) { ( latitude, longitude, error) in
188202 if error != nil {
189- // TODO: Handle error properly
190- print ( " Unable to get coordinates to save favorite. " )
203+ completion ( places, " \( place. name) : Unable to get Google Place coordinates " )
191204 } else {
192205 place. latitude = latitude
193206 place. longitude = longitude
194207 places. append ( place)
195208 }
196209 if places. count == data. count {
197- completion ( places)
210+ completion ( places, nil )
198211 }
199212 }
200213 } else {
201214 places. append ( place)
202215 if places. count == data. count {
203- completion ( places)
216+ completion ( places, nil )
204217 }
205218 }
206219
0 commit comments