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

謝謝!好的解決方案 –