Matt Quiros Matt Quiros - 2 months ago 7
iOS Question

Optional binding with try? and as? still produces an optional type

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.

Answer

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).