Cannot call value of non-function type 'String'
Asked Answered
U

7

43

I'm trying to pass the ILTItem variable into my ILTViewController, triggered by AppDelegate.swift when the user launches my app via a deeplink.

The code I have errors with:

Cannot call value of non-function type 'String'

on the line where I define ilt.

Here's the code I have at the moment:

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var ilt = ILT(homeworkID: 1234, title: "History ILT", subject: "History", teacher: "Miss A Smith", teacherCode: "asmith", studentID: 12345, description: "Description....", due: 1450137600, status: "In Progress", hasAttachments: true)
var newVC = ILTViewController()
newVC.ILTitem = ilt
appDelegate.window?.addSubview(newVC.view)

Why could this be? In my ILTViewController class I have:

class ILTViewController: UIViewController {
  // accept the incoming ILT struct
  var ILTitem: ILT!

IlT Struct Declaration:

struct ILT {
    let homeworkID: Int
    let title: String
    let subject: String
    let teacher: String
    let teacherCode: String
    let studentID: Int
    let description: String
    let due: Double
    let status: String
    let hasAttachments: Bool
}
Unpaged answered 27/1, 2016 at 14:15 Comment(7)
Post your ILT class declarationAccommodative
@Accommodative I have added itUnpaged
Your code works fine: swiftstub.com/580271845 . You've probably declared a String variable named ILT somewhere else and that's why it fails.Accommodative
@Accommodative That's not the issue, as when I combine it down to newVC.ILTItem = ILT(homeworkID: 1234, title: "History ILT", subject: "History", teacher: "Miss A Smith", teacherCode: "asmith", studentID: 12345, description: "Description....", due: 1450137600, status: "In Progress", hasAttachments: true) it still fails with the same message.Unpaged
What I was saying is that you redeclared ILT (uppercase), not ilt (lowercase). The error is telling you that you are trying to call a String instead of a method (struct constructor in your case). And, as you can check in the link I provided, the error is elsewhere in your code, because the code you posted works fine.Accommodative
@Accommodative Oh, I see. Didn't realise variables and methods can clash names, I've found the problem now. Thank you very much :)Unpaged
Cool, I'll convert the comment to an answer so others can benefit from it.Accommodative
A
42

The error is telling you that you are trying to call a String instead of a method (struct constructor in your case). You've probably declared a String variable named ILT (uppercase) somewhere else and that's why it fails.

Your posted code works fine so the error must be somewhere else in your code.

Accommodative answered 27/1, 2016 at 17:50 Comment(3)
Thanks. Related but slightly separate issue to the question - my ILTViewController: UIViewController class does not receive the new variable - printing ILTItem.title returns null. Any idea why?Unpaged
I recommend you to open a new question with the relevant code and preferably a self contained sample project reproducing the issue.Accommodative
Happened to me when accidentally calling a KRProgressHUD.show()() (double parenthesis accident)Filberte
E
5

Wrap your let statement in if eg:

if let xxx = yyy {
   ... do something
}
Enid answered 22/9, 2016 at 21:55 Comment(0)
N
3

Works:

let works = ["foo", "bar"].first(where: { ($0 == "foo") } )
let works = ["foo", "bar"].first(where: { (_ in true) } )

Fails:

let fails = ["foo", "bar"].first(where: { (true) } )

// Cannot call value of a non-function type 'String?'

You must be sure to use the parameter ($0 or _ in) in the closure expression.

Use _ in or $0 to discard or reference the parameter. You cannot simple move directly into the closure body and return true or you will receive this (extremely unhelpful) error.

Nyaya answered 24/5, 2017 at 19:26 Comment(0)
G
2

Had a similar issue in this code

array.first { $0 == item }

The problem was with $0 not conforming to Equatable protocol. In my case it conformed to NSObjectProtocol and simple pointer comparison was enough, so I fixed the issue with

array.first { $0 === item }
Gerald answered 1/9, 2017 at 14:9 Comment(0)
V
1

So I had a problem with a similar error message. I am writing a structure to handle Scalars for my library and needed a square root. Error was

Cannot call value of non-function type 'Vsip.Scalar'

when calling sqrt. Fixed it by explicitly calling sqrt as shown below. Hope this helps.

public var sqrt: Scalar {
        switch self.type {
        case .f:
            return Scalar(sqrtf(self.realf))
        case .d:
            let x = Foundation.sqrt(self.reald)
            return Scalar(x)
        case .cf:
            return Scalar(vsip_csqrt_f(self.vsip_cf))
        case .cd:
            return Scalar(vsip_csqrt_d(self.vsip_cd))
        default:
            precondition(false, "sqrt not supported for type \(self.type)")
        }
    }
Violetavioletta answered 21/10, 2016 at 15:44 Comment(0)
N
1

In messing around with Swift's various closure syntax types + autocomplete I often find myself in a mess of variables, return types, and using too few or too many sets of () or {}

I ended up with something like:

filenames.first(where: { $0 == filename } ) {

}

Which was giving the error

Cannot call value of non-function type

Solution was to remove the trailing { }, which is not correct in this form.

Should just be filenames.first(where: { $0 == filename } )

Check that you have not incorrectly applied a set of braces to the end of your non-function, etc., or some other hard to spot error in your current chosen Swift closure syntax.

Nyaya answered 24/5, 2017 at 18:22 Comment(0)
A
0

Check if you haven't missed ? for optionals.

That error can be shown for a different issue in a heavy-loaded schemes, like when I forget to mark optional.

services.first(where: { $0.category?.id == categoryID })

Augsburg answered 26/1, 2023 at 13:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.