0

我有两个实体,文档和字段核心数据的数据模型:NSPredicateEditor与核心数据关系

  • 文献:

    • 字段[一对多的关系]
  • Field:

    • fieldText
    • fieldDate
    • fieldNumber
    • 文档[一一对应关系]

我试图建立一个NSPredicateEditor允许基础上,有人来过滤文件某些领域的内容。我手动构建谓词编辑器,像这样:

func updatePredicateEditor() { 
    print("updatePredicateEditor") 

    let sortDescriptor = NSSortDescriptor(key: "orderIndex", ascending: true) 
    fieldsArrayController.sortDescriptors = [sortDescriptor] 
    let fields = fieldsArrayController.arrangedObjects as! [Field] 

    var keyPathsStringArray = [NSExpression]() 
    var stringFieldNames = [String]() 
    var keyPathsDateArray = [NSExpression]() 
    var dateFieldNames = [String]() 
    var keyPathsNumberArray = [NSExpression]() 
    var numberFieldNames = [String]() 

    for i in 0..<fields.count { 
     let currentField = fields[i] 

     switch currentField.type! { 
     case "Text": 
      keyPathsStringArray.append(NSExpression(forKeyPath: "fieldText")) 
      stringFieldNames.append(currentField.name!) 
     case "Date": 
      keyPathsDateArray.append(NSExpression(forKeyPath: "fieldDate")) 
      dateFieldNames.append(currentField.name!) 
     case "Number": 
      keyPathsNumberArray.append(NSExpression(forKeyPath: "fieldNumber")) 
      numberFieldNames.append(currentField.name!) 
     default: 
      print("error on field type") 
     } 
    } 

    let stringOperators = [NSNumber(unsignedInteger: NSPredicateOperatorType.ContainsPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.EqualToPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.NotEqualToPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.BeginsWithPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.EndsWithPredicateOperatorType.rawValue)] 

    let numberOperators = [NSNumber(unsignedInteger: NSPredicateOperatorType.EqualToPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.NotEqualToPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.LessThanPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.LessThanOrEqualToPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.GreaterThanPredicateOperatorType.rawValue), 
          NSNumber(unsignedInteger: NSPredicateOperatorType.GreaterThanOrEqualToPredicateOperatorType.rawValue)] 


    let dateOperators = [NSNumber(unsignedInteger: NSPredicateOperatorType.EqualToPredicateOperatorType.rawValue), 
         NSNumber(unsignedInteger: NSPredicateOperatorType.NotEqualToPredicateOperatorType.rawValue), 
         NSNumber(unsignedInteger: NSPredicateOperatorType.LessThanPredicateOperatorType.rawValue), 
         NSNumber(unsignedInteger: NSPredicateOperatorType.LessThanOrEqualToPredicateOperatorType.rawValue), 
         NSNumber(unsignedInteger: NSPredicateOperatorType.GreaterThanPredicateOperatorType.rawValue), 
         NSNumber(unsignedInteger: NSPredicateOperatorType.GreaterThanOrEqualToPredicateOperatorType.rawValue)] 

    var rowTemplatesTemp = [NSPredicateEditorRowTemplate]() // this is a temp array to hold the different popupbuttons 

    // add a template for Strings 

    let leftExpressionStringButton : NSPopUpButton 

    if keyPathsStringArray.count == 0 { 
     print("There aren't any text fields in NSPredicateEditor") 
    } 
    else { 
     let stringTemplate = NSPredicateEditorRowTemplate(leftExpressions: keyPathsStringArray, 
                         rightExpressionAttributeType: NSAttributeType.StringAttributeType, 
                         modifier: NSComparisonPredicateModifier.DirectPredicateModifier, 
                         operators: stringOperators, 
                         options: (Int(NSComparisonPredicateOptions.CaseInsensitivePredicateOption.rawValue) | 
                          Int(NSComparisonPredicateOptions.DiacriticInsensitivePredicateOption.rawValue))) 

     leftExpressionStringButton = stringTemplate.templateViews[0] as! NSPopUpButton 

     let stringButtonArray = leftExpressionStringButton.itemTitles 

     for i in 0..<stringButtonArray.count { 
      (leftExpressionStringButton.itemAtIndex(i)! as NSMenuItem).title = stringFieldNames[i] // set button menu names 
     } 

     rowTemplatesTemp.append(stringTemplate) 
    } 

    // add another template for Numbers... 

    let leftExpressionNumberButton : NSPopUpButton 

    if keyPathsNumberArray.count == 0 { 
     print("There aren't any number fields in NSPredicateEditor") 
    } 
    else { 
     let numberTemplate = NSPredicateEditorRowTemplate(leftExpressions: keyPathsNumberArray, 
                         rightExpressionAttributeType: NSAttributeType.Integer32AttributeType, 
                         modifier: NSComparisonPredicateModifier.DirectPredicateModifier, 
                         operators: numberOperators, 
                         options: 0) 

     leftExpressionNumberButton = numberTemplate.templateViews[0] as! NSPopUpButton 

     let numberButtonArray = leftExpressionNumberButton.itemTitles 

     for i in 0..<numberButtonArray.count { 
      (leftExpressionNumberButton.itemAtIndex(i)! as NSMenuItem).title = numberFieldNames[i] // set button menu names 
     } 

     rowTemplatesTemp.append(numberTemplate) 
    } 

    // add another template for Dates... 

    let leftExpressionDateButton : NSPopUpButton 

    if keyPathsDateArray.count == 0 { 
     print("There aren't any date fields in NSPredicateEditor") 
    } 
    else { 
     let dateTemplate = NSPredicateEditorRowTemplate(leftExpressions: keyPathsDateArray, 
                 rightExpressionAttributeType: NSAttributeType.DateAttributeType, 
                 modifier: NSComparisonPredicateModifier.DirectPredicateModifier, 
                 operators: dateOperators, 
                 options: 0) 


     leftExpressionDateButton = dateTemplate.templateViews[0] as! NSPopUpButton 

     let dateButtonArray = leftExpressionDateButton.itemTitles 

     for i in 0..<dateButtonArray.count { 
      (leftExpressionDateButton.itemAtIndex(i)! as NSMenuItem).title = dateFieldNames[i] // set button menu names 
     } 

     rowTemplatesTemp.append(dateTemplate) 
    } 

    // create the any, all or none thing... 
    let compoundTypes = [NSNumber.init(unsignedInteger: NSCompoundPredicateType.OrPredicateType.rawValue), 
         NSNumber.init(unsignedInteger: NSCompoundPredicateType.AndPredicateType.rawValue), 
         NSNumber.init(unsignedInteger: NSCompoundPredicateType.NotPredicateType.rawValue)] 

    // add the compoundtypes 
    let compoundTemplate = NSPredicateEditorRowTemplate(compoundTypes: compoundTypes) 
    rowTemplatesTemp.append(compoundTemplate) 

    print("setting row templates \(rowTemplatesTemp)") 

    predicateEditor.rowTemplates = rowTemplatesTemp 

    predicateEditor.addRow(self) 

} 

的问题是,NSPredicateEditor不允许NSExpressions与NSSubqueryExpressionType,所以我不能有一个子查询我的左表达。我需要的NSPredicateEditorRowTemplate以包括字段名和属性路径(fieldText,fieldDate或fieldNumber),这样从一排的最后谓词会是什么样子:

name == FIELDNAME && fieldText CONTAINS "<entered text>" 

如何做到这一点的任何建议?我应该继承NSPredicateEditorRowTemplate吗?如果是这样的话?预先感谢您的帮助。

+0

你能给出一个包含多行的最终谓词的例子吗?你想设置编辑器的谓词吗? – Willeke

+0

谢谢。我不是试图设置编辑器的谓词。对于多行,谓词将如下所示:(name == FIELDNAME004 && fieldText004 CONTAINS [cd]“”)OR(name == FIELDNAME005 && fieldText010 CONTAINS [cd]“”) –

+0

您是否想过滤文件或字段? – Willeke

回答

0

子类NSPredicateEditorRowTemplate并覆盖predicateWithSubpredicates将谓词"FIELDNAME CONTAINS <entered text>"转换为谓词"name == FIELDNAME && fieldText CONTAINS <entered text>"

+0

谢谢!好的解决方案 –