Как проверить NSPredicate перед вызовом fetch - PullRequest
0 голосов
/ 29 декабря 2018

Я создаю поиск NSPredicate, используя строку произвольного формата.Иногда синтаксис этой строки неправильный, и когда я выполняю выборку, используя NSFetchRequest с этим предикатом, я получаю NSInvalidArgumentException, например, когда путь ключа неверен.Я бы предпочел проверить этот предикат (вызвать метод, который возвращает YES, если формат в порядке), чем выдать исключение, которое приводит к сбою моего приложения.Что я могу сделать?

Чтобы перефразировать запрос в простой вопрос:

Можно ли проверить предикат без потенциального сбоя приложения?

Вот пример кода в Swift:

let text = "price > 0.1" // ok, no syntax error
let text = "price > 'abc'" // error
let predicate = NSPredicate.init(format: text, argumentArray: [])
let request = NSFetchRequest<Fruit>.init(entityName: "Fruit")    
request.predicate = predicate
request.fetchLimit = 1
let fruit = try myContext.fetch(request) as [Fruit]  // exception thrown here that crashes app
// sometimes the exception can be caught with an obj-c try/catch
// sometimes it can't be caught, and causes program to terminate
// CAN WE HAVE A SOLUTION THAT NEVER CAUSES A CRASH ?

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

Нет встроенного способа проверить, является ли строка формата предиката допустимым предикатом.В случае форматных строк вам действительно нужно проверить предикаты, (а) проверив их во время разработки и (б) проверив, что значения подстановки в предикатах, по крайней мере, имеют правильный тип данных.

Если это проблема, вы можетелучше строить свои предикаты другими способами, а не с помощью форматных строк.Например, используйте NSComparisonPredicate и NSCompoundPredicate для построения предикатов из экземпляров NSExpression.Код будет гораздо более подробным, но будет проще убедиться, что ваш предикат действителен, проверяя каждую его часть при ее создании.

0 голосов
/ 29 декабря 2018

Вы можете использовать evaluate(with:) для проверки формата NSPredicate,

Возвращает логическое значение, указывающее, соответствует ли указанный объект условиям, указанным в предикате.

Swift 4.2:

Например,

let dataArray = [
        "Amazon",
        "Flipkart",
        "Snapdeal",
        "eBay",
        "Jabong",
        "Myntra",
        "Bestbuy",
        "Alibaba",
        "Shopclue"
    ]
let searchString = "buy"
let predicate = NSPredicate(format: "SELF contains %@", searchString)
let searchResult = dataArray.filter { predicate.evaluate(with: $0) }
print(searchDataSource)

if !searchResult.isEmpty {
    //success
} else {
    //evaluation failed
}

Чтобы избежать исключения, вы можете использовать try-catch block

...