So I'm using multiple delegates to pass trough data, but I don't know if it's the right way. I only want to maintain 1 main object to be sure that if a user exists/closes the app the edit data is saved when not in the VC1. By using the delegates now I'm sure the data is in the main object and all is well. Could you guys send me in the right direction and tell me if this is the way to go? Thanks in advance!
VC1:
Main object, holds all data that needs to be saved
Delegate for VC2
VC2:
Specific object overview from VC1
Delegate for VC3
Delegate function called -> PassDataToVC1(editsForSpecificObject)
VC3:
Edit's data from specific object. -> Gives
Delegate function called -> PassDataToVC2(edits)
Maybe even a 4th VC depending what I'm going to do.
CodePudding user response:
What you're doing is basically correct for the architecture you have chosen:
If you have a rule that only VC1 knows the full data and can save it, then you need to pass changes in the data back to VC1.
If you have a rule that the way to pass the data back to VC1 is to use a protocol-and-delegate architecture, then you have to make VC1 the delegate for your protocol(s). There is nothing wrong with a single object (your VC1) being extended to adopt multiple protocols; that, indeed, is a standard Swift pattern.
However, I would argue that the reason this feels ugly to you is that those are not very good rules. I'll address them in reverse order:
Why delegation? In modern Swift, there are cleaner ways to pass data around. Modern app architectures are typically reactive, meaning that a handler of data is a publisher of the changes in that data, and the central store of the data subscribes to those publishers. Thus the data store can hear directly of any changes without the view controllers having to send those changes to anyone in particular.
Why a view controller? This is arguably the weakest point in your architecture. What business is it of a view controller to know anything about the data store and the mechanism for saving it? You should have a separate data store object retained by some securely persistent object such as the app delegate. This object stores and gatekeeps the data, and knows (or has a service helper who knows) how to persist it. You can use dependency injection to hand a reference to this object to every view controller — which also has the added benefit of making your code eminently testable. Even better, if you accompany this idea with the use of reactiveness that I outlined in the previous paragraph, you will have a clean "touch-free" architecture that just works, where every object does its own job and no other.