While there is an accepted answer, which provides some clarity, explaining that it's a Swift bug is not really accurate. That being said, the explanation is accurate but not for this issue.
Allowing the closure to be added to setValue in the first place is the real bug.
A more accurate answer is that there is no completion block/closure for the setValue function, which is why it fails.
The specific function -setValue: does NOT have a closure, which is why it's crashing. i.e. it's an incorrect implementation in your code. Per the docs:
func setValue(_ value: Any?)
note that the setValue function does NOT have a closure and if you add one the function will have no idea what to do with that data.
To use a completion block/closure, you must call the correct function which is
-setValue:withCompletionBlock:
Bottom line is you can't randomly add a parameter or call to a function that's not designed to accept it.
This is obviously not valid but conceptually it's the same error.
let a = "myString"
a.append("x") { (error: Error?) }
In this case the compiler knows the the string.append function doesn't have a closure option and catches it before compiling.
So go a tad further, this code complies & runs but also generates an error
ref.child("child").setValue("value") { }
Again, setValue doesn't have a closure so this code is improperly implemented.
To clarify, given a class
class MyClass {
var s = ""
var compHandler = {}
func setValue(aString: String) {
self.s = aString
}
func setValue(aString: String, someCompletionHandler: completionHandler) {
self.s = aString
self.compHandler = someCompletionHandler
}
}
Note that setValue:aString is a totally different function than setValue:aString:someCompletionHandler
The only parameter that can be based to setValue:aString is a String as the first and only parameter.
The setValue:aString:someCompletionHandler will be passed two parameters, a String in the first position and a completionHandler in the second position.
The actual completion block is the second parameter passed.
param1, param2
------, ---------------
string, completionBlock
This is why
setValue(value) {}
is improperly formatted whereas
setValue(value, withBlock: {})
is properly formatted.