Madhu
Madhu

Reputation: 994

How to set NSFetchRequest propertiesToFetch with a custom function using NSExpression

I have a attribute "message" of type String in CoreData Entity, which stores text and sometimes including URLs . Now i need to fetch all the url's from the entity.

    let predicate = NSPredicate(format:"message CONTAINS[cd] %@", "http")
    let fetchRequest = self.getfetchRequest(entityName: "Messages", sectionKey:nil, predicate:predicate)
    let expressionDescription = NSExpressionDescription()
    expressionDescription.name = "urlFromMsg"
    expressionDescription.expressionResultType = .StringAttributeType
    let expression = NSExpression(forFunction: "toUrl", arguments: [NSExpression(forKeyPath: "message")])

    expressionDescription.expression = expression
    fetchRequest.propertiesToFetch = [expressionDescription]
    fetchRequest.resultType = NSFetchRequestResultType.DictionaryResultType

Here toUrl is a custom function that extends String.

extension String {
    func toUrl()->[String]?{
        let detector = try! NSDataDetector(types: NSTextCheckingType.Link.rawValue)
        let matches = detector.matchesInString(self, options: [], range: NSRange(location: 0, length: self.utf16.count))
        var urls = [String]()
        for match in matches {
            urls.append((self as NSString).substringWithRange(match.range))
        }
        return urls
    }
}

i am getting crash at this line

let expression = NSExpression(forFunction: "toUrl", arguments: [NSExpression(forKeyPath: "message")])

How to set the custom method properly in NSExpression.

Upvotes: 1

Views: 733

Answers (1)

Tom Harrington
Tom Harrington

Reputation: 70976

When using a custom NSExpression in a fetch request and a SQLite-backed Core Data store, Core Data attempts to translate the expression into a SQL query. That helps with performance, but it means that not all valid NSExpressions are valid for use with Core Data.

Specifically, an NSExpression that relies on a custom function can't be used with a Core Data fetch, because Core Data can't translate arbitrary code into SQL.

You'll need to drop this NSExpression from the fetch and convert to URLs using the results of the fetch. You could also switch to a non-SQLite Core Data store, but that's generally much worse for a variety of reasons unless your persistent store contains very small amounts of data.

Upvotes: 1

Related Questions