I have a navigation and location tracking app. While a user is tracking his trip, coordinates, speed, timestamp (and a few more) are logged with each coordinate that comes in. I don't want to store this in memory as that would make the app memory grow as the user moves along, eventually leading to a didReceiveMemoryWarning and even an app crash. (At least that's been my experience so far)
What would be the most efficient way to do this? Thinking of battery consumption, CPU usage and also memory usage if that comes into play.
I can think of two options to do this:
- Log in a file (what I'm currently doing, using this code snipped):
let newLine: String = "bla bla bla"
let url: URL = URL(string: "someLocalPath")
newLine.appendToURL(url)
extension String {
func appendToURL(_ fileURL: URL) throws {
let data = self.data(using: String.Encoding.utf8)!
try data.appendToURL(fileURL)
}
}
extension Data {
func appendToURL(_ fileURL: URL) throws {
if let fileHandle = try? FileHandle(forWritingTo: fileURL) {
defer {
fileHandle.closeFile()
}
fileHandle.seekToEndOfFile()
fileHandle.write(self)
fileHandle.closeFile()
}
else {
try write(to: fileURL, options: .atomic)
}
}
}
Using Core Data
I have not tried this yet, but it would be relatively easy I believe. Just creating an entity with all the fields required, and then adding a
managedObjectfor each received coordinate.
So, to repeat my question: which of these two options would be more efficient from a battery, CPU and memory perspective?
Additional question: Is there perhaps another way to do this. One that I didn't think of?
I found another option that works best in my case. Should have thought of that in the first place ♂️.
So, I did not want to log to memory because it could make iOS kill my app due to excessive memory usage. But, iOS sends a
didReceiveMemoryWarningfirst, upon which you can reduce the memory footprint of the app, preventing it from being killed.So, what I do now:
I added a instance variable:
And log to it when a new coordinate is received:
If / when I get a
didReceiveMemoryWarningI write the entirelogStringto the file on disk and empty it afterwards:This way I only write to disk when necessary (and not with each coordinate received), which is a lot more energy efficient. (Writing to disk costs more energy than writing to memory. Source: https://developer.apple.com/videos/play/wwdc2016/719/)
Plus, my app is prevented from being killed by iOS due to high memory usage, because I clear up memory on time.