Swift 3 iOS10核心数据根据id检查记录是不是已经存在

Posted

技术标签:

【中文标题】Swift 3 iOS10核心数据根据id检查记录是不是已经存在【英文标题】:Swift 3 iOS10 core data check if record already exist base on idSwift 3 iOS10核心数据根据id检查记录是否已经存在 【发布时间】:2017-06-20 16:13:31 【问题描述】:

我正在 ios10 上使用新的 CoreData 和 Swift3 开发应用程序。 id 不存在时如何创建新对象(如果对象已经存在,我们从核心数据中提取对象并只修改它)?

类似

let objectID = someNumber

If exist with objectID = someNumber 
   //modify object
else 
   //create new object
   //assign attribute


//save

我正在尝试为 CoreData 使用新的 iOS10 Swift 3 语法。我使用的是本机代码,而不是任何 3rd 方库。考虑使用 fetch 但不知道该任务的正确语法是什么。

更新:感谢@Jan,我找到了检查的方法。我的更新问题是从给定的 JSON 创建或更新实体。这是我的功能

static func creatOrUpdateArticle(_ json: JSON, context: NSManagedObjectContext) ->Article 

        var article: Article

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Article")
        let predicateID = NSPredicate(format: "id == %@",json[Key.id].stringValue)
        fetchRequest.predicate = predicateID

        do 

            let results = try context.fetch(fetchRequest)
            if results.count > 0 
                article = results.first as! Article
            else 
                article = Article(context: context)
            

            article.webUrl = json[Key.webUrl].string


        
        catch let error 
            print(error.localizedDescription)
        
        return article
    

我收到错误消息:“变量文章在初始化之前已使用”。如何让函数返回一篇文章或更新现有文章并返回结果?

【问题讨论】:

【参考方案1】:

我假设您知道如何创建和修改对象。对于缺少的exists 部分,您可以使用以下内容:

func someEntityExists(id: Int) -> Bool 
    var fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "SomeEntity")
    fetchRequest.predicate = NSPredicate(format: "someField = %d", id)

    var results: [NSManagedObject] = []

    do 
        results = try managedObjectContext.fetch(fetchRequest)
    
    catch 
        print("error executing fetch request: \(error)")
    

    return results.count > 0

更有效的新方法是使用NSFetchRequestResult

func someEntityExists(id: Int) -> Bool 
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "SomeEntity")
    fetchRequest.includesSubentities = false

    var entitiesCount = 0

    do 
        entitiesCount = try managedObjectContext.count(for: fetchRequest)
    
    catch 
        print("error executing fetch request: \(error)")
    

    return entitiesCount > 0

【讨论】:

感谢您考虑这样做。新语法是“let fetchRequest = NSFetchRequest(entityName: "Article")" 而不是 fetchRequest = NSFetchRequest(entityName: "SomeEntity")? @LêKhánhVinh 啊抱歉,我误解了你想要什么...我已经更新了我的答案。 我可能会使用一个可选的,因为核心数据操作可能会失败并让您陷入无法返回任何东西的情况。 第二个例子中你在哪里使用了“id”? 也许你忘记了第二个例子中的谓词行,id 会用在哪里?【参考方案2】:

一个小技巧,可以改写如下:

if results.count > 0 
    article = results.first as! Article
else 
    article = Article(context: context)

作为:

let article = results.first as? Article ?? Article(context: context)

【讨论】:

以上是关于Swift 3 iOS10核心数据根据id检查记录是不是已经存在的主要内容,如果未能解决你的问题,请参考以下文章

iOS Swift 3核心数据-尝试递归调用-save的致命错误:上下文中止

swift ios如何检查核心数据库中的字段

在swift ios中再次运行应用程序后核心数据显示故障记录?

具有核心数据关系的 iOS 8 Swift NSFetchResult 谓词无法访问内部 ID

根据日期检查来自同一表的记录,其中包含多行中的不匹配值

Swift 核心数据问题