Lastmboy Lastmboy - 1 month ago 13
iOS Question

Cannot call value of non-function type (declared as var)

I migrated my project to Swift 3 and am down to 4 errors in an open source framework. The open source code is https://github.com/blackmirror-media/BMInputBox. It was working fine in Swift 2.2. It migrated fairly smoothly, with the exception of these errors. The errors are all the same and state:

.../Pod/Classes/BMInputBox.swift:430:26:
Cannot call value of non-function type '((AnyObject...) -> Void)!'


Here's the code it relates to:

/// Closure executed when user submits the values.
open var onSubmit: ((_ value: AnyObject...) -> Void)!

/// As tuples are not supported in Objc, this is a method, which is called as well, but instead an array of values are returned
open var onSubmitObjc: ((_ value: [AnyObject]) -> Void)!

/// Closure executed when user cancels submission
open var onCancel: (() -> Void)!

/// Closure executed when the value changes in the field. The caller can modify the value and return it
open var onChange: ((_ value: String) -> String)?

func cancelButtonTapped () {
if self.onCancel != nil {
self.onCancel()
}
self.hide()
}

func submitButtonTapped () {

// Submitting the form if valid
if self.validateInput() {
if self.onSubmit != nil {
let valueToReturn: String? = self.textInput!.text

if let value2ToReturn = self.secureInput?.text {
*Error> self.onSubmit(valueToReturn, value2ToReturn)
}
else {
*Error> self.onSubmit(valueToReturn)
}
}

if self.onSubmitObjc != nil {
let valueToReturn: String? = self.textInput!.text

if let value2ToReturn = self.secureInput?.text {
*Error> self.onSubmitObjc([valueToReturn!, value2ToReturn])
}
else {
*Error> self.onSubmitObjc([valueToReturn!])
}
}

self.hide()
}

// Shaking the validation label if not valid
else {
self.animateLabel()
}
}


I'm new to Swift and am having trouble figuring out what this is actually supposed to do. Without knowing that, it's hard to figure out what Swift 3 doesn't like about it.

What does this line actually do?

open var onSubmit: ((_ value: AnyObject...) -> Void)!


To my inexperienced eyes, it looks like it's trying to pass a tuple to a function that is declared as a variable (rather than a function) and that doesn't do anything or return anything. I'm obviously missing something. Can anyone explain why it is declared as a variable and why there is no logic defined in it? If anyone knows why Swift 3 is complaining, that would be a bonus!

Answer

onSubmit is a variable holding a closure as an implicitly unwrapped optional. But the error message is misleading, the actual reason is that strings (numbers, etc) are not automatically bridged to AnyObject anymore in Swift 3.

Replacing AnyObject by Any (the protocol to which all types conform) in those closure definitions should solve the problem.