如何在调用fetch之前验证NSPredicate

时间:2018-12-29 14:25:33

标签: ios core-data nspredicate nsfetchrequest

我使用自定义格式字符串创建搜索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 :(得分:0)

您可以使用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

答案 1 :(得分:0)

没有内置方法可以验证谓词格式字符串是否为有效谓词。对于格式字符串,您确实需要通过以下方式来验证谓词:(a)在开发过程中对其进行测试,以及(b)验证谓词中的替换值至少是正确的数据类型。

如果这是一个问题,您可能会发现以其他方式而不是使用格式字符串来构建谓词会更好。例如,使用NSComparisonPredicateNSCompoundPredicateNSExpression的实例构建谓词。该代码将更加冗长,但是通过在构造谓词时检查它的每个部分,可以更轻松地确保谓词有效。

相关问题