I'm a Java Developer new to iOS and objective c development.
I need to build an iOS application where multiple views (e.g. a ListView and a MapView) access the same data (e.g. stored in an NSArray).
Currently, I do alloc and init a DataManager class that loads the data (loading it from a plist, later it should be requested from the web) in the app delegate.
How do I access this data from the views? Should the DataManager be a singleton? Is there a better/more elegant/more "obj-c 2.0" solution?
Thanks!
Use the MVC architecture. Your data is a model object, which can be passed to the various controllers that use the data to populate the views. In Cocoa Touch, the views are the UIView subclasses that you typically create in XIB files. The controllers usually start with UIViewController instances that manage the views, but include things like table view delegates and data sources. The models are the objects you create to represent the data - your DataManager class.
There are plenty of frameworks in the Java world that use the MVC pattern, so you may already be used to dividing classes up this way if you've come across e.g. Spring MVC, or Eclipse RCP.
Related
just started iOS 7 development. I'm building an app which stores a user profile. Certain data, like photos and reviews, need is related to multiple users.
From researching, I found that Core Data essentially provides this type of relational DB. But super n00bie question - is a Core Data the same as a Singleton? Which should I use for accessing user data across multiple viewControllers?
If I go the Core Data route, it seems that I'll have instantiate a Core Data object in every ViewController. Doesn't that seem excessive??
With Singletons, I won't have to do that, but I'll need to have proper thread management.
Sound right?
CoreData is an object model framework, and a singleton is a design pattern. This isn't even comparing apples to oranges, because apples and oranges are both fruits.
But your question makes it seem like you want to know how to access your data throughout your app. There are a few common patterns for this.
You typically use one or more instances of NSManagedObjectContext. You can pass this instance along to each view controller. Or you can have some singleton object which has a reference to the NSManagedObjectContext. This singleton is often the App Delegate, especially since the built in Xcode templates already come with a reference to your NSManagedObjectContext in the App Delegate.
it's not the same thing at all.
Core Data allows you to create subclass of NSMamagedObject which are object representing table in a sql data base stored on disk.
singleton are unique instance of any class (usually if not never an NSManagedObject).
read on wikipedia about singleton it's a good article.
both have nothing to do with iOS7
When I have worked with Java applications involving a database and ORM (object relationship manager) the architecture was usually separated so when working with database entities in the database layer you worked directly with the entities. But if you needed to access the entities in the GUI you would create a data transfer object (DTO) of the entity and then use it in the GUI layer.
What is the preferred approach in iOS applications?
One example would be that I do a fetch from Core Data to retrieve some objects in a ViewController and then display the results in a TableView in the ViewController. Is it necessary to convert the NSManagedObjects to DTOs before showing the results?
What is the preferred approach in iOS applications?
Is it necessary to convert the NSManagedObjects to DTOs before showing the results?
No, it is not neccessary. The managed object is already a (generic) object wrapping the database entity. You can access the managed object's properties (ie the entitys attributes) using -valueForKey: calls.
But the preferred approach is to subclass NSManagedObject to fit your entities. In Xcode there is an option to generate subclasses automatically (editor-> generate NSManagedObject subclass). That way you get your own subclass object for your entities and can access their properties using dot notation.
On fetching objects, just let the result be of type of that subclass.
If you want to add custom methods to your entity objects, you should create a category on your managed object subclass. This is because if you change your db scheme and have to let xcode recreate your subclasses, it completely overwrites the and your custom methods would be lost.
I want to use SQLite database to store the scores of the games created with cocos2D framework. I use a singleton class controller called GameManager to control my application. To load the Scores I have a ScoreScene class which inherits CCScene and that class is called from GameManager, then when ScoreScene loads and from ScoreScene ScoreLayer class is called which inherits CCLayer class. I temporarily stored the score variable in GameManager and it is accessed from everywhere.
Now please help me and point out any weaknesses in my design and also help me in how I can implement SQLite database and store the score from GameManager class to the database.
The GameManager singleton seems to take the responsibility of managing common data and actions globally, right? Just be careful if there are multi-threading cases. I think your design is OK to use.
For SQLite part, you can refer to Apple official documentations if you want to use it via Core Data:
Core Data Programming Guide: Persistent Store Features
Core Data Programming Guide: Using Persistent Stores
Or you can use it via C interface directly. Some references:
http://klanguedoc.hubpages.com/hub/Tutorial-on-Creating-an-IOS-5-SQLite-Database-Application-IOS-5-SQLite
Use CoreData or SQLite on iPhone?
I'm working on an exiting iOS app (called Mazin in the App store, if anyone is interested) and I'm trying to rework the code to avoid using the Application Delegate or a singleton for sharing information/methods. In particular I have the following to share across certain views and controllers:
CoreData objects like NSManagedObjectConttext and related custom methods for interacting with the data
State properties used in several places like currentMazeType, gameMode, and soundIsMuted along with a few widely used utility methods particular to the game
Views and methods used to display information used commonly throughout the app (e.g., an ActivityIndicator and methods to show/hide it on a given view)
In general, several views and ViewControllers need access to various subsets of this information and I need a mechanism to share the information and methods "globally" across these objects. Some of this sharing is for convenience (e.g., every time I want to display a basic activity indicator, I just call a common "startActivityIndicator" method) but some are required (e.g., changing gameMode changes it "globally" and several views/controllers need to access the common mode info).
What sort of patterns would work best for this requirement? I have my own solution in mind, and I'll post it below for your consideration/comments.
Thanks!
Solution I am considering:
I plan to create a few "utility" classes (e.g. GameDataUtil, AppStateUtil, GadgetsUtil) that each encapsulate a proper subset of the "global" information and/or methods. Each View or ViewController that needs to access the common info/methods in a utility will have an appropriate property of that given type (e.g., a view that can make a sound needs access to the AppStateUtil so it can determine if sounds are currently muted).
The ApplicationDelegate will be the only class that generates single instances of the "utility" classes and will pass those instances to the appropriate objects that get loaded from its Nib (in applicationDidFinishLaunching). Those views/controllers will have to pass all necessary information to any of their members that they may load programmatically (which could get hairy--class A may need a GagetsUtil in order to pass it to an instance of class B even though class A never uses the utility directly).
This is sort of like injecting dependencies from the application delegate down (since I don't have the utility of an Dependency Injection Container).
Now, I have thought about creating an uber-utility (e.g., ConfigUtil) that would hold one property for each of the other utilities. The AppDelegate would create a single instance of the uber-utility (setting it up with instances of the other utilities it creates). The AppDelegate would pass the uber-utility instance to anyone who needs access to any of the basic utilities. Each basic utility would still encapsulate a sub-set of the common data/methods, but by putting one of each into an uber-utility and passing it around, I don't have to keep up with which utility is needed by which class (not only for its own use but also to pass to any of its member objects).
NSNotification would be a step away from that model, and is typically easy to implement.
If many things know of and refer to mutable global data right now... it will take time to undo that.
Update
I remembered that I had written a more detailed response to a similar scenario here at SO.
i've been reading for a while a little bit of Objective C and Cocoa, and i have to say that although i am thrilled with the overall simplicity of Objective-C, I feel totaly lost regarding Cocoa and especially the MVC design pattern. The Cocoa books I've read, ask the reader to just complete a set of steps for a program to work, without doing much explanation about the mechanisms of the API. I am trying to understand the overall meaning of NSTableView, NSOutlineView, their datasources, their delegates, and what all these have to do with the various controller classes like NSArrayController and NSTreeController. So i have a couple of questions to ask:
How do these classes really interoperate ?
Is the datasource of an NSTableView an instance of an NSArrayController ?
Should a delegate and a datasource be the same class in a NSTableView or NSOutlineView ?
Leaving binding aside, do NSArrayController and NSTreeController have any other important advantage ?
Let's assume that there is a container (in C) with some sort of data (a C struct). We want to be able to show these data in an NSTableView (or NSOutlineView) and to exchange views at runtime, if the data structure is hierarchical. Should i create a class that has an NSArrayController (or NSTreeController) as instance, and wrap the functionality of the C container ?
Thank you and forgive me for my silly questions.
These are not silly questions. You're asking precisely the right questions, and have gone to the heart of how to learn Cocoa. Learn MVC first, and how Cocoa implements it, and the rest will be clear.
While slowly becoming dated, there is still no better book for learning Cocoa than Cocoa Programming for Mac OS X by Aaron Hillegass. I wrote up some more comments about this book last year if you're interested. And some more guides (mostly targeted at new iPhone developers) here and here.
To your specific question, rather than store the data in a C struct, store it in an Objective-C object (a model object, the "M" in MVC).
Then build a Controller class to be the datasource for the NSOutlineView (which is designed for hierarchical data). For the moment, avoid Cocoa classes that end in "Controller." These are related to bindings (and mostly used for Core Data). While very powerful, they're more than you want to dive into at the beginning (and even after years of Cocoa programming, I only use bindings for certain targeted problems; they can make your programs very hard to maintain if they're complicated). Your controller for now should be a subclass of NSObject. It will implement the NSOutlineViewDataSource methods. If you need a delegate, it is common and natural to make the same object be the datasource and delegate.
How do these classes really interoperate ?
Consider the traditional way using a TableView or OutlineView (in any language). You typically implement a data source interface that will provide data for the view. This data source implementation is essentially a "controller" that translates your data model to your table view; and it can also handle row selection, inserting, deleting, sorting, filtering, etc.
Now say your app has a number of different TableViews, each with its own data source implementation. You'll find that each data source implementation starts to look the same; you'd be able to reuse a lot of the code between your data sources, because assuming they're working on the same or similar data models, the code for sorting etc. is also the same.
That's what NSArrayController is: a generic TableView controller/data source. It handles row selection, inserting, deleting, sorting, filtering, etc. thereby saving you from having to write a bunch of boilerplate code.
Is the datasource of an NSTableView an instance of an NSArrayController ?
No, data bindings replace the traditional data source interface; therefore, the NSTableView is connected to the array controller using data bindings.
For example, you would bind a table view column to a property of your model:
myArrayController.arrangedObjects.firstName
where arrangedObjects is a property of NSArrayController and firstName is a property of your model.
Should a delegate and a datasource be the same class in a NSTableView or NSOutlineView ?
When using data bindings you do not set the NSTableView's data source. You may still provide an NSTableView delegate to customize the look and behavior of the view. NSArrayController is not an NSTableView delegate.
When not using data bindings then you must implement a data source. Often the data source and the delegate are the same object.
Delegate is object that receives callbacks when something interesting happens with the view.
Datasource is very similar to delegate - it also receives callbacks, but only those related to getting data for the table.
They don't have to be the same (you might have controller/delegate that can operate on any data source), but in practice they're usually the same object, because it's convenient to provide data and operate on it in the same class.
You don't need to use NSArrayController at all, if that doesn't fit your program. Any class can be a delegate (it's informal protocol, meaning you don't need to declare any interface nor inherit any base class), you can simply write your own delegate methods.