// Parses the predicate and attempts to generate a characteristic-value tuple. static Tuple <HMCharacteristic, NSCopying> GetCharacteristicPair(this NSPredicate self) { var predicate = self as NSCompoundPredicate; if (predicate == null) { return(null); } var subpredicates = predicate.Subpredicates; if (subpredicates == null) { return(null); } if (subpredicates.Length != 2) { return(null); } NSComparisonPredicate characteristicPredicate = null; NSComparisonPredicate valuePredicate = null; foreach (var subpredicate in subpredicates) { var comparison = subpredicate as NSComparisonPredicate; if (comparison != null && comparison.LeftExpression.ExpressionType == NSExpressionType.KeyPath && comparison.RightExpression.ExpressionType == NSExpressionType.ConstantValue) { var keyPath = comparison.LeftExpression.KeyPath; if (keyPath == HMCharacteristic.KeyPath) { characteristicPredicate = comparison; } else if (keyPath == HMCharacteristic.ValueKeyPath) { valuePredicate = comparison; } } } if (characteristicPredicate != null && valuePredicate != null) { var characteristic = characteristicPredicate.RightExpression.ConstantValue as HMCharacteristic; var characteristicValue = valuePredicate.RightExpression.ConstantValue as NSCopying; return(new Tuple <HMCharacteristic, NSCopying> (characteristic, characteristicValue)); } return(null); }
private NSCompoundPredicate FindMatches(string searchString) { /* * Each searchString creates an OR predicate for: name, yearIntroduced, introPrice. * Example if searchItems contains "Gladiolus 51.99 2001": * - name CONTAINS[c] "gladiolus" * - name CONTAINS[c] "gladiolus", yearIntroduced ==[c] 2001, introPrice ==[c] 51.99 * - name CONTAINS[c] "ginger", yearIntroduced ==[c] 2007, introPrice ==[c] 49.98 */ var searchItemsPredicate = new List <NSPredicate>(); /* * Below we use NSExpression represent expressions in our predicates. * NSPredicate is made up of smaller, atomic parts: * two NSExpressions (a left-hand value and a right-hand value). */ // Name field matching. var titleExpression = NSExpression.FromKeyPath(ExpressionKeys.Title); var searchStringExpression = NSExpression.FromConstant(new NSString(searchString)); var titleSearchComparisonPredicate = new NSComparisonPredicate(titleExpression, searchStringExpression, NSComparisonPredicateModifier.Direct, NSPredicateOperatorType.Contains, NSComparisonPredicateOptions.CaseInsensitive | NSComparisonPredicateOptions.DiacriticInsensitive); searchItemsPredicate.Add(titleSearchComparisonPredicate); var numberFormatter = new NSNumberFormatter { NumberStyle = NSNumberFormatterStyle.None, FormatterBehavior = NSNumberFormatterBehavior.Default }; // The `searchString` may fail to convert to a number. var targetNumber = numberFormatter.NumberFromString(searchString); if (targetNumber != null) { // Use `targetNumberExpression` in both the following predicates. var targetNumberExpression = NSExpression.FromConstant(targetNumber); // The `yearIntroduced` field matching. var yearIntroducedExpression = NSExpression.FromKeyPath(ExpressionKeys.YearIntroduced); var yearIntroducedPredicate = new NSComparisonPredicate(yearIntroducedExpression, targetNumberExpression, NSComparisonPredicateModifier.Direct, NSPredicateOperatorType.EqualTo, NSComparisonPredicateOptions.CaseInsensitive | NSComparisonPredicateOptions.DiacriticInsensitive); searchItemsPredicate.Add(yearIntroducedPredicate); // The `price` field matching. var priceExpression = NSExpression.FromKeyPath(ExpressionKeys.IntroPrice); var finalPredicate = new NSComparisonPredicate(priceExpression, targetNumberExpression, NSComparisonPredicateModifier.Direct, NSPredicateOperatorType.EqualTo, NSComparisonPredicateOptions.CaseInsensitive | NSComparisonPredicateOptions.DiacriticInsensitive); searchItemsPredicate.Add(finalPredicate); } return(NSCompoundPredicate.CreateOrPredicate(searchItemsPredicate.ToArray())); }