user10497264
user10497264

Reputation:

Unable to infer closure type in the current context

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

Answers (3)

Rainer Schwarze
Rainer Schwarze

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

ScottyBlades
ScottyBlades

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

George
George

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

Related Questions