1

I am trying to output text to viewDidLoad using a delegate (for test), however nothing happens

protocol LoaderDelegate: class {
  func LoadData(_ controller: SearchPhotosViewController)
}

class LoaderData: LoaderDelegate {
  func LoadData() {
    print("Hello from LoaderData")
  }
}

class SearchPhotosViewController: UICollectionViewController {

  // MARK: - Properties
  weak var delegate: LoaderDelegate?

  override func viewDidLoad() {
    super.viewDidLoad()
    print("Hello from viewDidLoad")
    delegate?.LoadData()
  }

}
Coffee inTime
  • 231
  • 1
  • 8
  • Someone needs to create a strongly held instance of `LoaderData` and assign that to `delegate` in `SearchPhotosViewController`. Right now, it is just `nil` and therefore does nothing. This is usually done by the presenting VC. – vacawama Sep 05 '19 at 16:59
  • delegate is nil. You need some class to explicitly handle the `delegate`, check this: https://stackoverflow.com/a/56719732/8869493 – Gustavo Vollbrecht Sep 05 '19 at 16:59

1 Answers1

1

First, you should delete the parameter from LoaderDelegate.LoadData, because the current code does not compile (LoaderData.LoadData's signature does not match that of the protocol).

protocol LoaderDelegate: class {
  func LoadData()
}

You have set up the delegate correctly, but you have not set the delegate a value. Usually, the delegate pattern is used to "pass data backward". In the view controller that presents SearchPhotosViewController (or whatever thing that is using SearchPhotosViewController), you set the delegate to an instance of LoaderData:

searchPhotosViewController.delegate = LoaderData()

And now when the search photos view is loaded, you will see "Hello from LoaderData" in the logs.

If SearchPhotosViewController is actually a root VC, then the delegate pattern is probably not suitable here. But you can still make it print "Hello from LoaderData" by setting delegate in viewDidLoad (but that's kind of pointless):

override func viewDidLoad() {
    super.viewDidLoad()
    print("Hello from viewDidLoad")
    delegate = LoaderData()
    delegate?.LoadData()
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • I did not quite understand where I should add "searchPhotosViewController.delegate = LoaderData()"? – Coffee inTime Sep 05 '19 at 17:09
  • @CoffeeinTime What view controller presents `SearchPhotosViewController`? Put that line right before `SearchPhotosViewController` is presented. – Sweeper Sep 05 '19 at 17:11
  • I do not understand. How can I place this code somewhere other than the LoaderData class or the SearchPhotosViewController class, this will cause an error. – Coffee inTime Sep 05 '19 at 17:20
  • @CoffeeinTime do you only have those two classes in your project? If so, then you should not use the delegate pattern. Read my last paragraph. – Sweeper Sep 05 '19 at 17:22
  • I'm just trying to understand how they work. In the future I want to use it to upload photos. Aren't delegates created for such purposes? To transfer part of the responsibilities to another class. – Coffee inTime Sep 05 '19 at 17:24
  • @CoffeeinTime unfortunately, no. As I said in my answer, delegates are used to pass data back to another object (usually the owner of `self`). – Sweeper Sep 05 '19 at 17:28
  • Maybe you can tell me ... I want to create a bootloader class that will upload photos to me and send them to the collection. (I'm trying to create an application in which the “tab bar controller” leads to several collections, the difference is only in the category of photos. And to avoid duplication of code, I was going to do it all in one place by creating a convenient class for loading.) How can I to implement a similar class that could change the collection I need and be able to upload photos? – Coffee inTime Sep 05 '19 at 17:49