核心数据 - 提取,排序和编辑/更新属性

时间:2016-01-26 11:07:33

标签: ios swift core-data

所以我已经把我的脚趾浸入核心数据池,而且它确实是一个黑暗神秘的游泳池......

我有以下内容:

名为RAS的实体。

RAS中存在以下属性:

    类型为rasIdentifier
  1. String(非可选)
  2. rasAutoRetire类型Bool(可选)
  3. rasAutoRetireDate类型NSDate(可选)
  4. rasReassessmentDate类型NSDate(可选)
  5. rasReassesmentDueNow类型Bool(可选)
  6. rasAutoRetireDone类型Bool(可选)
  7. rasReassessmentDone类型Bool(可选)
  8. 当我第一次保存"记录"发生以下情况:

    • 如果用户选择项目在特定的未来日期自动退出,则值设置如下:

    • rasIdentifier获得唯一值。

    • rasAutoRetire设置为true
    • rasAutoRetireDate设置为特定日期(比如将来一周)。
    • rasReassessmentDate留空
    • rasReassessmentDueNow设置为false
    • rasAutoRetireDone设置为false
    • rasReassessmentDone设置为false

    • 如果用户选择在特定的未来日期重新评估项目,则值设置如下:

    • rasIdentifier获得唯一值。

    • rasAutoRetire设置为false
    • rasAutoRetireDate留空。
    • rasReassessmentDate设置为特定日期。
    • rasReassessmentDueNow设置为false
    • rasAutoRetireDone留空
    • rasReassessmentDone设置为false

    从上面可以看出,未来一个项目有两种选择:自动退役或重新评估。

    为了检查一个项目是否已经到达并通过了它的重新评估日期,我已经开始编写以下函数,但是代码很笨拙,我无处可去,我真的很感谢这里有一些天才的帮助...... :

    func HandleItemsThatNeedReassessment() {
    
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedObjContext = appDelegate.managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: "RAS")
    var error: NSError?
    
    //Step 1:  Check if database exists
    let count = managedObjContext.countForFetchRequest(fetchRequest, error: &error)
    if count == NSNotFound {
    
        print("Database does not exist")
    
    } else {
    
        print("Database exists.  Check now if there are any records.")
    
        //Step 2:  Check if there are any records in the database
    
        do {
    
        let results = try managedObjContext.executeFetchRequest(fetchRequest)
        let varRecordsExist = results as! [NSManagedObject]
    
            if varrecordsExist.count == 0 {
    
                print("No records in the database")
                //do nothing further!
    
            } else {
    
                print("Yes, there are \(varRecordsExist.count) records in the database.")
    
                //Step 3:  Select all the existing records that are due for reassessment (and leave those that are due for auto-retirement - for now)
    //NO IDEA WHAT TO DO HERE!
    
    
    
                    //Step 4:  Check which items are due for reassessment, but exclude those that have already been reassessed (rasReassessmentDone = true)
    //NO IDEA WHAT TO DO HERE EITHER!
    
    
    
                    //Step 5:  Because the reassessment date is in the past, change the valueForKey("rasReassessmentDueNow") to TRUE
                    if varIsAssessmentOverdue == true {
    //NO IDEA WHAT TO DO HERE - AGAIN!
    
                        ??SomethingHere??.setValue(true, forKey: "rasReassessmentDueNow")
    //Do this for all items that needs reassessment
    
                    }
    
                    //Step 6:  If any changes were made/values were changed in Step 5, SAVE those changes to Core Data
                    if managedObjContext.hasChanges {
                        do {
                            try managedObjContext.save()
    
                            //How do you save these changes???
    
                        } catch let error as NSError  {
                            NSLog("Could not save \(error), \(error.userInfo)")
                        }
                    }
    
                }
    
            }
    
        }
    
        catch
    
        let error as NSError {
    
        print("Print error stuff here \(error)")
    
        }
    
    }
    }
    

    是的,尝试的代码很糟糕。我甚至不知道我的步骤是否合乎逻辑。甚至可以一次完成这一切吗?上面的很多内容对我来说没有意义 - 尽管谷歌搜索和阅读时间 - 并且一个善意,全面的解释将受到高度赞赏。

    顺便说一句,在app的第一个视图控制器的viewDidLoad中调用此函数,这就是为什么我在步骤1和步骤2中执行所有这些检查的原因,否则事情就会崩溃到停止如果没有记录。

1 个答案:

答案 0 :(得分:1)

我不会在开始时检查数据库中是否有任何内容,我会直接跳到第3步。 您只需指定符合要求的谓词,例如:

    //Step 3:  Select all the existing records that are due for reassessment (and leave those that are due for auto-retirement - for now)
    //You could also combine it with Step 4 in the same predicate:
    let predicate1 = NSPredicate(format: "%K == true AND %K == false AND %K = false", "rasReassessmentDueNow", "rasAutoRetire", "rasReassessmentDone")

现在像上面一样创建获取请求,将谓词添加到请求并运行它。

    fetchRequest.predicate = predicate1

do {

    let results = try managedObjContext.executeFetchRequest(fetchRequest)
    let records = results as! [NSManagedObject]
    ...

现在您有一个带对象的数组,在这里您可以检查count属性以查看是否有任何数据。

在步骤5中,只需枚举数组并检查varIsAssessmentOverdue是否为true。 但说实话,我会在上面的谓词中添加另一个预测,检查varIsAssessmentOverdue为真(..AND%K == true&#34;,..&#34; varIsAssessmentOverdue&#34;)在这种情况下你只有您想要的对象,您只能枚举数组并将值设置为所需的对象,数组中的每个对象都将是您要查找的对象<​​/ p>

for ras in results {
         // I don't understand what you are trying to do here, all of the items here will be true and you want to change it to true again?
         ras.setValue(value, forKey: attribute)
}

保存代码中的更改。

将此代码主要视为伪代码,某些位需要进行少量修改,但您应该能够进行修改。

这里的想法是尽可能少地访问数据库。您应该创建NSPredicate,它只返回您想要的数据结果,之后只需更改数据并保存即可。