LAST CHANCE: Save 50% on all my Swift books and bundles! >>

Hacking With Swift - Project 38 - Table view going crazy when trying to save/load the newest date with UserDefaults

Forums > Swift

Hi guys,

One of the tasks from Project 38 is:

"Rewrite the getNewestCommitDate() method so that it uses UserDefaults rather than a fetch request in order to fix the bug in the current implementation. (Didn't spot the bug? If users delete the most recent commit message, we also lose our most recent date!)"

So far, getNewestCommitDate() looked like that:

        let formatter = ISO8601DateFormatter()

        let newest = Commit.createFetchRequest()
        let sort = NSSortDescriptor(key: "date", ascending: false)
        newest.sortDescriptors = [sort]
        newest.fetchLimit = 1 

        if let commits = try? container.viewContext.fetch(newest) {
            if commits.count > 0 {
                return formatter.string(from: commits[0].date.addingTimeInterval(1)) 

        return formatter.string(from: Date(timeIntervalSince1970: 0)) // if no valid date is found, the method returns a date from the 1st of January 1970, which will reproduce the same behavior we had before introducing this date change.

I changed it to:

func getNewestCommitDate() -> String {
        let defaults = UserDefaults.standard
        let formatter = ISO8601DateFormatter()

        if let newestDate = defaults.string(forKey: "NewestDate") {
            print("Newest date loaded: \(newestDate)")
            return newestDate

        return formatter.string(from: Date(timeIntervalSince1970: 0))

Saving the newest date occurs here:

func saveNewestCommitDate() {
       let defaults = UserDefaults.standard
        let formatter = ISO8601DateFormatter()

        let string = formatter.string(from: newCommits[0].date)

        defaults.setValue(string, forKey: "NewestDate")
        print("Newest date saved: \(string)")

So, when fetching the data, first we load the newest commit date, and if there is any new one, we save it as the newest:

@objc func fetchCommits() {
        let newestCommitDate = getNewestCommitDate()

        if let data = try? String(contentsOf: URL(string: "\(newestCommitDate)")!) { 
            // give the data to SwiftyJSON to parse:
            let jsonCommits = JSON(parseJSON: data)

            // read the commits back out as an array:
            let jsonCommitArray = jsonCommits.arrayValue

            DispatchQueue.main.async { [unowned self] in
                for jsonCommit in jsonCommitArray {
                    let commit = Commit(context: self.container.viewContext) 
                    self.configure(commit: commit, usingJSON: jsonCommit) 

                    self.newCommits.append(commit) // adding the newest commits to an array:


But if I use what I described above, I ALWAYS get the same error, no matter what I try to do. It's worth to note that I get this error every time I launch the app for THE SECOND TIME. The first launch with the resetted simulator is always successful, with the newest date being saved properly. The error is:

"Thread 1: Exception: "Invalid update: invalid number of rows in section 7. The number of rows contained in an existing section after the update (52) must be equal to the number of rows contained in that section before the update (52), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).""

I noticed that there is always this thing - (0 inserted, 1 deleted) - but I haven't deleted anything from any section, nor have I attempted to do so. What gives? I tried to google the solution but haven't found any situation similar to mine.


Hacking with Swift is sponsored by Essential Developer.

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until July 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.