Type has no member? Swift

I have been struggling to get two swift documents to communicate. There is a line of code in my ViewController triggering a function in the model which in turn alters the contents of another ViewController. I seem to get this error a lot; but two swift documents in the same project should be able to refer to one another? I'll show the errors I get below. Any help would be greatly appreciated!

First viewcontroller
@objc func lookupDog(sender: UIButton){
        let dogName = sender.title(for: .normal)
        Dog.profileViewer(name:dogName) "'Dog' has no member 'profileViewer' "
        self.performSegue(withIdentifier: "lookupDogSegue", sender: self)

    }

Model:
import Foundation
struct Dog {
    var name: String
    var gender: String
    var speed: Int
    }

func profileViewer() -> String {
    dogNameLabel.text = String(dogName) "use of unresolved identifier 'dogName' "

Second ViewController where changes will show up:


import UIKit
class DogViewController: UIViewController { 
    @IBOutlet weak var dogNameLabel: UILabel!
    @IBOutlet weak var dogGenderLabel: UILabel!
    @IBOutlet weak var dogSpeedLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()



    

}
A line of code may mean different things depending on the context.

So, I cannot say something sure unless you show more context.

If I might write some comments by guessing the missing parts of your code...
Code Block
    Dog.profileViewer(name:dogName) //->"'Dog' has no member 'profileViewer' "


When you write {typeName}.{methodName}, the type typeName need to have the type method methodName.
(I hope you know the difference between type method and instance method.)

You have defined your type Dog as:
Code Block
struct Dog {
var name: String
var gender: String
var speed: Int
} //<- End of struct Dog.

There's no type methods in your Dog.


Code Block
func profileViewer() -> String {
  dogNameLabel.text = String(dogName) //-> "use of unresolved identifier 'dogName' "


Please show enough context. Where this profileViewer() is defined? What sort of lines exist till end of profileViewer()?


You may need to show something more for some people wanting to help you. Please show enough code, whole relevant parts to fix your issue.
I wasn't able to edit my question, but here is more of the code:

First viewController (kennel overview)
Code Block import Foundation
import UIKit
class HomeKennelViewController: UIViewController {
    @IBOutlet weak var buttonsStack: UIStackView!
    override func viewDidLoad() {
        super.viewDidLoad()
        let stackView  = UIStackView(frame: CGRect(x: 40, y: 100, width: 60, height: 100))
        stackView.backgroundColor = .red
        stackView.axis  = NSLayoutConstraint.Axis.vertical
        stackView.distribution  = UIStackView.Distribution.equalSpacing
        stackView.alignment = UIStackView.Alignment.center
        stackView.spacing   = 16.0
        for dog in myDogs {
            let button = UIButton()
            button.addTarget(self, action: #selector(self.lookupDog(sender:)), for: .touchUpInside)
            button.setTitleColor(.blue, for: UIControl.State.normal)
            button.setTitle(dog.name, for: UIControl.State.normal)
            // "Click"
            button.backgroundColor = .white
            stackView.addArrangedSubview(button)
         }
         stackView.translatesAutoresizingMaskIntoConstraints = false
         self.view.addSubview(stackView)
              //Constraints
         stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
         stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
        
    }
    @objc func lookupDog(sender: UIButton){
        let dogName = sender.title(for: .normal)
        Dog.profileViewer(name:dogName)
        self.performSegue(withIdentifier: "lookupDogSegue", sender: self)
    }
    @IBAction func unwindToHome(_ sender: UIButton) {
        self.performSegue(withIdentifier: "unwindToHome", sender: self)
    }
    
    }


Model
Code Block import Foundation
import UIKit
struct Dog {
    var name: String
    var gender: String
    var speed: Int
func profileViewer() -> String {
    dogNameLabel.text = String(dogName)
    }
}

My dogs
Code Block import Foundation
import UIKit
var myDogs = [
        Dog(name: "Saleks", gender: "Male", speed: 50),
        Dog(name: "Balto", gender: "Male", speed: 70),
        Dog(name: "Mila", gender: "Female", speed: 20),
        Dog(name: "Apollo", gender: "Male", speed: 100)
    ]



Second ViewController (dog profile)
Code Block import Foundation
import UIKit
class DogViewController: UIViewController {
    @IBOutlet weak var dogNameLabel: UILabel!
    @IBOutlet weak var dogGenderLabel: UILabel!
    @IBOutlet weak var dogSpeedLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}




I get unresolved identifier errors for dogName, dogNameLabel, although the dog.profileViewer error resolved when I moved that one curly brace.
Thanks for showing the more. It has cleared up some parts of your issue.
Code Block
struct Dog {
var name: String
var gender: String
var speed: Int
func profileViewer() -> String {
dogNameLabel.text = String(dogName) //<- `dogNameLabel` is not visible here, `dogName` is not visible here.
}
} //<- End of struct Dog.


In the struct Dog above, there are no properties of name dogNameLabel or dogName.
Without explicit declarations of such properties inside Dog, Swift compiler cannot do anything but showing error.

I guess, you want to show the DogViewController with the info of the Dog specified by the button pressed, OK?
If so, something like dogNameLabel.text = String(dogName) cannot be inside the struct Dog.

Remove the profileViewer() method from your struct Dog.

Your DogViewController should be something like this:
Code Block
import UIKit
class DogViewController: UIViewController {
@IBOutlet weak var dogNameLabel: UILabel!
@IBOutlet weak var dogGenderLabel: UILabel!
@IBOutlet weak var dogSpeedLabel: UILabel!
///Property to receive the `Dog` specified by the button.
var dogPassed: Dog?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
if let theDog = dogPassed {
dogNameLabel.text = theDog.name
dogGenderLabel.text = theDog.gender
dogSpeedLabel.text = "\(theDog.speed) mph"
}
}
}


You need to set the property dogPassed of the right instance of DogViewController just before the transition to the DogViewController.
The right place would be in the method prepare(for:sender:). You may need to add the method in your HomeKennelViewController.
Also, need to modify your lookupDog(sender:).

Code Block
@objc func lookupDog(sender: UIButton){
//The `title` of the button may be localized, this may not work when your app is internationalized.
let dogName = sender.title(for: .normal)
//`lookupDog` from `myDogs`
if let theDog = myDogs.first(where: {$0.name == dogName}) {
dogSelected = theDog
self.performSegue(withIdentifier: "lookupDogSegue", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "lookupDogSegue":
//Get the right instance of `DogViewController`
let dogVC = segue.destination as! DogViewController
//Set the property `dogPassed`
dogVC.dogPassed = dogSelected
default:
print("Unknown segue: \(segue.identifier ?? "nil")")
}
}


Your code may have many more issues to be fix, but at least, these changes above will fix the issues 'Dog' has no member 'profileViewer' and use of unresolved identifier 'dogName' .


But, in my opinion, if you do not understand why this sort of definition causes errors,
Code Block
struct Dog {
var name: String
var gender: String
var speed: Int
func profileViewer() -> String {
dogNameLabel.text = String(dogName) //<- `dogNameLabel` is not visible here, `dogName` is not visible here.
}
} //<- End of struct Dog.

it is too early to write an actual app. You should better take more and more time to study Swift language rather than app programming.


One more, you should better use UICollectionView instead of programming UIStackView by code.
Programming UIStackView is sort of a tough thing even for experienced iOS developers, you need plenty of work to utilize it, and will need more when you want some parts modified, for example, adding an image to each button.
Thanks, this is really helpful! I agree there are big gaps in my knowledge, I finished an online course and thought I would try a simple app to try to practise a bit. I will probably go back and do the course again. It helps to have some practical experience to attach the theory to
By the way, where did you first define "dogSelected"? The following lines are giving me an unresolved identifier error

dogSelected = theDog
dogVC.dogPassed = dogSelected

By the way, where did you first define "dogSelected"?

Sorry, I have missed to include the declaration of dogSelected.

You need it as a property of HomeKennelViewController:
Code Block
class HomeKennelViewController: UIViewController {
//...
    private var dogSelected: Dog? //<- Please add this line into your `HomeKennelViewController`.
//...
}


It works! This was a really big part of starting off the app. Thanks for your help!!
Type has no member? Swift
 
 
Q