0

I have a function that accepts a request and an optional callback for a server response:

static func getData(request: NSMutableDictionary?, callback: ((Dictionary<String, Any>) -> Void)? ) {
    // ...
}

I want to write a wrapper over this function in which the parameters are not optional. I did it like this:

static func getData(id: CLong, callback: ((Dictionary<String, Any>) -> Void) ) {
    getData(request: ["userId" : id], callback: callback)
}

The problem is that swift cannot convert type ((Dictionary<String, Any>) -> Void) to type ((Dictionary<String, Any>) -> Void)?. And I can't figure out why. After all, we can successfully convert non optional to optional:

var a = "hello"
var b: String? = a // correct

Why can't swift do it? Why does Swift think that Type ((Dictionary<String, Any>) -> Void) and Type ((Dictionary<String, Any>) -> Void)? are completely different types, and not optional variations of the same type?

Sweeper
  • 213,210
  • 22
  • 193
  • 313
RareScrap
  • 541
  • 1
  • 7
  • 17
  • The rule is an optional variable might be nil and the non-option variable never be nil. In your case, you are trying to set the optional value to non-optional. So, whenever you optional value gets nil there will be an exception. Avoiding that exception swift not letting you cast. – Satyendra Chauhan Sep 10 '20 at 05:04

1 Answers1

3

When a closure is wrapped inside an optional, that closure "escapes". If you don't know what "escapes" means, read this answer of mine.

The non-optional closure in the second getData, however, is not @escaping. So you are trying to make a non-escaping closure escape! The error message is kind of confusing here, but if you pass .some(callback) rather than callback directly, it becomes clear what's happening:

Converting non-escaping parameter 'callback' to generic parameter 'Wrapped' may allow it to escape

So you should mark callback in your second getData as @escaping:

func getData(id: CLong, callback: @escaping ((Dictionary<String, Any>) -> Void) ) {
Sweeper
  • 213,210
  • 22
  • 193
  • 313