Passing user data through view controllers [duplicate] - ios

This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 8 years ago.
I'm making a basic app that allows user login.
I wanted to know the general practice of passing user data between view controllers. After a user is authenticated, is it generally acceptable to pass their data through view controllers?
For example, user A is logged in and authenticated. User A wants to "create a event", to be able to save that the user is hosting this event, I would have to store the users ID on the event as host and I would need access to his UID. Would you save the users ID after login and keep passing it in to every view?
I am using Firebase as my backend if that helps.

You should learn about a thing called "segues". It is the primary mechanism to transition between views in ios.
Here's a good tutorial(no personal affiliation, btw)
http://makeapppie.com/2014/07/01/swift-swift-using-segues-and-delegates-in-navigation-controllers-part-1-the-template/
haven't used firebase, but if you are passing event data from scratch by yourself you would do 4 things.
would declare the var in the target controller.
in the source controller you would fire off the function: performSegueWithIdentifier at the appropriate time.
that takes you to your prepareForSegue function (the contents of this func is like the last point of no return before you transition to the new controller). inside, create a var where the name of the type is the name of the target view controller.
use dot operators to access the variable you want to pass to and give it the appropriate value

Yes, best practice is to pass data between your view controllers as needed. You usually hook into the prepareForSegue method to accomplish that. Don't fall into the all-too-common practice of using (abusing, rather) your app delegate to maintain a bunch of global state. That is bad news. It is cleaner and more modular, in my view, to pass data down the view controller hierarchy, rather than having your view controllers reach back "up" and grabbing what they need.

Related

MVC in Swift 4 - Model's interactions with Controller

I'm developing a mobile application in Swift 4, that needs to interact with an external device using Bluetooth LE connection.
Currently i'm using the Model-View-Controller pattern to implement the structure of the app, but i need a clarification about.
When i receive data from the bluetooth adapter, i store it inside the model. The Model talks to the Controller "posting" the changes using the notification center.
On the other side, the Controller (the owner of the model) write the modification back to the Model simply setting the property of it.
The problem is that, sometimes, i do not have the Controller ready(instantiated), so i can loose Model's update (in that moment i'm not ready to "observe" the updates from the Model).
The only way that i found to workaround this issue is to:
In the Controller viewDidLoad read the status of the Model using "getters" of the Model properties.
Register the Controller to observe the future Model updates.
This now is working fine, but what i would like to understand is if this is the correct behaviour of communication between a Model and a Controller.
You can create a variable for that model in the view controller.
For the variable, implement didSet and perform the operations that you want to perform in the view controller. You do not need to post the changes using notification center.
In viewDidLoad, you can get the data first time from the bluetooth adapter.
After that whenever you receive the updated data from the bluetooth adapter, update the model only. It will do the rest of the things for you.

Keeping a WKWebView and it's UIViewController in the background running and accessible from multiple ViewControllers

Background: In order to make web requests to an API endpoint, I need to scrape a website and retrieve a token every 25-30 seconds. I'm doing this with a WKWebView and injecting some custom JavaScript using WKUserScript to retrieve AJAX response headers containing the token. Please focus on the question specifically and not on this background information - I'm attempting this entirely for my own educational purposes.
Goal
I will have different 'model' classes, or even just other UIViewControllers, that may need to call the shared UIViewController to retrieve this token to make an authenticated request.
Maybe I might abstract this into one "Sdk" class. Regardless, this 'model' SDK class could be instantiated and used by any other ViewController.
More info
I would like to be able to call the UIViewController of the WKWebView and retrieve some data. Unless I re-create it every 25 seconds, I need to run it in the background or share it. I would like to be able to run a UIViewController 'in the background' and receive some information from it once WKWebView has done it's thing.
I know there are multiple ways of communicating with another ViewController including delegation and segueing. However, I'm not sure that these help me keep the view containing the WKWebView existing in the background so I can call it's ViewController and have it re-perform the scrape. Delegation may work for normal code, but what about one that must have the view existing? Would I have to re-create this WKWebView dynamically each time a different model, or view controller, were to try and get this token?
One post suggests utilising ContainerViewControllers. From this, I gather that in the 'master' ViewController (the one containing the other ones), I could place the hidden WKWebView to do it's thing and communicate to the child view controllers that way via delegation.
Another post suggests using AppDelegate and making it a shared service. I'm completely against using a Singleton as it is widely considered an anti-pattern. There must be another way, even if a little more complex, that helps me do what I want without resorting to this 'cheat'.
This post talks about communicating between multiple ViewControllers, but I can't figure out how this would be useful when something needs to stay running and executing things.
How about any other ways to do this? Run something in a background thread with a strong pointer so it doesn't get discarded? I'm using Xcode 9.2, Swift 4, and iOS 11. As I'm very new to iOS programming, any small code examples on this would be appreciated.
Unfortunately, WKWebView must be in the view hierarchy to use it. You must have added it as a sub view of an on-screen view controller.
This was fine for me. I added this off-screen so it was not visible. Hidden attribute might have worked as well. Either way you must call addSubview with it to make it work.
There are some other questions and answers here which verify this.
Here is a way if you don't wish to use a singleton.
1- In the DidFinishlaunchingWithOptions, Make a timer that runs in the background and call a method inside the app delegate Called FetchNewToken.
2- In FetchNewToken, make the call needed and retrieve the new token (you can use alamofire or any 3rd library to make the call easier for you).
Up on successfully retrieving the token, save it in NSUserDefaults under the name upToDateToken
You can access this token anywhere from the application using NSUserDefaults and it will always be up to date.

pass object back or pull from firebase

I have a situation where I am creating and saving objects to firebase. These can then be edited, and viewed in multiple places, or in multiple viewControllers.
I cannot decide if it is best to continually pass the whole object back and forth, so that when it is changed each view will get the most recent version.
Or, to only pass a little reference to it, or some way that each view knows which one it is dealing with, then have each view just download the most recent version from Firebase...
So central location for up/down from firebase, and pass the object locally around the App.
Or pass some reference around, and have each View up/down/observe with Firebase to stay up to date.
Does this make sense? Sorry for a very conceptual question and thank you for any input!

Saving User Information with Parse on different View Controllers

I was wondering if anybody knows how to save data to the same User on Parse by entering information on different ViewControllers? I would like for the user to be able to Sign-Up on 1 View Controller, then answer some questions on the next ViewController, and having all the information be saved under that user? Thanks.
There are many ways to do that, depends on what approach of saving information you are going with. If you just want to pass values from the first view controller to the second one, then it is very simple.
One example of how to do it is here:
http://www.infragistics.com/community/blogs/torrey-betts/archive/2014/05/29/passing-data-between-view-controllers-ios-obj-c.aspx
UPDATE:
Keep in mind that with that approach you won't have any saved data... In order to save it properly, I would suggest to use SQLite or some database to manage users data.

How do I record the request used to call an Action

I'm working on an existing, fairly labyrinthine, intranet that I do not have authority to re-factor.
The back button is disabled in this application so back navigation is through code.
This was OK when we had simple workflows e.g. Index->Details->Edit
However, the workflows are now becoming longer and crossing between different Controller domains so managing back navigation is becoming more complex.
I'm thinking that if I have an object that records each step forwards then I can simply replay it backwards. This should accommodate any edits made downstream in the workflow.
To do this I need to record the URL or at least the Action, Controller and parameters sent to each Action into the object.
My questions are:
When an action/method is called is there a object that contains the call so that I can record it?
If not, can I find out which Action and Controller I am currently in using code rather than having to explicitly set these into the recording object.
I'm using ASP.MVC 5

Resources