'unresolved identifier' for return value of Type Method in Swift - swift

I'm trying to access the return value from a Type Method in one file from another file. To wit:
file_1:
class LetterView: UIView {
class func testFunction() -> CGSize {
return CGSizeMake(100,200)
}
}
file_2:
class AnotherClass {
func callTestFunction() {
var result = LetterView.testFunction()
print("- breakpoint here - ")
}
}
I get an Unresolved Identifier error on var result if I put a breakpoint in the debugger and do a po result. However if I change the return type of testFunction() to be an Int (say 2) and return that instead, then the function call works as expected. Color me confused.

Is the second file importing UIKit as well? Also, you should update your example from function to func. This all works in the playground which leads to UIKit missing.

There could be a few possible issues.
One of the classes has a Testing target and other one doesn't. You have to even include all of your classes in the testing target or none of them.
If it's Objective C class, check that the class is in ObjectiveC bridging header file.
If it's NSManagedObject subclass. Add #objc(className) before the class declaration.
If it's part of a different framework, make sure that the class or function is public
This is the original answer link : Swift Compiler Error: Use of unresolved identifier 'name'

Related

Class Declaration and Usage

Newbie question. I am simply trying to declare a class (or even struct) as a separate Swift file and then build it or use it inside a separate class. Consider this:
import Foundation
class PayloadTest{
var label: String
init(label:String) {
self.label = label
}
}
---- then separate file
import WatchKit
import Foundation
class InterfaceController2: WKInterfaceController {
var payloadtest = PayloadTest(label: "test string init")
payloadtest.label = "test" // this line gives error - says it was expecting a declaration
.
.
.
}
I can't figure out why if I make a class or struct at the same level in my watchOS extension, it is not allowed to be accessed or recognized when I try to access the variables.
As dfd mentioned in the comment section this is a scope issue. In many programming languages you just can't write statements (expressions) which is not either a declaration or initialization or a method call outside the function or a method.
Let me explain what I said,
In a class or a structure definition any statements(expressions) apart from declaration & initialization should be present in the function (method) definition.
class PayloadTest{
//The below statement is declaration, which declares label is an property of type string.
var label: String
init(label:String) {
//The below statement is an assignment, and it compiles and execute fine as this is inside a init method.
self.label = label
}
}
However in your second snippet,
import WatchKit
import Foundation
class InterfaceController2: WKInterfaceController {
//The below statement compiles fine even tough it isn't present inside a method coz it is initialization statement.
var payloadtest = PayloadTest(label: "test string init")
//However the compiler complains about the below assignment statement because, this is neither an declaration nor an initialization statement and it should not be outside method.
//So you've to keep this statement inside a method for compiler to stop complaining.
payloadtest.label = "test" // this line gives error - says it was expecting a declaration
....
}
To make the second snippet work put the below line of code in a method and call that method,
payloadtest.label = "test"
So always remember any statements apart from declaration, initialization should be present inside a method or function definition and this applies to most of the languages.
Please go through the various scope levels present. HTH :)
You can't have an expression nested in a class like that. You can get around this by putting your code in a closure which you immediately call:
class InterfaceController2: WKInterfaceController {
var payloadtest = {
let pt = PayloadTest(label: "test string init")
pt.label = "test"
return pt
}()
you can try to move that code in a function. (Swift 3.0 version)
class InterfaceController: WKInterfaceController {
var payloadtest = PayloadTest(label: "test string init")
fileprivate func test() {
payloadtest.label = "test" // tape this line in a function
}
}
Try this below code work with optional type -
class PayloadTest {
var label: String?
init(label:String) {
self.label = label
}
}

'Method' is ambiguous for type lookup in this context, Error in Alamofire

I am using Alamofire for network handling in swift and run into one weird error. It seems like we can't pass Method enum as parameter. [Error is on Method parameter]
private func apiRequest(method: Method, url: String, apiData: [String : AnyObject], completion:(finished: Bool, response: AnyObject?) ->Void) {
Alamofire.request(method, url, parameters: apiData).responseJSON{ response in
if let JSON = response.result.value {
completion(finished: true, response: JSON)
} else {
completion(finished: false, response:nil)
}
}
}
You have to specify the module from which to lookup object type.
Call Alamofire.Method
There is probably a name collision. To solve it, you can use the qualified name of the enum (including the module name):
private func apiRequest(method: Alamofire.Method, ...
I have also encountered this problem, because I have declared a number of the same name of the protocol:
protocol SomeProtocol {
static func someTypeMethod()
}
protocol SomeProtocol {
init(someParameter: Int)
}
protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
Had this error conflict when using "Moya" and when bridging a c framework, fixed it by implicitly adding Moya.Method module.
var method: Moya.Method {
switch self {
case .login: return .post
case .register: return .post
}
}
The type Method is declared in two imported modules. You have to specify the module from which to use the type. Use Alamofire.Method instead of Method.
Tip: If you are using the type often, you can create a type alias in your module (application):
typealias Method = Alamofire.Method
That way you will not need to prefix the type with Alamofire. any more.
While the answer to this did fix the build error; in my case, the file showing the warning was in two different frameworks so Xcode did not know where to look. This was not the intended behavior of our internal frameworks so I simply removed the copy I no longer wanted.
You may have a class declared in two or more places in your application. The error is saying that there is no conclusive way to use this class because there are a couple different places in the code it is declared.
Swift 4 and Alamofire 4.7
Replace HTTPMethod to Alamofire.HTTPMethod
I got this error because my database table name and model class name was same...Issue resolved by renaming model class name.
Change the enum type name to different &...
Use the $(inherited) flag, or
Remove the build settings from the target.
Target - > building settings- >ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES, Value type is Boolean, click on the other, change the value to $(inherited)
perform - pod update
Done
then try to run Your project , error will gone ! (I have tried in my project)
enum 'XYZ'ButtonType {
}
I managed to fix the problem by deleting the Alamofire folder in the pods project manually. Then, I do a "pod install" to reinstall the missing pods.
There are significantly less files in the Alamofire folder after doing this.

Calling a global function which has the same name as a member function Part 2

Directly related to Calling a global function which has the same name as a member function, I'm wondering how to call a global function in my own module.
I have a project named Parsing that is a Cocoa Framework. The name of my Xcode target is Parsing.
I have a function named failure at the framework level, and I'm attempting to call it from within a member of a type that has the same name.
I can obviously work around this by changing names; but I'm more curious about why the qualified name isn't working for me.
I get the compile error Use of unresolved identifier 'Parsing' in the following code:
import Foundation
//import Parsing;
func failure<T>() -> ParserOf<T> {
return ParserOf { inp in nil }
}
class ParserOf<T> {
let _parser:String -> (T, String)?;
private init(_ p:String -> (T, String)?) {
_parser = p;
}
func parse(s:String) -> (T, String)? {
return _parser(s);
}
class func failure() -> ParserOf<T> {
return Parsing.failure(); // compile error
}
}
If I uncomment the import Parsing line then I get a compiler error that says Cannot load underlying module for 'parsing' which looks a little odd because the casing of the name in the error message doesn't match the casing of the actual name.
I usually do that by importing the framework like you did in your commented code:
import Parsing
and then using the full name, including the namespace (module), again like you did:
Parsing.failure()
You should check that:
the entity you are trying to access to (in this case a function) is declared as public
the module name (Parsing) is correct
the function is actually a global function and not a class/struct method
target -> Build Settings -> Packaging -> Product Module Name is the actual model name you are trying to import
Last, if you change the name of the class func failure() method, does it work?

Array extension called from other module

Array extension methods are unavailable from other modules (for example the XCTest project)
For the sake of simplicity the code below does nothing but it can be used to reproduce the error
import Foundation
extension Array {
mutating func myMethod(toIndex: Int) -> Int! {
// no real code, it's here only to show the problem
return 0
}
}
Calling it from the same module works as expected but from a test class don't
class MyProjectTests: XCTestCase {
func testMoveObjectsFromIndexes1() {
var arr = ["000", "001", "002", "003"]
arr.myMethod(0)
}
}
I think this is correct because the method visibility is restricted to its own module, indeed I obtain the error '[String]' does not have a member named 'myMethod'
I've tried to define the extended method as public as shown below
extension Array {
public mutating func myMethod(toIndex: Int) -> Int! {
// no real code, it's here only to show the problem
return 0
}
}
But I get the compile error 'Extension of generic type 'Array<T>' from a different module cannot provide public declarations'
Until Beta 7 using public solved the problem but under XCode 6.1 (6A1046a) I obtain this error
How can I fix it to run under other modules/projects?
Swift does not allow public extensions currently so you will need to include that extension swift file in your project and put it part of the target.
While not entirely solving the original question, I did find that I could test extension methods in Swift 2.0 (Under XCode 7.0) by importing the module with the #testable directive:
#testable import MyGreatModule

Swift - Extra Argument in call

I am trying to call a function declared in ViewController class from DetailViewController class.
When trying to debug the 'Extra Argument in call" error pops up.
In ViewController class:
func setCity(item : Cities, index : Int)
{
citiesArray!.removeObjectAtIndex(index)
citiesArray!.insertObject(item, atIndex: index)
}
In detailViewController Class
// city of type Cities
ViewController.setCity(city ,5 ) //Error: "Extra argument in call"
This is pretty simple yet I'm baffled.
In some cases, "Extra argument in call" is given even if the call looks right, if the types of the arguments don't match that of the function declaration. From your question, it looks like you're trying to call an instance method as a class method, which I've found to be one of those cases. For example, this code gives the exact same error:
class Foo {
func name(a:Int, b: Int) -> String {
return ""
}
}
class Bar : Foo {
init() {
super.init()
Foo.name(1, b: 2)
}
}
You can solve this in your code by changing your declaration of setCity to be class func setCity(...) (mentioned in the comments); this will allow the ViewController.setCity call to work as expected, but I'm guessing that you want setCity to be an instance method since it appears to modify instance state. You probably want to get an instance to your ViewController class and use that to call the setCity method. Illustrated using the code example above, we can change Bar as such:
class Bar : Foo {
init() {
super.init()
let foo = Foo()
foo.name(1, b: 2)
}
}
Voila, no more error.
SwiftUI:
This error message "extra argument in call" is also shown, when all your code is correct, but the maximum number of views in a container is exceeded (in SwiftUI). The max = 10, so if you have some different TextViews, images and some Spacers() between them, you quickly can exceed this number.
I had this problem and solved it by "grouping" some of the views to a sub container "Group":
VStack {
Text("Congratulations")
.font(.largeTitle)
.fontWeight(.bold)
Spacer()
// This grouping solved the problem
Group {
Text("You mastered a maze with 6 rooms!")
Text("You found all the 3 hidden items")
}
Spacer()
// other views ...
}
In my case calling non-static function from static function caused this error. Changing function to static fixed the error.
This error will ensue, if there is a conflict between a class/struct method, and a global method with same name but different arguments. For instance, the following code will generate this error:
You might want to check if there is such conflict for your setCity method.
You have to call it like this:
ViewController.setCity(city, index: 5)
Swift has (as Objective-C) named parameters.
I have had this error when there is nothing at all wrong with the expression highlighted by the compiler and nothing wrong with the arguments specified, but there is an error on a completely different line somehow linked to the original one. For example: initialising object (a) with objects (b) and (c), themselves initialised with (d) and (e) respectively. The compiler says extra argument on (b), but in fact the error is a type mismatch between the type of (e) and the expected argument to (c).
So, basically, check the whole expression. If necessary, decompose it assigning the parts to temporary variables.
And wait for Apple to fix it.
This can also happen if you have more than 10 views for ViewBuilder arguments in SwiftUI
This is not the direct answer to this question but might help someone.
In my case problem was that class with same name existed in a different (Test) target.
While running Test target I got this error as a new argument was added to init method but was missing in the class in Test target.
Adding the same argument also to other init solved the issue.
In latest Swift 2.2, I had a similar error thrown which took me a while to sort out the silly mistake
class Cat {
var color: String
var age: Int
init (color: String, age: Int) {
self.color = color
self.age = age
}
convenience init (color: String) {
self.init(color: color, age: 1){ //Here is where the error was "Extra argument 'age' in call
}
}
}
var RedCat = Cat(color: "red")
print("RedCat is \(RedCat.color) and \(RedCat.age) year(s) old!")
The fix was rather simple, just removing the additional '{ }' after 'self.init(color: color, age: 1)' did the trick, i.e
convenience init (color: String) {
self.init(color: color, age: 1)
}
which ultimately gives the below output
"RedCat is red and 1 year(s) old!"