1

I have store data of my contacts in core data entity, and i'm trying to get that data in an array of that entity and populate data in my table view, now when i get that data i got duplicate data . How can delete my duplicate data from the array of my core data entity. This is the code how am i getting data from entity,

 func getAllContacts()
{
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Contacts")
    request.returnsObjectsAsFaults = false
    do {
        let result = try context.fetch(request)

        allContacts = result as! [Contacts]

        for contact in allContacts
        {
            let register = contact.register
            if register == "yes"
            {
                self.contactsCoreDataRavenNameArray.append(contact.name!)
                self.contactsCoreDataRavenNumberArray.append(contact.number!)
                self.contactsCoreDataRavenImageArray.append(contact.image!)
            }
            else {

                self.contactsCoreDataNonRavenNameArray.append(contact.name!)
                self.contactsCoreDataNonRavenNumberArray.append(contact.number!)
                self.contactsCoreDataNonRavenImageArray.append(contact.image!)
            }
            contactsCoreDataNameServer.append(contact.name!)
            contactsCoreDataNumberServer.append(contact.number!)
            contactsCoreDataImageServer.append(contact.image!)
        }

    } catch {

        print("Failed")
    }
}

This is how i'm storing api response data in my core data entity,

func compareWithRavenServerContacts(_ refreshing: Bool) {

    if let token = LoginToken {
        let param = [
            "token" : token,
            "contacts" : numberArrayForServer,
            "names" : namesArrayForServer
            ] as [String : Any]

        print(param)
        if refreshing {
            DispatchQueue.main.async {
            topViewController()?.view.makeToastActivity(.center)
            }
        }

        ServerCall.makeCallWitoutFile(GetRavenContactsUrl, params: param, type: Method.POST, currentView: nil) { (response) in

            if let json = response {
                print(json)
                if json["success"].boolValue {
                    let data = json["data"].arrayValue
                    print(data.count,data)
                    var ravenContacts = [ContactStruct]()
                    var serverContacts = [ContactStruct]()
                    var NonRavenContacts = [ContactStruct]()

                    for item in data
                    {
                        let name = item["name"].stringValue
                        let phone = item["phone"].stringValue
                        let picture = item["picture"].stringValue
                        let register = item["is_register"].stringValue

                        let optData = try? self.updateContact(name: name, number: phone)
                        guard let data1 = optData else {
                            return
                        }
                        print(data1)

                        let appDelegate = UIApplication.shared.delegate as? AppDelegate
                        let context = appDelegate?.persistentContainer.viewContext
                        let entity = NSEntityDescription.entity(forEntityName: "Contacts", in: context!)
                        let user = NSManagedObject(entity: entity!, insertInto: context)

                        user.setValue(name, forKey: "name")
                        user.setValue(phone, forKey: "number")
                        user.setValue(register, forKey: "register")
                        user.setValue(picture, forKey: "image")

                        do {
                            try context?.save()
                            print("Saved successfully.")

                        } catch  {
                            print("Fail to save")
                        }

                        let contact = ContactStruct(name: name, number: phone, register: register, profilePic: picture, isSelected: false)

                        if register == "yes" {
                            ravenContacts.append(contact)
                        } else {
                            NonRavenContacts.append(contact)
                        }
                        serverContacts.append(contact)
                    }

                    self.contactsRaven = ravenContacts.sorted(by: { ($0.name < $1.name) })

                    self.contactsServer = serverContacts.sorted(by: { ($0.name < $1.name) })

                    self.contactsNonRaven = NonRavenContacts.sorted(by: { ($0.name < $1.name) })

                    self.getAllContacts()

                    self.contactsDevice = self.contactsServer

                    topViewController()?.view.hideToastActivity()
                }
                else
                {
                    topViewController()?.view.makeToast("Error!. Please try again", duration: 2.0, position: .center)
                    topViewController()?.view.hideToastActivity()
                }
            }
        }
    }
    else {
        DispatchQueue.main.async {
            topViewController()?.view.makeToast("Error!, Login Again To Call Services", duration: 2.0, position: .center)
            topViewController()?.view.hideToastActivity()
        }
    }
}
Hamza Imran
  • 55
  • 1
  • 7
  • What data types do you store in the name, number, image arrays? If they conform to the Hashable protocol you can convert the array into a set which deletes duplicates. – lajosdeme Feb 07 '19 at 12:50
  • Actually in allContacts array i have all name, number and images and when i extract from that array i get them in seperate array all of them. These are contacts name, number and their images. Now when api i call multiple time it stores in my entity multiple times and and shows me duplicate data. i want to remove this duplicate data. @ldem – Hamza Imran Feb 07 '19 at 13:08

1 Answers1

0

So if contact.name and contact.number are both string it is easy to clear the duplicates. You just have to call this:

let noDuplicatesNameArray = Array(Set(exampleNameArray))

I assume that the contact.image is UIImage. This is a bit trickier. The best, cleanest solution would be to store the names of the UIImages in a string array and check that for duplicates and then construct your new image array from that.

If you can not do that for some reason, I worked out a solution for you where you can check an array of UIImages for duplicates. Note that I just hammered out this code now. Some people might find it unsophisticated. If you too find it unsophisticated please search SO for more optimal answers.

So you have an array of UIImages:

var imagesArray = [UIImage(named: "image1"), UIImage(named: "image1"), UIImage(named: "image1"), UIImage(named: "image2")]

You make a new array where you will save the non-duplicate images:

var newImagesArray = [UIImage]()

This is the function that cleans the array from duplicates:

    func clearDuplicates() {
    var set = Set<Data>()

    for image in imagesArray {
        let data = image?.pngData()
        set.insert(data!)
    }

    let noDuplicateArray = Array(set)

    for imgData in noDuplicateArray {
        let image = UIImage(data: imgData)
        newImagesArray.append(image!)
    }
    print("You have an array of UIImages with no duplicates!")
}

Now newImagesArray is imagesArray but without duplicates. Let me know if this helps!

For more information on removing dupliates from arrays see this SO answer.

lajosdeme
  • 2,189
  • 1
  • 11
  • 20