Skip to content

Commit 4ff484f

Browse files
committed
Improved error handling, function only fires once now
1 parent fdffbba commit 4ff484f

4 files changed

Lines changed: 82 additions & 47 deletions

File tree

TCAT/AppDelegate.swift

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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

TCAT/Controllers/HomeViewController.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,14 @@ class HomeViewController: UIViewController {
115115
firstViewing = userDefaults.value(forKey: Constants.UserDefaults.version) == nil
116116

117117
let whatsNewDismissed = userDefaults.bool(forKey: Constants.UserDefaults.whatsNewDismissed)
118-
let hasSeenVersion = VersionStore().has(version: WhatsNew.Version.current())
118+
let hasSeenVersion = VersionStore.shared.has(version: WhatsNew.Version.current())
119119
if !firstViewing && (!whatsNewDismissed || !hasSeenVersion) {
120120
createWhatsNewView()
121121
}
122122
if !hasSeenVersion {
123123
userDefaults.set(false, forKey: Constants.UserDefaults.whatsNewDismissed)
124124
}
125-
VersionStore().set(version: WhatsNew.Version(stringLiteral: Constants.App.version))
125+
VersionStore.shared.set(version: WhatsNew.Version(stringLiteral: Constants.App.version))
126126
}
127127

128128
override func viewDidLayoutSubviews() {
@@ -259,7 +259,7 @@ class HomeViewController: UIViewController {
259259
if completed {
260260
self.tableView.animating = false
261261
self.tableView.tableHeaderView = nil
262-
VersionStore().set(version: WhatsNew.Version.current())
262+
VersionStore.shared.set(version: WhatsNew.Version.current())
263263
}
264264
})
265265
tableView.endUpdates()

TCAT/Utilities/Analytics.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,11 @@ struct SiriShortcutUsedPayload: Payload {
189189
let intentDescription: String
190190
let locationName: String
191191
}
192+
193+
struct DataMigrationOnePointThreePayload: Payload {
194+
static let eventName: String = "v1.3 Data Migration"
195+
let deviceInfo = DeviceInfo()
196+
197+
let success: Bool
198+
let errorDescription: String?
199+
}

TCAT/Utilities/VersionStore.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,27 @@ import UIKit
1010
import WhatsNewKit
1111

1212
class VersionStore: WhatsNewVersionStore {
13+
14+
static let shared = VersionStore()
15+
16+
/// The current app version, dynamically loaded based on bundle identifier.
17+
var currentAppVersion: WhatsNew.Version {
18+
return WhatsNew.Version(stringLiteral: Constants.App.version)
19+
}
20+
21+
/// The saved app version in UserDefaults. This is manually updated on release.
22+
var savedAppVersion: WhatsNew.Version {
23+
let versionString = userDefaults.string(forKey: Constants.UserDefaults.version) ?? Constants.App.version
24+
return WhatsNew.Version(stringLiteral: versionString)
25+
}
26+
1327
/// Returns true if update has been seen
1428
func has(version: WhatsNew.Version) -> Bool {
1529
let isVersionPatch = version.patch > 0
16-
let savedAppVersion = userDefaults.string(forKey: Constants.UserDefaults.version) ?? Constants.App.version
17-
let isNotNewVersion = (Constants.App.version == savedAppVersion)
30+
let isNotNewVersion = (currentAppVersion == savedAppVersion)
1831

19-
set(version: WhatsNew.Version.current())
32+
// TODO: Confirm this still works!
33+
// set(version: WhatsNew.Version.current())
2034
return isVersionPatch || isNotNewVersion
2135
}
2236

0 commit comments

Comments
 (0)