Search code examples
core-dataswiftui

How to get filtered data from entities in coredata


I have a scenario where I know what I need to do but do not know how to implement it in Swift...

I have 2 tables in CoreData and I fetch their values as below

What I need - all friends that are in a particular user friends array

//-----Full Code Manual CachedUser Class

import Foundation
import CoreData


extension CachedUser {

@nonobjc public class func fetchRequest() -> NSFetchRequest<CachedUser> {
    return NSFetchRequest<CachedUser>(entityName: "CachedUser")
}

@NSManaged public var name: String?
@NSManaged public var id: String?
@NSManaged public var company: String?
@NSManaged public var isActive: Bool
@NSManaged public var age: Int16
@NSManaged public var email: String?
@NSManaged public var address: String?
@NSManaged public var about: String?
@NSManaged public var registered: String?
@NSManaged public var tags: String?
@NSManaged public var friends: NSSet?

public var wrappedName: String {
    name ?? "Name N/A"
}

public var wrappedId: String {
    id ?? "id N/A"
}

public var wrappedCompany: String {
    company ?? "comapny N/A"
}

public var wrappedIsActive: Bool {
    isActive
}


public var checkIsActive: String {
    return isActive ? "YES" :"NO"
}

public var wrappedEmail: String {
    email ?? "email N/A"
}

public var wrappedAge: Int16 {
    age
}

public var wrappedRegistered: String {
    registered ?? "N/A"
}



public var cachedFriend: [CachedFriend] {
    let set = friends as? Set<CachedFriend> ?? []
    return set.sorted {
        $0.wrappedName < $1.wrappedName
    }
}

}

// MARK: Generated accessors for friends extension CachedUser {

@objc(addFriendsObject:)
@NSManaged public func addToFriends(_ value: CachedFriend)

@objc(removeFriendsObject:)
@NSManaged public func removeFromFriends(_ value: CachedFriend)

@objc(addFriends:)
@NSManaged public func addToFriends(_ values: NSSet)

@objc(removeFriends:)
@NSManaged public func removeFromFriends(_ values: NSSet)

}

extension CachedUser : Identifiable {

}

//-----

//----- CachedUSer

import Foundation
import CoreData


extension CachedFriend {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<CachedFriend> {
        return NSFetchRequest<CachedFriend>(entityName: "CachedFriend")
    }

    @NSManaged public var name: String?
    @NSManaged public var id: String?
    @NSManaged public var users: CachedUser?
    
    
    public var wrappedId: String {
        id ?? "Unknown Id"
    }
    
    public var wrappedName: String {
        name ?? "Unknown Name"
    }
    

}

extension CachedFriend : Identifiable {

}

//------

//---SwiftUI View where I want the data , Section friends does not show any friends

import SwiftUI

struct DetailView: View {
    let users: [CachedUser]
    let user: CachedUser
    @State var friendsArray: [CachedFriend] = []
    @FetchRequest(sortDescriptors: []) var friendsData: FetchedResults<CachedFriend>
    var body: some View {
        Form {
            List {
                Section("Name") {
                    Text(user.wrappedName)
                        .font(.body)
                }
                Section("email") {
                    Text(user.wrappedEmail)
                }
                Section("Registration Date") {
                    Text(user.wrappedRegistered)
                }
                Section("Company") {
                    Text(user.wrappedCompany)
                }
                Section("Is Active") {
                    Image(systemName: user.isActive ? "checkmark.circle.fill" : "xmark.octagon.fill")
                        .foregroundColor(user.isActive ? Color.green : Color.red)
                }
                
                Section("Friends") {
                    List {
                  
                        ForEach(friendsArray, id:\.self) {friend in
                        Text(friend.wrappedName)
                    }
                        
                    }
                  
                    
                }
                
               
                               
                
            }
            .onAppear {
                friendsArray = Array(user.cachedFriend)
            }
           
           
            
           
            }
           
          
        }
        
   
    
  
}

//-----End Here I have a CachedUser Entity and CachedFriend Entity Image of Relationship attached .

enter image description here

Every user has an array of friends that I get from json file , that friend array contains name and id....

I know I have to loop over the friends table and filter all names that have the same name as in User Friends array, but I just cannot seem to do it, I have tried below , but they just do not work , can any one point me in right direction. Thanks

  @State var friendsArray: [CachedFriend] = []
 let user: CachedUser
func findFriend()  {
    for allFriend in friendsData {
           
        friendsArray = user.cachedFriend.filter({ item in
            item.wrappedId == allFriend.wrappedId
        })
           
    }
    
    print(friendsArray.count)
}

Sample of json

[
    {
        "id": "50a48fa3-2c0f-4397-ac50-64da464f9954",
        "isActive": false,
        "name": "Alford Rodriguez",
        "age": 21,
        "company": "Imkan",
        "email": "[email protected]",
        "address": "907 Nelson Street, Cotopaxi, South Dakota, 5913",
        "about": "Occaecat consequat elit aliquip magna laboris dolore laboris sunt officia adipisicing reprehenderit sunt. Do in proident consectetur labore. Laboris pariatur quis incididunt nostrud labore ad cillum veniam ipsum ullamco. Dolore laborum commodo veniam nisi. Eu ullamco cillum ex nostrud fugiat eu consequat enim cupidatat. Non incididunt fugiat cupidatat reprehenderit nostrud eiusmod eu sit minim do amet qui cupidatat. Elit aliquip nisi ea veniam proident dolore exercitation irure est deserunt.",
        "registered": "2015-11-10T01:47:18-00:00",
        "tags": [
            "cillum",
            "consequat",
            "deserunt",
            "nostrud",
            "eiusmod",
            "minim",
            "tempor"
        ],
        "friends": [
            {
                "id": "91b5be3d-9a19-4ac2-b2ce-89cc41884ed0",
                "name": "Hawkins Patel"
            },
            {
                "id": "0c395a95-57e2-4d53-b4f6-9b9e46a32cf6",
                "name": "Jewel Sexton"
            },
            {
                "id": "be5918a3-8dc2-4f77-947c-7d02f69a58fe",
                "name": "Berger Robertson"
            },
            {
                "id": "f2f86852-8f2d-46d3-9de5-5bed1af9e4d6",
                "name": "Hess Ford"
            },
            {
                "id": "6ba32d1b-38d7-4b0f-ba33-1275345eacc0",
                "name": "Bonita White"
            },
            {
                "id": "4b9bf1e5-abec-4ee3-8135-3a838df90cef",
                "name": "Sheryl Robinson"
            },
            {
                "id": "5890bacd-f49c-4ea2-b8fa-02db0e083238",
                "name": "Karin Collins"
            },
            {
                "id": "29e0f9ee-71f2-4043-ad36-9d2d6789b2c8",
                "name": "Pace English"
            },
            {
                "id": "aa1f8001-59a3-4b3c-bf5e-4a7e1d8563f2",
                "name": "Pauline Dawson"
            },
            {
                "id": "d09ffb09-8adc-48e1-a532-b99ae72473d4",
                "name": "Russo Carlson"
            },
            {
                "id": "7ef1899e-96e4-4a76-8047-0e49f35d2b2c",
                "name": "Josefina Rivas"
            }
        ]
    },

Solution

  • You don't need to use filter on a CoreData FetchRequest ever.

    It is best to do the filtering by NSPredicate

    https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/index.html

    But in this case all the user's friends are in a variable. If you have the individual user all you need to do is something like this...

    user.friends.allObjects