本文介绍了从联机Json再次获取时更新CoreData的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从Json获取数据,并将所有数据一次保存在CoreData中.我介绍了一个新实体"isFavorite",将核心数据发布标记为收藏.问题是,当我再次从服务器获取数据后,isFavorite数据被重置为默认值false.

我这样保存数据:

  import SwiftUI导入CoreData类JSONViewModel:ObservableObject {@已发布的var列表:[ListingModel] = []//将Json保存到核心数据中...func saveData(contex:NSManagedObjectContext){listings.forEach {(数据)在让实体=列表(上下文:contex)entity.id = Int64(data.id)实体.标题=数据.标题实体名称=数据名称entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = false//每次我再次获取所有帖子时,其默认值都为isFavorite = false, 

女巫正在对付一个哨所的女巫,已经是isFavorite = true

 }做{//一次保存所有待处理的数据尝试contex.save()打印(成功")}抓住{打印(error.localizedDescription)}}func fetchData(上下文:NSManagedObjectContext){让url ="json上的https://..."var request = URLRequest(URL:URL(string:url)!)request.addValue("swiftui2.0",对于HTTPHeaderField:"field")let session = URLSession(配置:.default)session.dataTask(with:request){(data,res,_)在守护让jsonData =数据else {return}//检查错误让response = res为!HTTPURLResponse//通过状态码检查如果response.statusCode == 404 {打印(错误Api错误")}//获取JSON数据..做 {让清单=尝试JSONDecoder().decode([ListingModel] .self,来自:jsonData)DispatchQueue.main.async {self.listings =列表self.saveData(contex:上下文)}}抓住 {打印(error.localizedDescription)}}.恢复()}} 

如何检查数据是否存在,仅更改新内容?

我还通过"id"设置了约束.并像这样更新PersistentContainer:

 让容器:NSPersistentContainerinit(inMemory:Bool = false){容器= NSPersistentContainer(名称:"WebyCoreData")container.viewContext.automaticallyMergesChangesFromParent = truecontainer.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy如果inMemory {container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath:"/dev/null")}container.loadPersistentStores(completionHandler:{如果让error = error as NSError?{fatalError(未解决的错误\(错误),\(error.userInfo)")}})} 

任何帮助深表感谢!

也尝试过:

  if entity.isFavorite == true {entity.isFavorite = true}别的 {entity.isFavorite = false} 
解决方案

在saveData函数中,尝试执行以下操作:

  let listingFetch:NSFetchRequest< Listing>= Listing.fetchRequest()listingFetch.predicate = NSPredicate(格式:"id ==%@",Int64(data.id))做 {让结果:[列表] =尝试contex.fetch(listingFetch)如果results.count == 0 {让实体=列表(上下文:contex)entity.id = Int64(data.id)实体.标题=数据.标题实体名称=数据名称entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = false尝试?contex.save()打印(插入列表")}别的{设实体=结果[0]实体.标题=数据.标题实体名称=数据名称entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = true尝试?contex.save()打印(更新列表")}}将let错误捕获为NSError {print(插入/更新列表\(error),\(error.userInfo)时出错")} 

使用Marius的完整属性列表进行更新.还修改了错字

  func saveData(contex:NSManagedObjectContext){listings.forEach(){(数据)在let listingFetch:NSFetchRequest< Listing>= Listing.fetchRequest()listingFetch.predicate = NSPredicate(格式:"id =%@",data.id)做 {让结果:[列表] =尝试contex.fetch(listingFetch)如果results.count == 0 {让实体=列表(上下文:contex)entity.id = Int64(data.id)实体.标题=数据.标题实体名称=数据名称entity.category = data.category实体.图像=数据.图像实体.发布日期=数据发布日期entity.tagline = data.tagline实体.内容=数据.内容entity.coverimage = data.coverimageentity.galleryunu = data.galleryunuentity.gallerydoi = data.gallerydoientity.gallerytrei =数据.gallerytreientity.saleprice = Int64(截断:NSNumber(值:data.saleprice))entity.rentprice = Int64(截断:NSNumber(值:data.rentprice))实体.电话=数据.电话实体.电子邮件=数据.电子邮件实体.区域= Int64(截断:NSNumber(值:数据.区域))entity.rooms = Int64(截断:NSNumber(值:data.rooms))实体.床= Int64(截断:NSNumber(值:数据.床))实体.浴室= Int64(截断:NSNumber(值:数据浴室))entity.expires = data.expiresentity.adresa = data.adresa实体.列表类型=数据.列表类型entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = false尝试?contex.save()打印(插入列表")}别的{设实体=结果[0]entity.id = Int64(data.id)实体标题=数据标题实体名称=数据名称entity.category = data.category实体.图像=数据.图像实体.发布日期=数据发布日期entity.tagline = data.tagline实体.内容=数据.内容entity.coverimage = data.coverimageentity.galleryunu = data.galleryunuentity.gallerydoi = data.gallerydoientity.gallerytrei =数据.gallerytreientity.saleprice = Int64(截断:NSNumber(值:data.saleprice))entity.rentprice = Int64(截断:NSNumber(值:data.rentprice))实体.电话=数据.电话实体.电子邮件=数据.电子邮件实体.区域= Int64(截断:NSNumber(值:数据.区域))entity.rooms = Int64(截断:NSNumber(值:data.rooms))实体.床= Int64(截断:NSNumber(值:数据.床))实体.浴室= Int64(截断:NSNumber(值:数据浴室))entity.expires = data.expiresentity.adresa = data.adresa实体.列表类型=数据.列表类型entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = true尝试?contex.save()打印(更新列表")}}将let错误捕获为NSError {print(插入/更新列表\(error),\(error.userInfo)时出错")}}} 

I am fetching data from Json and save all at once in CoreData. I introduced a new entity "isFavorite" to mark core data posts as favorites. The problem is that after i fetch again from server the isFavorite data is resseting to the default false.

I save the data like this:

import SwiftUI
import CoreData

class JSONViewModel: ObservableObject {

    @Published var listings: [ListingModel] = []
    // saving Json to Core Data...
    
    func saveData(contex: NSManagedObjectContext) {
        
        listings.forEach { (data) in
            
            let entity = Listing(context: contex)
            
            entity.id = Int64(data.id)
            entity.title = data.title
            entity.name = data.name
            entity.latitude = Double(truncating: NSNumber(value: data.latitude))
            entity.longitude = Double(truncating: NSNumber(value: data.longitude))
            entity.isFavorite = false // everytime i fetch again all the post get default value as isFavorite = false, 

witch is overighting tha acual post's witch have already isFavorite = true

        }

        do{
           // saving all pending data at once
           try contex.save()

            print("success")
        }
        catch{
            print(error.localizedDescription)
        }
       
    }
    
    
    func fetchData(context: NSManagedObjectContext){
        
        let url = "https://... on line json"
        
        var request = URLRequest(url: URL(string: url)!)
        request.addValue("swiftui2.0", forHTTPHeaderField: "field")
        
        let session = URLSession(configuration: .default)
        
        session.dataTask(with: request) { (data, res, _) in
            
            guard let jsonData = data else{return}
            
            // check for errors
            
            let response = res as! HTTPURLResponse
            // checking by status code
            
            if response.statusCode == 404 {
                print("error Api Errror")
            }
            
            // fetching JSON Data ..
            do {
                let listings = try JSONDecoder().decode([ListingModel].self, from: jsonData)
                
                DispatchQueue.main.async {
                  
                    self.listings = listings
                    self.saveData(contex: context)
                }
            }
            catch {
                print(error.localizedDescription)
            }
        }
        
        .resume()
    }
}

How can i check if data exist and only change what is new?

i have also set Constraints by "id".and updated the PersistentContainer like this::

 let container: NSPersistentContainer
   
    init(inMemory: Bool = false) {
        
        container = NSPersistentContainer(name: "WebyCoreData")
        container.viewContext.automaticallyMergesChangesFromParent = true
        container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")       }
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        
    }

Any help is deeply appreciated!

Have tried also:

if entity.isFavorite == true {
                entity.isFavorite = true}
            else {
                entity.isFavorite = false}
解决方案

In your saveData function, try something like this:

 let listingFetch: NSFetchRequest<Listing> = Listing.fetchRequest()
  listingFetch.predicate = NSPredicate(format: "id == %@", Int64(data.id))

    do {
     let results:[Listing] = try contex.fetch(listingFetch)
        if results.count == 0 {

           let entity = Listing(context: contex)
           entity.id = Int64(data.id)
           entity.title = data.title
           entity.name = data.name
           entity.latitude = Double(truncating: NSNumber(value: data.latitude))
           entity.longitude = Double(truncating: NSNumber(value: data.longitude))
           entity.isFavorite = false

            try? contex.save()
           print ("Inserted Listing")
        }
        else
        {
           let entity = results[0]
           entity.title = data.title
           entity.name = data.name
           entity.latitude = Double(truncating: NSNumber(value: data.latitude))
           entity.longitude = Double(truncating: NSNumber(value: data.longitude))
           entity.isFavorite = true

            try? contex.save()
            print ("Updated Listing")
        }
    } catch let error as NSError {
        print("error inserting / updating Listing \(error), \(error.userInfo)")
    }

Update with Marius's full list of properties.Also modified typo

    func saveData(contex: NSManagedObjectContext) {
        
       
        listings.forEach() { (data) in
            
        let listingFetch: NSFetchRequest<Listing> = Listing.fetchRequest()
          listingFetch.predicate = NSPredicate(format: "id = %@", data.id)
        
       
            do {
             let results:[Listing] = try contex.fetch(listingFetch)
                if results.count == 0 {

                   let entity = Listing(context: contex)
                    entity.id = Int64(data.id)
                    entity.title = data.title
                    entity.name = data.name
                    entity.category = data.category
                    entity.image = data.image
                    entity.publishdate = data.publishdate
                    entity.tagline = data.tagline
                    entity.content = data.content
                    entity.coverimage = data.coverimage
                    entity.galleryunu = data.galleryunu
                    entity.gallerydoi = data.gallerydoi
                    entity.gallerytrei = data.gallerytrei
                    entity.saleprice = Int64(truncating: NSNumber(value: data.saleprice))
                    entity.rentprice = Int64(truncating: NSNumber(value: data.rentprice))
                    entity.phone = data.phone
                    entity.email = data.email
                    entity.area = Int64(truncating: NSNumber(value: data.area))
                    entity.rooms = Int64(truncating: NSNumber(value: data.rooms))
                    entity.beds = Int64(truncating: NSNumber(value: data.beds))
                    entity.bathrooms = Int64(truncating: NSNumber(value: data.bathrooms))
                    entity.expires = data.expires
                    entity.adresa = data.adresa
                    entity.listingtype = data.listingtype
                    entity.latitude = Double(truncating: NSNumber(value: data.latitude))
                    entity.longitude = Double(truncating: NSNumber(value: data.longitude))
                   entity.isFavorite = false

                    try? contex.save()
                   print ("Inserted Listing")
                }
                else
                {
                   let entity = results[0]
                    entity.id = Int64(data.id)
                    entity.title = data.title
                    entity.name = data.name
                    entity.category = data.category
                    entity.image = data.image
                    entity.publishdate = data.publishdate
                    entity.tagline = data.tagline
                    entity.content = data.content
                    entity.coverimage = data.coverimage
                    entity.galleryunu = data.galleryunu
                    entity.gallerydoi = data.gallerydoi
                    entity.gallerytrei = data.gallerytrei
                    entity.saleprice = Int64(truncating: NSNumber(value: data.saleprice))
                    entity.rentprice = Int64(truncating: NSNumber(value: data.rentprice))
                    entity.phone = data.phone
                    entity.email = data.email
                    entity.area = Int64(truncating: NSNumber(value: data.area))
                    entity.rooms = Int64(truncating: NSNumber(value: data.rooms))
                    entity.beds = Int64(truncating: NSNumber(value: data.beds))
                    entity.bathrooms = Int64(truncating: NSNumber(value: data.bathrooms))
                    entity.expires = data.expires
                    entity.adresa = data.adresa
                    entity.listingtype = data.listingtype
                    entity.latitude = Double(truncating: NSNumber(value: data.latitude))
                    entity.longitude = Double(truncating: NSNumber(value: data.longitude))
                   entity.isFavorite = true

                    try? contex.save()
                    print ("Updated Listing")
                }
            } catch let error as NSError {
                print("error inserting / updating Listing \(error), \(error.userInfo)")
            }
        }
    }

这篇关于从联机Json再次获取时更新CoreData的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-25 04:16