I am creating a plist controller class that dose things like takes my plist saves it to the document root saves all the values in my plist to variables that will be used for checking my connection responses.
also I do things like saving new values when needed.
the issue I am having however is that I want to access this one class from many classes but if I initialize it in one class and then another I am creating two objects am I not?
so my question is whats the best way for handling a class that has to be accessed from a couple of different classes?
Where are you using these other classes? If they are view controllers then creating an instance in each is perfectly fine.
If they are objects created within the same view controller, try having your objects take your object as function input. That way you can create one instance of that object and share it with all your other objects. Here is an example:
-(void)myFunction:(plistControlClass *)myPlistController{
}
Related
Suppose I have three interface controllers which are all linked by push segues.
InterfaceController1 -pushSegue-> InterfaceController2 -pushSegue-> InterfaceController3
InterfaceController1 has table which will house the data from the class below.
So, suppose I have class:
class manageData {
var data1:String?
var data2:String?
}
and this class is supposed to hold the data from InterfaceController2 and InterfaceController3.
So InterfaceController1 creates a manageData object and passes it to InterfaceController2 using the contextForSegueWIthIdentifier method. InterfaceController2 then adds to its data to the manageData object and passes it along to InterfaceController3 using the contextForSegueWIthIdentifier method as well.
Now my question is, once InterfaceController3 adds its data to the object, how do I pass that complete object back to InterfaceController1 with the data filled in so InterfaceController1 can add the data to the table? Hopefully I've made this clear enough. I don't have any actual code to represent this because I have no idea how to implement it yet.
So the way I solved this issue was to create a singleton class which held all my data throughout the different controllers. Then when I reach the last controller and send my data to the singleton, I pop back to the root controller.
When I'm back in the root controller, in the awake method, I call a function I made called loadTableData() which automatically takes information from the singleton when it awakes and loads it in the table. Seems to work perfectly for now but I don't know any potential issues that can come up with this method.
This is more of a generalized question as I have yet to write the code for the question I am asking. Before I get started writing the code I wanted to make sure I am on the right track and possibly getting suggestions for better ways to do what I want to do. Basically right now I have a core data model setup in a way that I think is correct for what I am trying to do and just need some guidance on a very specific part of the code but want to make sure overall I created it correctly.
The first part to the question is more of a clarification on how relationships work in core data. Right now I have 5 entities and to make sure I have the correct idea on how it works I will use a few examples to make sure I am on the right track.
So lets save I have an entity I called name. Within that Name entity that contains only a name attribute. Next I have an entity that has classes, that each have a boolean of true or false to determine which class it is. These 2 are related in a inverse relationship of Name entity having a to one relationship and the Classes having a to many relationship because multiple names can have multiple classes but each name can only have 1 class. If I am right on this one that means I full understand core data relationships!
Now the second part of the question is related to the booleans in the class. I have the Class entity which is like I said a boolean containing a true false set as default to false. When the user selects one of the class buttons before presenting the popover where they actually give the name of the class selected it saves the boolean to true then passes that data over to the popover Name view controller. I am very unsure as to how to do this as it isn't a widely asked question on here nor have I been able to find any info through researching. I am one of those people who needs to actually learn by clear examples....any help with this would be appreciated! Sorry I don't have any example code for this.
The first part seems correct. The ManagedObject of your Class CoreDataObject should have an NSSet property which will contain the names (as the Class can have multiple names)
For the second part, Core Data uses objects. When you 'get' the data from Core Data it will be a (probably extended) NSManagedObject (named Class in our case). You can send this object as a parameter just as you would do with any other object and use it as you would use any other object :-). For example looping over de NSSet Names
func iterateOverNames(someClass: Class) {
for name: Name in someClass.names {
// do stuff
}
}
You can check these links for more information:
https://realm.io/news/jesse-squires-core-data-swift/
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/index.html
Being able to share data between multiple view controllers and doing that in a way that makes use of recommended patterns such as MVC seems to be essential to create good apps, but my problem is that these things aren't clear at all for me.
I am conscient that this question is really dense, but for things to be clear I think you really need to understand the whole thing.
First of all we need to be sure of what Model, View and Controller are doing, here is how I would describe them, please tell me if I'm right about that:
Model : a class that's responsible for managing data, and only that (for example, a class that will go on the web to retrieve information, such as weather forecast).
View : a view is an object that's displayed to the user, who can often interact with it, that's the objects that you can drag and drop in Interface Builder (for example a button) and you might also create one from scratch, or custom an already existing one by subclassing it.
Controller : a controller is responsible for managing a view and its subviews, it receives events (such as viewDidLoad, or even when the user taps a button) and can react to it, for example, it might change the text of a label.
Now about the way they are interacting between each other, I'd say that the controller is between the view and the model, it's managing the view and might ask for data to the model. In addition to receiving events from the view, it might also receive events from the model, for example, if the controller asks to the model for a specific data on the web (let's say if it asks weather for a specific city) the data won't be available immediately, instead, the model will notify the controller so that it can update the view with the data it received. Am I right?
One of the first thing I'm wondering is if an object could be considered as a model if it isn't here to retrieve data, but to do other things that are simply not related to the view, for example, could an object that's responsible for communicating and managing a bluetooth accessory considered as a model ? Could an object that sends data to a cloud considered as a model ? And what about a Tic Tac Toe AI ?
Then, singleton instances, I often heard of them when an app had to share data between multiple views, but first of all, I never really understood why it was necessary to use them in this case ?
Then, here is a singleton that I found in an article of the We Heart Swift website.
class Singleton {
struct Static {
static let instance = Singleton()
}
class var sharedInstance: Singleton {
return Static.instance
}
}
Singleton.sharedInstance
The problem if that I have had difficulties to find anywhere more details about why it's written in this way, and most of all, can a singleton have an initializer that takes arguments? How to add properties and methods to a singleton like this one? What are exactly the Static structure and the sharedInstance?
My last question is about why, technically, does a singleton makes it possible to get an access to things we have defined somewhere else? What I mean is that if I create an instance of let's say, a Dog class in my AppDelegate, and if I want to access to this specific instance in a view controller, then it wouldn't be possible, so how does singleton makes that possible under the hood?
EDIT : Oh, and, is the use of singletons recommended by Apple?
Thank you.
It has to do with the static in the struct. Static is essentially a class variable that persists for every instance of that class, so when you make the shared instance static, every time you access it, even from another instance of Singleton.instance it is the same variable because it is static. It persists amongst instances. However, Swift does not support class variables yet, so when it does, that should quickly replace the Struct syntax that is common of singletons. It is very similar to static variables in java.
For example:
class Singleton {
var someVar = 0
struct Static {
static let instance = Singleton()
}
}
to create a singleton with a variable and the following to access it:
let foo = Singleton.Static.instance
foo.someVar = 11
let bar = Singleton.Static.instance
println(bar.someVar) // Prints 11
As you can see, bar.someVar was never set, and that is because the variable for the shared instance was set, so it prints 11.
I have splitted my application into two main areas.
Part(A)
PartStashContainer(B)
The content of A should be set based on what user wants.
So basically i can have 1..N classes which could be used in Class URI of Part in application model.
I don't know if i should replace the whole Part(A) with new dynamically created Part(C) which has content i want, or i should somehow to modify the existing Part (call setContributionURI, or setObject methods on Part object?).
It does make more sense to me to modify the existing Part, because it is defined in Application model and therefore already describing the location where the content should be.
Possible solutions:
Modify the Part object so it "reload" its content based on new setup (But how? Can setContributionURI or setObject methods help?)
Remove the old Part and add dynamically on same place in Application model the new Part (using EModelService and EPartService).
other solution??
If you want to reuse the Part then do something like:
MPart part = find or inject your part
MyClass myClass = (MyClass)part.getObject();
... call a method of MyClass to change the contents
MyClass is the class you specify for the object in the application model. You should add a method to that to let you change the contents.
Don't try to call setObject, this is really only for use by Eclipse. I don't think setContributionURI would do anything after the part is created (but I am not sure).
If you want to use different classes for the different data then you really should use different Parts.
How can I eliminate to write $object = new Application_Model_Database() in every controller?
For example for an article controller, I have to type $articles = new Application_Model_Articles() for every controller. Should I put it under viewer controller, action helpers, or any other way?
Your question almost sounds like an OOP best practices question as opposed to a Zend Framework specific question. Regardless of whether or not I'm using a framework, and regardless of what framework I choose, I base when and where I create new objects on testability how many times I have to write $object = new My_Random_Object();.
Speaking specifically to the Zend Framework: Objects I'm going to use everywhere, or almost everywhere, get created in Bootstrap.php. These objects generally include a database adapter, logger, view object, and any plugins I might use. To access these across the application, I'll create private properties in the appropriate controllers and assign the objects to those properties in the controller's init() method.
class ExampleController extends Zend_Controller_Action
{
public function init()
{
$bootstrap = $this->getInvokeArg('bootstrap');
$this->_db = $bootstrap->getResource('db');
$this->_log = $bootstrap->getResource('log');
// and so on, and so forth
}
}
Ideally, models, services, daos, etc, will all be relatively tightly grouped by controller and by action. In my experience, and this is speaking generally, if I have the same model or service class showing up across all of the controllers in my application, I have an organization problem. That being said, any model that shows up in only one action gets created in that action. If it's across actions in a controller, it gets created in the init() method and assigned to a property. If it shows up across multiple controllers, it gets created in my Bootstrap.php.
(Ideally, everything gets created in the Bootstrap.php, so you can swap out that bootstrap for testing purposes. Sadly, I don't always do that, and I most often use the principles I outlined above.)
Well do you really need it in every controllers? Because that's pretty much by design. You implement models when you need them. Its not that much code really.
Now if its to be used across actions from a controller you could always:
class MyController extends Zend_Controllers{
$protected $_articleModel;
...
and in your constructor or __init() function initialize it so you can use it in every action thru $this->_articleModel
If you REALLY want it everywhere in your application just initialize it in your bootstrap and store it in the registry.
public function __initModels(){
$articles = new Application_Model_Articles()
Zend_Registry::set('articles', $articles );
}
And access it in your controllers like so:
Zend_Registry::get('articles')->fetchAll();
But then your still writing a couple of characters.
Hope this help!
IF you want to use models in the controllers you must call it..anyway some shortcuts are here
1.You can initialize it in the init section of your controller like
public function init(){
$this->object = new Application_Model_Database();
}
So that the this->object is available in all the actions of that particular controller
2.Use Zend_registry as suggested in the above answer
Another possibility is to use a Dependency Injection container, such as the Symfony DI component. It takes care of instantiating your objects, and you get some additional benefits:
Separation of concerns. You have a component devoted to create your object tree.
Easier testability of the objects.
Last, but not least, the performance benefits given by lazy instantiation (objects are created only when you ask for them). Thus, if some object is not used by the particular controller serving your request, it's not instantiated).
It's a bit more laborious than the above solutions, but much more flexible if you need to maintain and extend your application in the future.
Hope that helps,
If you are using this object to just display data in your view and are using your controller to grab the data and assign it to your view, like so:
//someControllerAction
$object = new Application_Model_Articles();
$object->fetchAll();
//assign to view
$this->view->articles = $object;
You might be better off making a view helper similar to:
//Articles.php put in /application/views/helpers
class Zend_View_Helper_Articles extends Zend_View_Helper_Abstract {
public function Articles() {
$articles = new Application_Model_Articles();
$articles->fetchAll();
//return rowset object
return $articles;
Then in your view (phtml) you could do something like:
//someView.phmtl
<?php $articles = $this->Articles(); ?>
<h1><?php echo $this->escape($articles->title); ?></h1>
<p><?php echo $this->escape($articles->body); ?></p>
building a view helper allows you to bypass the controller completely if you just need to display data from the model. This is a very simple example and can be used with partials and partialLoops.
REF:ZF reference Custom View Helper
ZF partial view helper reference