Reputation:
On the 3rd line in the function below I get the following error:
Unable to infer closure type in the current context
How do I fix this?
func fetchAllUsersImages() {
print("inside func")
self.ref.child("Posts").child(self.userID).child(self.postNum).observe(.childAdded, with: { snapshot in //error here
var images: [URL] = []
if let snapShotValue = snapshot.value as? [String: String] {
for (_, value) in snapShotValue {
if let imageURL = URL(string: value) {
print(imageURL, "image url here")
let imageAsData = try Data(contentsOf: imageURL)
let image = UIImage(data: imageAsData)
let ImageObject = Image()
ImageObject.image = image
self.arrayOfImgObj.append(ImageObject)
self.tableView.reloadData()
}
}
}
})
}
Upvotes: 18
Views: 30421
Reputation: 4745
In addition to ScottyBlades answer, I'd like to add two data points to the "experience". It looks like referencing a non-existent property using self
inside the block is not handled nicely by the compiler.
Nice error inside the block:
// Setting a handler for an NWListener instance:
self.nwListener?.newConnectionHandler = { (_ connection: NWConnection) -> Void in
// Results in "Cannot find 'nonExistentProperty' in scope"
// in the line below:
guard let delegate = nonExistentProperty else { return }
}
Weird "Type of expression is ambiguous without more context" error: (note the new self in front of nonExistentProperty)
// Setting a handler for an NWListener instance:
// Results in "Type of expression is ambiguous without more context"
// at the equals sign below:
self.nwListener?.newConnectionHandler = { (_ connection: NWConnection) -> Void in
guard let delegate = self.nonExistentProperty else { return }
}
Upvotes: 1
Reputation: 13993
This error can also happen if you have a non related compilation error in your closure body. For example, you may be trying to compare two or more non-boolean types.
extension Array where Element == Resistance {
init(_ points: [Point]) {
let peaks = points.beforeAndAfter { (before, current, after) -> Bool in
before < current && current > after
}
self = []
}
}
will produce Unable to infer closure type in the current context
.
The correct code:
extension Array where Element == Resistance {
init(_ points: [Point]) {
let peaks = points.beforeAndAfter { (before, current, after) -> Bool in
before.value < current.value && current.value > after.value
}
self = []
}
}
Upvotes: 7
Reputation: 30391
The reason why it is not inferring the closure type is because the try
statement is not handled. This means that the closure expected to "catch"
the error, but in your case, you forgot the do-try-catch
rule.
Therefore you can try the following answer which will catch your errors:
do {
let imageAsData = try Data(contentsOf: imageURL)
let image = UIImage(data: imageAsData)
let ImageObject = Image()
ImageObject.image = image
self.arrayOfImgObj.append(ImageObject)
} catch {
print("imageURL was not able to be converted into data") // Assert or add an alert
}
You can then assert an error (for testing), or what I would personally do, is set up an alert.
This way the app wouldn't crash, but instead, notify the user. I find this very helpful when on the go and my device isn't plugged in - so I can see the error messages instead of a blank crash with no idea what happened.
Upvotes: 11