I have code for executing an NSFetchRequest
and casting its result to an array of my custom data model type. Fetching may throw but I don't want to care about the error so I use try?
, and I also use as?
in casting. In Swift 2, this used to be just fine, but Swift 3 produces a double optional:
var expenses: [Expense]? {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: Expense.entityName)
request.predicate = NSPredicate(format: "dateSpent >= %@ AND dateSpent <= %@", [self.startDate, self.endDate])
// Returns [Expense]? because right side is [Expense]??
if let expenses = try? App.mainQueueContext.fetch(request) as? [Expense],
expenses?.isEmpty == false {
return expenses
}
return nil
}
How can I rephrase the right side of my optional binding in if let
so that its type will simply be an array [Expense]
? I think it looks absurd that in the following boolean condition (which used to be a where
clause), the array is still optional.
You must wrap your try?
call within parenthesis like this :
if let expenses = (try? App.mainQueueContext.fetch(request)) as? [Expense]
That's because as?
has a higher precedence than try?
(probably because try?
can be applied to the whole expression).
@Fantattitude's answer gives what you want. But it takes me a while to go through the document to find out why. To long to be a comment, so here's the reference:
According to The Swift Programming Language (Swift 3) Expressions Chapter
When the expression on the left hand side of a binary operator is marked with try, try?, or try!, that operator applies to the whole binary expression.
Firstly, I thought as
may not be a binary operator, but in Swift Standard Library Operators
as
,as?
, andas!
are Infix operators operators
and in Operator Declaration chapter
An infix operator is a binary operator that is written between its two operands, such as the familiar addition operator (+) in the expression 1 + 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With