0

I am currently working on an app using Xcode/swift 4 where I need a view (lets call it loggerView), which is not the main view, to be able to take data from the main view (or other views) in a manner that allows said data to be shown whenever loggerView is displayed (using a text view in this case). I understand that I can use a segue to present/push this data (text log msg) to the loggerView upon transition to the loggerView, but there are a couple of probs with that:

  1. When using segues the data can only be pushed all at once through segue prepare when transitioning and not piecemeal, which I need.

  2. When the user exits loggerView back to the primary (or other) view all the data in the loggerView is lost.

Because of (2) I would need the primary view to store all logging data related to the information I want displayed in the loggerView such that upon segueing to loggerView all the data can be provided each time. This is not ideal because I don't want the primary view to store this, I'm looking for a way to fire this data to loggerView in the same way a delegate might work back from loggerView->primaryView where it can be called at any time whilst loggerView is being shown.

I think the main prob here is that I am working with a parent->child view situ (using navigation controller) where every time we transition back from child to parent the child view (loggerView in this case) is removed from memory and so all data pertaining to loggerView is deleted, thus the need to segue everything each time loggerView is opened.

Is there a way to make more than one view permanent (memory wise) and then send data between primaryView and this other view on an ad-hoc basis rather like the way delegates might work in reverse (loggerView->primaryView)?

Matt74
  • 31
  • 1
  • 4
  • I don’t understand your objection to storing the child’s data back in the parent. That is normal and standard. If you insist on being different, why not keep it in UserDefaults? – matt Oct 12 '18 at 02:36
  • I think it comes down to the architectural overview of the project and perhaps I need to change mindset here. If the child in this case is simply a ViewController whose job is solely to display log messages that occur from any other part of the app then perhaps it is not useful to think of the child view in this case as the storer of said data, but rather to create a separate storage container where the logs are passed to and then, when the parent view switches to the child view have it pass this separate storage container to the child as part of the segue? – Matt74 Oct 17 '18 at 14:20
  • That is the usual thing. — Basically, think of view controllers as nimble; their purpose is to come and go, as the views that they control come and go. So if you have data that needs to persist, it needs to be passed around, or put in a more persistent place. Model, view, controller. Three different things. Do not try to turn the controller into the model! – matt Oct 17 '18 at 14:22
  • Summarized the discussion into an actual answer. – matt Oct 17 '18 at 14:32

1 Answers1

0

Summarizing our discussion in the comments:

Your objection to storing the child's data back in the parent is probably misplaced. Such behavior is normal and standard. If you insist on being different, you could keep the data in UserDefaults, as being both global and persistent, but that is usually regarded as a crutch.

In effect, your desire to persist the view controller merely in order to persist some data that it has fetched from the user is just wrong. Suppose a dialog pops up asking you to enter a name. You enter the name and tap OK, and the dialog vanishes. You do not believe that the dialog should persist behind the scenes just to hold the name, do you? No — what persists is the name. The dialog, and all the mechanism that enabled it to appear, was merely temporary in order to manage the user interface.

It might help to repeat "model view controller" (MVC) to yourself over and over as you work. The data collected from the user is model. If you want it to persist, persist it. But do not persist a view controller merely in order to do that. Think of view controllers as nimble; their purpose is to come and go, as the views that they control come and go. If you have data that needs to persist, it needs to be passed around, or put in a more persistent place. Model, view, controller. Three different things. Do not try to turn the controller into the model!

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Fair enough. Thanks for summarizing. – Matt74 Oct 17 '18 at 22:13
  • Sorry, in re-reading your comment I realize that you are of the impression that in this case the data is from the user. There is no user involvement here at all. Simply put there is some "engine" running on some thread that spits out log messages every now and then. These log messages will now get pushed to some main data storage and whenever the child view is opened it will display them all. However... there still appears to be a limitation in that whilst the child view is open it won't see any additional logs that are pushed without first closing the view and opening it again? – Matt74 Oct 17 '18 at 22:36
  • There is no _inherent_ limitation. Again, it's a matter of communication between view controllers. The engine needs to send off messages so this child view controller can receive them if it is in existence. And again, it would be wrong to make the child view controller persist merely in order to do that. – matt Oct 17 '18 at 22:45
  • So I think it is these "messages" you mentioned that would perhaps address my need here? I don't know a way of getting information to the child view whilst it is currently open other than at the point of its creation. With regards to it being wrong, then its perhaps a matter of architecture? In my case the main view controller is filled with a bunch of control things and has no "room" for a logging window. When I kick the engine off I need to move over to the logging (child view) and watch the progress of the engine. – Matt74 Oct 20 '18 at 16:32
  • "I don't know a way of getting information to the child view whilst it is currently open other than at the point of its creation." Then perhaps you need to ask a new question about that. There are lots of ways to do it. In other words, if you are trying to program in a bad way merely because you don't understand how to pass data / messages between view controllers, you need to stop and learn how to pass data / messages between view controllers so that you can program the right way. Meanwhile, I believe I've answered _this_ question sufficiently. – matt Oct 20 '18 at 16:34
  • I can ask a new question, but honestly that is what I thought I was asking, but maybe I was too wordy. I understand and have read about Segue's and Delegates. Segue's going from main viewcontroller->child view and delegates going in reverse. Delegates allow exactly the functionality I am looking for except in my searching I find only how delegates go from the child view back to the main view and not the other direction. I appreciate the time you have taken to write responses, but I am no better off. We can close this out for now and I will do more research. – Matt74 Oct 21 '18 at 02:24