I linked a TableViewController from storyboard to a class. In a different class I implemented some network request functionality and I would like, as soon as I receive responses, update data in my TableViewController-Class. Is there any way I can address this specific instance of class that contains the table etc.?
One way to solve this problem is to access a field of the NetworkClass by implementing a Timer in the TVC-Class, it works, but is probably not the best way to solve the problem.
Is there a way to get e.g. an id of a class and a function that lets me create an object with this id, so that I can simply access field and methods of it
Thanks in advance
Julian
Related
I am using a custom AuthAttribute to determine whether a user can access a controller and/or actions. The problem is I have to duplicate information and EFx connections in the attribute that already exist on the class that is being adorned.
My question is whether there is a way to access the fields on the adorned class from the custom AuthAttribute? I am trying to avoid having to re-architect the software in a way that would provide a single point of access since that would open up a different can of worms.
I believe I have found an answer that works. I welcome all comments on this solution.
Rather than have the attribute gain access to the properties and fields on the controller it adorns you can share values between them in a thread-safe way through the common HttpContext object. So if you are being extreme like I am and are trying to cut down on duplicate calls to your database in both the authattribute and the adorned controller action then pass the results forward. What that means is the authattribute will be called first and you can stash the retrieved values in the "Items" collection off the HttpContext object passed into the AuthorizeCore(..) method. You can then retrieve the same value in a THREAD-SAFE way through the HttpContext object in the controller.
example to save value within the AuthorizeCore(..) override of the AuthAttribute:
httpContext.Items.Add("fester", "bester");
example to retrieve value inside the subsequent call to the Controller/Action:
this.HttpContext.ApplicationInstance.Context.Items["fester"];
I have to warn you this is only a possible implementation that appears to work in simple testing. Personally it feels like a hack and there has to be a better way. I would also state this is in pursuit of a dubious performance benefit. It should cut down on the number of database and/or network calls by cache'ing retrieved data in the HttpContext so you don't have to repeat the calls in both the authattribute and the adorned Controller/Action. If you don't have a web site that gets a huge volume of calls then I would warn you against this.
I hope someone recommends something better on this page. I will keep an eye on how this works on my web site and let y'all know if it behaves and is truly thread-safe.
In my AppDelegate, I download some data from a JSON feed. I am downloading a now/next/later schedule for a few channels. I have three different view controllers for each now, next and later. In each view controller, a user can add/remove the channels so when that happens, the newly added channel data has to be downloaded again.
Since the data is downloaded in the AppDelegate and stored there, how would I pass it to the three view controllers? Should I implement three separate delegates? Keep in mind that when adding a new channel, its data has to be downloaded again (which I am doing outside the AppDelegate now).
Any help please?
Thanks
This is basically a matter of style and your approach isn't invalid as such.
I'd do it another way, though - the AppDelegate is not meant to be used as a workhorse and having several AppDelegates at the same time is simply impossible.
Here are some thoughts about how this could be done (though it's of course not the only proper way):
First, I'd employ Core Data or some other sort of storage which is available from anywhere within your app.
Then maybe I'd introduce some sort of "data controller" class (maybe a singleton). This class should handle both download of data and the distribution of that data to your viewcontrollers as requested.
By having one central controller for that purpose, you'd ensure that data gets downloaded only once because the controller knows exactly which data is already in stock.
Your viewcontrollers would neither be responsible for managing downloads anymore nor would they access the data on disk by themselves. They'd just make a request to your data controller and get a callback when the requested data is available - no matter if it was on disk already or has been downloaded for the occasion.
This keeps your VCs slim and focused and reduces the pain of making changes to your interface.
Toastor's answer is correct and as he says, there are several ways to do this. One is to call a data access class and change the values OR listen for changes on the values. For the later, the Key-Value Observing Programming Guide says the following:
KVO is particularly useful for communication between model and
controller layers in an application.
A controller object typically observes properties of model
objects, and a view object observes properties of model objects
through a controller.
In addition, however, a model object may observe other model
objects (usually to determine when a dependent value changes) or even
itself (again to determine when a dependent value changes).
Another is to make the dependency explicit, maybe passing a data access class saved in your app delegate. See Object-oriented design question, iPhone.
The ViewModel can notify the View about property change by raising property change event. If the underlying data (for example, a Plain class which do not implement IPropertyChange) changes, how can ViewModel get notified?
If the underlying data (for example, a Plain class which do not implement IPropertyChange) changes, how can ViewModel get notified?
It cannot, there has to be a mechanism in place to do the notification. The most likely cause is a POCO that is used in one region (or module) of the application is also being used in another, i.e. a loosely coupled master-detail situation. If you are "sharing" the same instance of a POCO like this, then it is unlikely that you haven't also implemented change notification in it. If you have implemented change notification, then a change in one module of the application will automatically be visible to the other module (they are both looking at the same object) and anything that watches for that change notification (like a binding subsystem) will do its thing and pick up the changes.
If you have two separate instances of the same data and one gets updated, the other will not know about it. This also happens when your VM requests data via the Model, and the Model retrieves the data from a disconnected data source like a database or a web service. You don't know when the underlying data has been changed, once again you need to implement a change notification system. You can also take another aproach with this - let the user change the data, then do a fresh grab of the data before saving the user's changes, and if the underlying data has changed while the user was working then you can notify the user and take the appropriate action (or let the user choose the appropriate thing to do).
Does this answer your question? Or do you care to elaborate more about what you are wanting to know?
I have noticed that with iPhone programming you kind of need to retrieve your data from within the ViewController because of the way the data is retrieved.
e.g.: ViewDidLoad is called. You start retrieving the data and then when its finished a message is sent to your viewcontroller e.g. requestFinished and this is where you configure/refresh your UI.
The problem that I have with this approach is that I have a bunch of web service code and XML building and parsing all in my view controller.
Does anyone know if this is the correct approach or is there a better way to do this.
In .NET I would have classes specifically for retrieving data from webservices and I would simply call the web service to fetch the data and I could use the same web service at various places inside my app.
There is no reason to do that different in Objective-C/Cocoa. You should create a class that handles the web service and notifies the view controller when data is available.
No, it absolutely isn't the correct approach. The key to this is the MVC paradigm, - model, view, controller - your data classes are perfectly suited to being the M = model so put all your data handling code inside a dedicated model class.
Because the url handling is hopefully asynchronous, your model will still need to inform your view controller when various events have taken place. You have a couple of choices here but the most appropriate is probably to use a delegate pattern so that the model can basically initiate a call back to the view controller when it has data that needs displaying etc.
(The other approach would be to use notifications which is less tightly coupled, and perfectly viable in this scenario, but delegates would be more appropriate).
Well you could create a parse that will parse your XML in a seprate class, and even your http request can be in a seprate class.
There is no need to do every thing in the the on viewcontroller.
Just be sure to create delegate or use the notification center if you are using threads. Set the delegate on either the request or parse to nil if the view controller get unloaded.
I have a UINavigation based application that gathers information on various screens and eventually makes a web service request using all the parameters collected.
So I have A,B,C,D view controllers. A gets the name & number, it then pushes B onto the screen with some basic info ETC ETC until it gets to D where I actually fire off the web service.
The poor method I have been using is to duplicate class fields from A onwards. Meaning if I collect name, and number, then I make those the fields of B, which then adds a few fields, and then C has class fields of both A & B which seems like a poor programing practice.
What can I do to get access to class A's fields in class D? I have gotten certain ideas but not sure how valid they are.
1). Use NSNotification (Is this overkill?) If so how do I pass fields?
2). DO I just retain all 5 view controllers and just get the info at the end? (seems very inefficient)
3). Should I just instantiate a NSObject class called Payload and just set its fields every time I bounce from one view controller to the next? (If so do I create it in class A? What if user navigates back to class A, will it then get reset ETC ETC)
As you can tell I have tried to find a solution and I am fairly new to it. Some detailed suggestions would be highly appreciated.
Depending on situation, there are several ways that seem appropriate.
Get to know MVC Design Pattern
Classes are not data storage. If class doesn't have interface to interact with represented object, excluding accessors, you're doing it wrong.
3.
I have a UINavigation based
application that gathers information
on various screens and eventually
makes a web service request using all
the parameters collected.
So, your web request is based on parameters gathered from various views. Why not create an
model of said request? MyRequest or something like that :) Or several more specific variants, sharing common parent class? This generator holds logic, gathers data and parameters as you advance trough views and provides NSUrlRequest at the end to WebView or maybe different kind of object which is NSURLRequest delegate and conforms to UITableViewDataSource/Delegate protocols to be used to display downloaded data.
I'd go for 3) and yes you should create it at the beginning (Class A).
But maybe user go back to Class A to change the value on purpose so resetting it doesn't seem to be a problem.
Why not use a singleton object and pass it around?
The advantages of this method are:
There's only one instance whose
reference is being passed around
between viewcontrollers
Changes you
make are reflected the next time you
access this object from another view
controller
And to answer one of your questions, NSNotification allows us to pass objects along....
Here's a good example on singleton objects in iOS by Matt Galloway. It's the one I always refer to:
http://www.galloway.me.uk/tutorials/singleton-classes/