Home > database >  Core Data only ever returning 1 result
Core Data only ever returning 1 result

Time:01-21

I have used Core Data many times before but this has me completely stumped and it's very frustrating.

In short, I make a server request which returns 12 results, I can see that these 12 results are iterated through and added to my Core Data entity (Friends). Once complete I do a fetch request for all the results in the Friends entity and it only ever returns 1 result which seems to always be the last result that was added.

My code is as follows.

Request to server:

func getFriends(token: String) async throws -> Int {
    var request = EndPoints().getFriendsEndPoint()
    request.httpMethod = "GET"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    let (data, response) = try await URLSession.shared.data(for: request)
    let httpResponse = response as? HTTPURLResponse
    guard (response as? HTTPURLResponse)?.statusCode == 200 else {return httpResponse?.statusCode ?? 0}
    let decodedLocations = try JSONDecoder().decode([FriendsStruct].self, from: data)
    ///Update Locations Core Data record
    self.updateCoreDataFriendsRecords(friendsData: decodedLocations)
    return httpResponse?.statusCode ?? 1000
}

Save the response records to Core Data:

func addFriendsDetailsToCoreData(friendsData:[FriendsStruct]) {
    deleteFriendsDetailsData()
    let data = NSEntityDescription.insertNewObject(forEntityName: "Friends", into: self.managedObjectContext) as! Friends
    for items in friendsData {
        data.initials = items.initials
        data.username = items.username
        data.id = items.id
        data.activeEventId = items.activeEventId
        data.email = items.email
        data.firstName = items.firstName
        data.lastName = items.lastName
        data.isInActivity = items.isInActivity
        data.fullName = items.fullName
        print("Adding friend")
    }
    print("saving core data = \(friendsData.count)")
    SaveCoreData().save()
}

And finally, fetching the new results from Core Data:

let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
var fetchedFriendsResults = [Friends]()

func fetchFriends() -> [Friends] {
    fetchedFriendsResults.removeAll()
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Friends")
    let sortDescriptor = NSSortDescriptor(key: "username", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]
    do {
        if let fetchResults = try managedObjectContext.fetch(fetchRequest) as? [Friends] {
                print("Number of items in friends = \(fetchResults.count)")
                for items in fetchResults {
                    print("A Friend - \(items.fullName ?? "Unknown")")
                fetchedFriendsResults = fetchResults
                return fetchedFriendsResults
            }
        }
    }
    catch {
        return fetchedFriendsResults
    }
    return fetchedFriendsResults
}

CodePudding user response:

The issue here is, with this line of code you are creating only one object:

let data = NSEntityDescription.insertNewObject(forEntityName: "Friends", into: self.managedObjectContext) as! Friends

in your loop you are manipulating this object multiple times and saving it once at the end. So the only saved entity in CoreData contains the informations of the last loop.

Possible solution:

Move the creation of the CoreData entity into the loop.

for items in friendsData {
    let data = NSEntityDescription.insertNewObject(forEntityName: "Friends", into: self.managedObjectContext) as! Friends
    data.initials = items.initials
    data.username = items.username
    data.id = items.id
    data.activeEventId = items.activeEventId
    data.email = items.email
    data.firstName = items.firstName
    data.lastName = items.lastName
    data.isInActivity = items.isInActivity
    data.fullName = items.fullName
    print("Adding friend")
}
  • Related