Example #1
0
        // 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()));
        }