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")
}