Skip to content

Commit f716c9c

Browse files
authored
Merge pull request #277 from merlos/fix/open-folder-crashes-app
Fix: Tap on folder icon crashes app sometimes
2 parents 65332b1 + 8f6f4e0 commit f716c9c

16 files changed

+274
-121
lines changed

Diff for: OpenGpxTracker/GPXFileInfo.swift

+31-6
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,46 @@ import Foundation
1414
///
1515
class GPXFileInfo: NSObject {
1616

17+
/// Cached modified date. Assumes a short lived time. It keeps the value of the size that only once is retrived from the filesystem
18+
var _modifiedDate: Date?
19+
20+
/// Cached filesize. Assuming a short lived time it keeps the value so only once is retrieved
21+
var _fileSize: Int?
22+
1723
/// file URL
1824
var fileURL: URL = URL(fileURLWithPath: "")
1925

20-
/// Last time the file was modified
26+
/// Returns last time the file was modified
27+
/// The date is cached in the internal variable _modifiedDate,.
28+
/// If for some reason the date cannot be retrieved it returns `Date.distantPast`
29+
///
2130
var modifiedDate: Date {
22-
// swiftlint:disable:next force_try
23-
return try! fileURL.resourceValues(forKeys: [.contentModificationDateKey]).contentModificationDate ?? Date.distantPast
31+
if _modifiedDate != nil {
32+
return _modifiedDate!
33+
}
34+
guard let resourceValues = try? fileURL.resourceValues(forKeys: [.contentModificationDateKey]),
35+
let _modifiedDate = resourceValues.contentModificationDate else {
36+
return Date.distantPast // Default value if the modification date cannot be retrieved
37+
}
38+
return _modifiedDate
2439
}
25-
2640
/// modified date has a time ago string (for instance: 3 days ago)
2741
var modifiedDatetimeAgo: String {
2842
return modifiedDate.timeAgo(numericDates: true)
2943
}
3044

3145
/// File size in bytes
46+
/// It returns -1 if there is any issue geting the size from the filesystem
47+
/// It caches the values in _filezise
3248
var fileSize: Int {
33-
// swiftlint:disable:next force_try
34-
return try! fileURL.resourceValues(forKeys: [.fileSizeKey]).fileSize ?? 0
49+
if (_fileSize != nil) {
50+
return _fileSize!
51+
}
52+
guard let resourceValues = try? fileURL.resourceValues(forKeys: [.fileSizeKey]),
53+
let _filesize = resourceValues.fileSize else {
54+
return -1 // Default value if the file size cannot be retrieved
55+
}
56+
return _filesize
3557
}
3658

3759
/// File size as string in a more readable format (example: 10 KB)
@@ -40,6 +62,9 @@ class GPXFileInfo: NSObject {
4062
}
4163

4264
/// The filename without extension
65+
/// Example:
66+
/// /path/to/file.ext => file
67+
///
4368
var fileName: String {
4469
return fileURL.deletingPathExtension().lastPathComponent
4570
}

Diff for: OpenGpxTracker/GPXFileManager.swift

+17-18
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,22 @@
77

88
import Foundation
99

10-
/// GPX File extension
11-
let kFileExt = ["gpx", "GPX"]
12-
1310
///
1411
/// Class to handle actions with GPX files (save, delete, etc..)
1512
///
1613
/// It works on the default document directory of the app.
1714
///
1815
class GPXFileManager: NSObject {
1916

17+
/// List of GPX File extension
18+
static let gpxExtList = ["gpx", "GPX"]
19+
2020
///
2121
/// Folder that where all GPX files are stored
2222
///
2323
class var GPXFilesFolderURL: URL {
2424
if let customFolderURL = Preferences.shared.gpxFilesFolderURL {
25+
print("GPXFileManager: using custom folder: \(customFolderURL)")
2526
return customFolderURL
2627
}
2728
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
@@ -32,17 +33,13 @@ class GPXFileManager: NSObject {
3233
/// Gets the list of `.gpx` files in Documents directory ordered by modified date
3334
///
3435
class var fileList: [GPXFileInfo] {
35-
let fileManager = FileManager.default
36-
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
37-
var files = self.fetchFilesList(from: documentsURL)
38-
if let customFolderURL = Preferences.shared.gpxFilesFolderURL {
39-
_ = customFolderURL.startAccessingSecurityScopedResource()
40-
files += self.fetchFilesList(from: customFolderURL)
41-
customFolderURL.stopAccessingSecurityScopedResource()
42-
}
43-
return files.sorted { lhs, rhs in
44-
return lhs.modifiedDate > rhs.modifiedDate
36+
let documentsURL = GPXFileManager.GPXFilesFolderURL
37+
if documentsURL.startAccessingSecurityScopedResource() {
38+
let files = self.fetchFilesList(from: documentsURL)
39+
documentsURL.stopAccessingSecurityScopedResource()
40+
return files
4541
}
42+
return []
4643
}
4744

4845
///
@@ -55,8 +52,8 @@ class GPXFileManager: NSObject {
5552
var fullURL = self.GPXFilesFolderURL.appendingPathComponent(filename)
5653
print("URLForFilename(\(filename): pathForFilename: \(fullURL)")
5754
// Check if filename has extension
58-
if !(kFileExt.contains(fullURL.pathExtension)) {
59-
fullURL = fullURL.appendingPathExtension(kFileExt[0])
55+
if !(gpxExtList.contains(fullURL.pathExtension)) {
56+
fullURL = fullURL.appendingPathExtension(gpxExtList[0])
6057
}
6158
return fullURL
6259
}
@@ -189,6 +186,7 @@ class GPXFileManager: NSObject {
189186
private class func fetchFilesList(from rootURL: URL) -> [GPXFileInfo] {
190187
var GPXFiles: [GPXFileInfo] = []
191188
let fileManager = FileManager.default
189+
print("====================================================================")
192190
do {
193191
// Get all files from the directory .documentsURL. Of each file get the URL (~path)
194192
// last modification date and file size
@@ -204,17 +202,18 @@ class GPXFileManager: NSObject {
204202
fileSize: (try? url.resourceValues(forKeys: [.fileSizeKey]))?.fileSize ?? 0)
205203
}
206204
.sorted(by: { $0.1 > $1.1 }) // sort descending modification dates
207-
print(sortedURLs)
208205
// Now we filter GPX Files
209206
for (url, modificationDate, fileSize) in sortedURLs {
210-
if kFileExt.contains(url.pathExtension) {
207+
if gpxExtList.contains(url.pathExtension) {
211208
GPXFiles.append(GPXFileInfo(fileURL: url))
212209
let lastPathComponent = url.deletingPathExtension().lastPathComponent
213-
print("\(modificationDate) \(modificationDate.timeAgo(numericDates: true)) \(fileSize)bytes -- \(lastPathComponent)")
210+
print("fetchFileList: GPXFileInfo added \(modificationDate) \(modificationDate.timeAgo(numericDates: true)) \(fileSize)bytes -- \(lastPathComponent)")
214211
}
215212
}
216213
}
217214
}
215+
print("fetchFilesList: returned \(GPXFiles.count) files")
216+
print("====================================================================")
218217
return GPXFiles
219218
}
220219
}

0 commit comments

Comments
 (0)