Search code examples
swiftfunctionclosuresany

How do you handle closures that return Any? type in swift?


I noticed that sometimes calling a function returns an Any? type.

One such example is the AccessToken.refreshCurrentAccessToken method from the Facebook Login iOS SDK.

The data that comes back is of type "Any?"

How do you correctly handle this type when you don't know what it contains?

What is the correct way to anticipate and handle a function that returns the Any? type in swift?

Example:

 AccessToken.refreshCurrentAccessToken { (connection:GraphRequestConnection?, data:Any?, error:Error?) in
    if error != nil {
        print("error")
        return
    }
            
    print("no error: data is /(data)")
 }

In this case, data returns the following in the debugger. But theres no way to know ahead of time what is in it.

(lldb) po data
▿ Optional<Any>
  ▿ some : 1 element
    ▿ 0 : 2 elements
      - key : data
      ▿ value : 3 elements
        ▿ 0 : 2 elements
          ▿ 0 : 2 elements
            - key : status
            - value : granted
          ▿ 1 : 2 elements
            - key : permission
            - value : email
        ▿ 1 : 2 elements
          ▿ 0 : 2 elements
            - key : status
            - value : granted
          ▿ 1 : 2 elements
            - key : permission
            - value : openid
        ▿ 2 : 2 elements
          ▿ 0 : 2 elements
            - key : status
            - value : granted
          ▿ 1 : 2 elements
            - key : permission
            - value : public_profile

Solution

  • In this specific case, it doesn't look like any useful information will be returned in that parameter. According to the docs:

    An optional callback handler that can surface any errors related to permission refreshing.

    In a more general sense, you'd have to know some sort of information about what Any? might contain and then you could do a type match with as? such as:

    if let d = data as? Data {
    
    }
    

    See: https://docs.swift.org/swift-book/LanguageGuide/TypeCasting.html

    Then, inside { } you have access to a typed version if it passed the match successfully. But, again, you'd have to know what types you might encounter to do such a test.