问题
I am parsing some data from Json and saved into the coredata,after fetching core data showing into the tableview working fine, tableview is show all the value in repeatedly how can avoid the repeated values I tried many ways but not find way
Json format
{
"contacts": [
{
"id": "c200",
"name": "Ravi Tamada",
"email": "ravi@gmail.com",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
},
{
"id": "c201",
"name": "Johnny Depp",
"email": "johnny_depp@gmail.com",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
},
{
"id": "c202",
"name": "Leonardo Dicaprio",
"email": "leonardo_dicaprio@gmail.com",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
}
]
}
when I fetching "name" showing repeated values
these are save and fetch code
func getfetchdata()
{
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Contacts")
do{
let fetchResults = try self.context.fetch(fetchRequest) as? [Contacts]
if fetchResults!.count > 0 {
for bEntity in fetchResults! {
let employeeEntity = bEntity
print(employeeEntity.name as Any)
TableviewData.append(ContactsDataVal.init(name: employeeEntity.name!,
id: employeeEntity.id!, email: employeeEntity.email!, gender: employeeEntity.gender!, address: employeeEntity.address!))
}
print("data values already")
}}
catch let error as NSError
{
print(error)
}
}
func getdata()
{
let url = URL(string: "https://api.androidhive.info/contacts/")
URLSession.shared.dataTask(with: url!) { (Data, response, error) in
do
{
let data = try JSONSerialization.jsonObject(with: Data!, options: JSONSerialization.ReadingOptions.allowFragments)as! [String:AnyObject]
let arraydata = data["contacts"]as! [[String:Any]]
for arravalues in arraydata
{
let entityDescription = NSEntityDescription.entity(forEntityName: "Contacts", in:self.context)
let favouriteObj = Contacts(entity: entityDescription!, insertInto: self.context)
favouriteObj.name = arravalues["name"] as? String
favouriteObj.id = arravalues["id"] as? String
favouriteObj.email = arravalues["email"] as? String
favouriteObj.gender = arravalues["gender"] as? String
favouriteObj.address = arravalues["address"] as? String
do {
try self.context.save()
}
}
}catch let error as NSError{
print("error",error)
}
}
.resume()
}
how to avoid repeated values in core data and show proper data into the tableview
回答1:
Maybe there is something that can be done to the fetch request similar to How to get distinct results from a single field in Core Data (Swift 4) but another option would be to remove the duplicates by simply creating a set from the fetch result:
let fetchSet = Set(fetchResults)
and iterate over the set instead
回答2:
First of all in getdata
do not save the context in each iteration of the loop, save it once after the loop.
To avoid duplicates fetch all contacts from Core Data, map them to the names and check if the array contains the received name
func getdata()
{
let url = URL(string: "https://api.androidhive.info/contacts/")
let names : [String]
do {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Contacts")
let fetchResults = try self.context.fetch(fetchRequest)
names = fetchResults.map{ $0.name }
} catch {
names = []
}
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil { print(error!); return }
do {
let data = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
let arraydata = data["contacts"] as! [[String:Any]]
for arravalues in arraydata
{
guard let name = arravalues["name"] as? String, !names.contains(name) else { continue }
let entityDescription = NSEntityDescription.entity(forEntityName: "Contacts", in:self.context)
let favouriteObj = Contacts(entity: entityDescription!, insertInto: self.context)
favouriteObj.name = name
favouriteObj.id = arravalues["id"] as? String
favouriteObj.email = arravalues["email"] as? String
favouriteObj.gender = arravalues["gender"] as? String
favouriteObj.address = arravalues["address"] as? String
}
try self.context.save()
} catch {
print("error",error)
}
}
.resume()
}
Notes:
- A Core Data fetch with generic fetch request returns always a non-optional array of the
NSManagedObject
subclass which is specified as generic type on success. - Never check for empty array with
foo.count > 0
, use!foo.isEmpty
- A JSON dictionary in Swift 3+ is always
[String:Any]
rather than[String:AnyObject]
- Handle a potential error in the
dataTask
completion block. - Name the first parameter in the completion block lowercased (
data
) to avoid a confusion with the typeData
. - Omit the
options
parameter injsonObject(with
as the result is clearly a collection type.
来源:https://stackoverflow.com/questions/49198724/core-data-with-duplicate-entity-values-in-swift