-
Notifications
You must be signed in to change notification settings - Fork 150
/
Copy pathCoreDataHelper+FetchRequests.swift
124 lines (97 loc) · 6 KB
/
CoreDataHelper+FetchRequests.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// CoreDataHelper+FetchRequests.swift
// OpenGpxTracker
//
// Created by Vincent Neo on 1/8/20.
//
import CoreData
import CoreGPX
extension CoreDataHelper {
func rootFetchRequest() -> NSAsynchronousFetchRequest<CDRoot> {
let rootFetchRequest = NSFetchRequest<CDRoot>(entityName: "CDRoot")
let asyncRootFetchRequest = NSAsynchronousFetchRequest(fetchRequest: rootFetchRequest) { asynchronousFetchResult in
guard let rootResults = asynchronousFetchResult.finalResult else { return }
DispatchQueue.main.async {
print("Core Data Helper: fetching recoverable CDRoot")
guard let objectID = rootResults.last?.objectID else { self.lastFileName = ""; return }
guard let safePoint = self.appDelegate.managedObjectContext.object(with: objectID) as? CDRoot else { self.lastFileName = ""; return }
self.lastFileName = safePoint.lastFileName ?? ""
self.lastTracksegmentId = safePoint.lastTrackSegmentId
self.isContinued = safePoint.continuedAfterSave
// swiftlint:disable:next line_length
print("Core Data Helper: fetched CDRoot lastFileName:\(self.lastFileName) lastTracksegmentId: \(self.lastTracksegmentId) isContinued: \(self.isContinued)")
}
}
return asyncRootFetchRequest
}
func trackPointFetchRequest() -> NSAsynchronousFetchRequest<CDTrackpoint> {
// Creates a fetch request
let trkptFetchRequest = NSFetchRequest<CDTrackpoint>(entityName: "CDTrackpoint")
// Ensure that fetched data is ordered
let sortTrkpt = NSSortDescriptor(key: "trackpointId", ascending: true)
trkptFetchRequest.sortDescriptors = [sortTrkpt]
// Creates `asynchronousFetchRequest` with the fetch request and the completion closure
let asynchronousTrackPointFetchRequest = NSAsynchronousFetchRequest(fetchRequest: trkptFetchRequest) { asynchronousFetchResult in
print("Core Data Helper: fetching recoverable CDTrackpoints")
guard let trackPointResults = asynchronousFetchResult.finalResult else { return }
// Dispatches to use the data in the main queue
DispatchQueue.main.async {
self.tracksegmentId = trackPointResults.first?.trackSegmentId ?? 0
for result in trackPointResults {
let objectID = result.objectID
// thread safe
guard let safePoint = self.appDelegate.managedObjectContext.object(with: objectID) as? CDTrackpoint else { continue }
if self.tracksegmentId != safePoint.trackSegmentId {
if self.currentSegment.points.count > 0 {
self.tracksegments.append(self.currentSegment)
self.currentSegment = GPXTrackSegment()
}
self.tracksegmentId = safePoint.trackSegmentId
}
let pt = GPXTrackPoint(latitude: safePoint.latitude, longitude: safePoint.longitude)
pt.time = safePoint.time
pt.elevation = safePoint.elevation
self.currentSegment.points.append(pt)
}
self.trackpointId = trackPointResults.last?.trackpointId ?? Int64()
self.tracksegments.append(self.currentSegment)
// siftlint:disable:next line_length
print("Core Data Helper: fetched CDTrackpoints. # of tracksegments: \(self.tracksegments.count). trackPointId: \(self.trackpointId) trackSegmentId: \(self.tracksegmentId)")
}
}
return asynchronousTrackPointFetchRequest
}
func waypointFetchRequest() -> NSAsynchronousFetchRequest<CDWaypoint> {
let wptFetchRequest = NSFetchRequest<CDWaypoint>(entityName: "CDWaypoint")
let sortWpt = NSSortDescriptor(key: "waypointId", ascending: true)
wptFetchRequest.sortDescriptors = [sortWpt]
let asynchronousWaypointFetchRequest = NSAsynchronousFetchRequest(fetchRequest: wptFetchRequest) { asynchronousFetchResult in
print("Core Data Helper: fetching recoverable CDWaypoints")
// Retrieves an array of points from Core Data
guard let waypointResults = asynchronousFetchResult.finalResult else { return }
// Dispatches to use the data in the main queue
DispatchQueue.main.async {
for result in waypointResults {
let objectID = result.objectID
// thread safe
guard let safePoint = self.appDelegate.managedObjectContext.object(with: objectID) as? CDWaypoint else { continue }
let pt = GPXWaypoint(latitude: safePoint.latitude, longitude: safePoint.longitude)
pt.time = safePoint.time
pt.desc = safePoint.desc
pt.name = safePoint.name
if safePoint.elevation != .greatestFiniteMagnitude {
pt.elevation = safePoint.elevation
}
self.waypoints.append(pt)
}
self.waypointId = waypointResults.last?.waypointId ?? Int64()
// trackpoint request first, followed by waypoint request
// hence, crashFileRecovery method is ran in this.
self.crashFileRecovery() // should always be in the LAST fetch request!
print("Core Data Helper: fetched \(self.waypoints.count) CDWaypoints ")
print("Core Data Helper: async fetches complete.")
}
}
return asynchronousWaypointFetchRequest
}
}