Reputation: 717
I have a computed property that is expected to return an object or nil if it fails.
var findRequest: Book {
get {
var foundRequest: Book!
API.requestBook(book: bookRequest) { book in
if book != nil {
foundRequest = book!
} else {
print("Could not find book")
foundRequest = nil
}
}
return foundRequest
}
}
When I run the code I get an unexpectedly found nil while unwrapping an Optional value error on the return foundRequest line. It looks like the code skips my closure function and goes straight to the return.
Thanks
Upvotes: 0
Views: 2522
Reputation: 54785
There are several issues with your implementation. First of all, you shouldn't define foundRequest
as an implicitly unwrapped optional if there is a possibility that its value will be nil
. Second of all, you are returning the value outside the completion handler of the asynchronous function API.requestBook
, so you are returning before foundRequest
could get a value and hence you are returning the default value of nil
, which will be force unwrapped due to the implicitly unwrapped optional declaration, hence the error.
Moreover, you shouldn't make an asynchronous request inside the getter of a computed property, since computed properties are supposed to return a value right away.
You should completely change your implementation to make findRequest
a function returning a value of type Book
inside a completion handler.
func findRequest(bookRequest: URLRequest, completion: @escaping (Book?->Void)){
API.requestBook(book: bookRequest) { book in
if let book = book {
completion(book)
} else {
print("Could not find book")
completion(nil)
}
}
}
You can call the function like this:
findRequest(bookRequest: yourRequest, completion: { book in
if let book = book {
//use the returned value
} else {
print("Book not found")
}
})
You might have to change the type of bookRequest
from URLRequest
depending on what the type of the input parameter book
needs to be.
Upvotes: 3
Reputation: 16256
I have a computed property that is expected to return an object or nil if it fails.
Then you should probably define it as:
var findRequest: Book? {
// ...
(note the "?" after Book
)
Also, like Martin mentioned in the comments, your computed property's getter is supposed to return a value right away, but you are making what looks like an asynchronous call to retrieve the value. The getter itself returns right away, before the completion handler is called. There is no way the side accessing the property will get the actual value returned by the API.
Upvotes: 0