JSON-driven iOS MVC architecture - iphone

I know this is a bit of an ethereal question, but I'm working on an app that takes its entire structure from a remote JSON object and I'm trying to figure out the best way to approach the creation of Views, View Controllers, and Models. Currently, I am using RestKit to grab, parse, and map objects. I will have the structure of the views, controls, and fields defined at runtime, so how should I dynamically create and manage object composition, view controllers, and all appropriate delegates? (I imagine KVC and KVO will have a huge part in all of this.)
A few things to address:
Nested/chained delegation to allow leaf control events to bubble up to the root controller and then down to the proper model.
Dynamic object composition to allow a view to contain an arbitrary combination of subviews at runtime
Dynamically linking data between views and the proper model objects
Are there any good resources, guides, or examples of implementing/planning for this type of architecture?

This answer may not satisfy you but i will try to help.
Initialize dictionaries(NSDictionary) and detecet objects&values with [yourObject objectForKey:#"yourJSONKey"]; and [yourKey valueForKey:#"yourJSONValue"]; and after this create&push your views so that thay play a rol in run time(according to the JSON response)

Related

What is the right architecture to design classes for SwiftUI app

I am bit new to app development in SwiftUI. In last 2-3 months I have developed few small iOS app just to learn concepts. Otherwise I am experienced developer in C#, Java etc.
One thing I am little unsure about SwiftUI is the right set of architecture around developing classes for the project. I mean like there could be couple of ways
We write model classes that represent the data that our application need to hold. In purist form the model classes should only be concerned about just data, I mean the model classes should only hold the attributes that reflect the data.
Say I am writing a Inventory management app so if one of the model is Merchandise item then its attribute could be Id, name, price, barcode etc. In my opinion the model classes should not concerned about View's concern like #Published, #ObservableObject, #State, #EnvironmentObject etc etc. Model should just stick to representing domain only. Correct?
Ideally the model classes should be written as Class not Struct (if I carry over my understanding of OOPS from C++ to Java/C# where we write classes not struct)
The second set of classes we need are views i.e. inherited from View. Undoubtedly these has to be Struct as SwiftUI framework works this way.
Now in between the model classes (presuming they are classes or at max we made them Struct for the sake of SwiftUI framework) and View classes, lots of communication, state change, eventing has to happen to make app worthy of doing something. I mean handling user gestures, creating & editing data which should update screens when user navigate back and forth between UIs.
I found it little hard to connect Model (if they are developed in purist form) and View. Hard in the sense that as I started writing Views and look to implement use cases which involve data editing, reflecting changes in views etc I found pure model classes insufficient. They have to be modified to reflect SwiftUI features like binding, observability, published to sync data between view and model and also between two models.
Wondering what is the right design pattern to connect and communicate between model and view? Is MVVM the right design pattern to be used in SwiftUI based project? If not then what else is right pattern?
If MVVM is right pattern then are there any quality guide or resources or sample SwiftUI projects (gitHub??) I can look at and learn?
I think your hypothesis is wrong.
Ideally the model classes should be written as Class not Struct
Make a distinction between model with and without state.
Model without state should be value type.
Model with state should be reference type.
The second set of classes we need are views i.e. inherited from View. Undoubtedly these has to be Struct as SwiftUI framework works this way.
Value type cannot be inherited. I also think they are models rather than views.
E.g.; struct Model: View {}
They are models, that can be used to build views, hence the View conformance.
The fact that it is of value type also supports that it's not view. (cannot be inherited)
Whether your model has state or not, as long as it conforms to View, it can be used to render a view. This is the design of SwiftUI, taking a page from React, IMO. (I personally don't see React ever bothering with MVVM)
Now since you think Model should be strictly without state, you have a problem.
You need a reference type object that handles all the state and bridge it to the view.
You can follow MVVM. In that case you lose most of the SDK support that builds around struct Model: View, e.g.; #State, #StateObject, #EnvironmentObject, and associated automatic binding and safety checks. You would also add at least one reference type for each of the views, and put most of the control / business logic in it. (where else can you put it?)
So it's in effect a view controller. And you would be doing most of the Control work on a reference type object, without safe guards of immutability. That is on top of all the overheads you would introduce; and since you would pass view model around to be "reusable", you are going to have all the usual bugs caused by shared reference with implicit states.
Take my above assessment with a grain of salt, of course.
Or you can do what official guide do: struct Model: View {} with possible states in it.
The key here, as SDK requires you to put extra annotation, is that state objects are explicitly identified. E.g.; #StateObject, #ObservableObject. And you have to create reference type objects separate from your model. It essentially cuts out the middle man that is view model.
I think this is the most difficult thing for MVVM devs to get used to. You no longer need a view model to do what a view model does.
But shouldn't it be obvious? View model depends on how binding is designed. If SwiftUI has a binding design so efficient, (it does so declaratively without extra object) view model could be automatic.
SwiftUI removes UIViewController, does that mean you can't have Control?
I don't see MVC developers come out and create a Controller for every view.
Same reasoning, you can have MVVM without VM. Design pattern is a #State of mind.
To summarize:
I think the best architecture is official SDK. Learn to walk before you run.
MVVM in legacy sense is an option too. But I think you need to consider the possibility that
traditional wisdom is not up-to-date with latest SDK.

iPhone development and use of separate model files?

I've read a lot about MVC as I'm ramping up with iPhone / IOS development. However in the various sample files I've see so far I'm not really seeing separate classes for model, view & controller?
How should I concretely see MVC in action with a best practice developed iPhone application? For example perhaps one based on a NavigationController & some Table Views etc.
For example:
Should there be a separate Model, View & Controller for each "iPhone UI controller" - noting that there seems to be 1 page == 1 UI controller in iPhone development from what I'm seeing, then my question is effectively should each UI Controller have it's own View file and Model file?
Given that Interface Builder and NIBs are a big part of things, to what extent is a NIB considered to be part of the MVC pattern? e.g. does the creation of a NIB effectively implement the "controller" and the "view", leaving you to create a separate class (in a separate file) for the model?
What happens when you've got shared data (or a shared model - e.g. a list of items) that is shared/used by multiple application pages (e.g. list view, edit view etc) - in this case this seems to me you would have 1 x model, but then reuse this model instance across the separate pages (which are View & Controller).
Hope this makes sense...
You'll be following MVC by using the objects and tools in their typical use. A UIView object is used to present data and receive input (View). A UIViewController responds to events and routes the data back and forth between the data model and the UIView hierarchy (Controller). Your data model lives wherever you want it to, sometimes composited together with your UIViewController subclass, sometimes present in the app as a singleton class (Model). When you specify your shared data model as a singleton class then any class that needs it can access it from anywhere in the app. By maintaining this division of labor, your application will tend to be well-organized and modular, and you can maintain/extend one aspect without having to rewrite all the other aspects of the program.
Interface builder is a tool for visually building the view hierarchy (and to some extent the control hierarchy) of your application.

Maintaining Single Responsibility Principle (SRP) with UIViewControllers

Sticking to Apple's guidelines, I create one subclass of UIViewController per screen of my iPhone application. However I consistently find that these classes become very large, both in terms of sheer lines of code and number of member variables.
By definition they end up being responsible for quite a number of different concerns (e.g. view life cycle, mediating between views and models, sometimes touch handling, control logic, managing alerts and other UI state).
Not only does this violate the Single Responsibility Principle but it also results in large swathes of code which are near impossible to unit test.
What responsibilities/concerns do you tend to divide off into new classes? What kinds of responsibilities do you think make good candidates for clean separation in the case of UIViewController subclasses?
This is an interesting question and I also struggle on how to properly separate responsibility. It all depends on the context but since testing subclasses of UIVieController can be a pain I try to move as much as I can into model classes. In the spirit of Skinny Controller, Fat Model.
When it comes to tables I have created a base model class for handling all the table view stuff, basically encapsulating what you get when you create a new Navigation Based Core Data project. The in the controller I just forwards the calls to my table model.
I'm trying to keep the methods of the controller as small as possible. Depending on the context I may have several model classes, each responsible for a specific part.
I have also looked into the possibility of using controller factories for getting detail controllers for certain data models.
UIViewController *detailController = [self.controllerFactory controllerForItem:item];
[self presentModalViewController:detailController animated:YES];
This way I can unit test that I get the proper controller for a specific data item without having to involve the parent controller.
With mine, I'm creating categories, abstract parents and using a variety of patterns I've learned in the Java world to reduce complexity and code duplication. But when it comes down to it, I still have one view controller per screen because every screen has at least one thing on it thats unique in some way. There just might not be much code left in the controllers thanks to the infrastructure I've placed around them.

Wheres the best place Iphone app to place a Data Model instance and how would you Access it?

I am learning tons on this thing. Reading also, but this is awesome!
Ok.. so long story sort I hope. I'm making a data class to pump out some instances of people that have various attributes. I would like my view controllers to be able to access them (through properties of course.. I think) to manipulate their data.
Where in an iphone app would be the best place to do this, and how would you write the code to message to this object. My current setup would be to have a navigation controller with a firstlevelviewcontroller that created a few secondlevelviewcontroller children instances that would do things like pickers for date of birth, and height, weight, etc.
Could the Navigation Controller make these model objects? Should application delegate? Lets say application delegate does. If so, then how would I put references to these objects from my first and second level view controllers?
Awesome!
**Update for the new millenium. **
I'm reading on core data structures, and though they are awesome, they are above and beyond what I need for this project. what I need is simple, I think..
I want one class that is a data class with a few variables that I can manipulate. I want to manipulate these from two view controllers. I might want more than one data instance, so I don't want a singleton data object. I don't need a persistent store of data.
I would like to know how to step by step have this data class instantiated.. should it be in app delegate? can i do it somewhere else? I dont want it a child of one of the view controllers.. How would I do that? then, how would I reference it from the view controllers and manipulate data (I'm pretty sure through properties but I can't figure out how to reference the instances to make this happen).
CHeers! thanks for the help!
Lots of questions that fringe on conjunction of various best practices.
First, the NSManagedObjectContext (if instantiated in the application delegate) can be shared in any number of ways. You can push it on through as you load your controllers or, something I've been more want to do (and will gladly argue the merits), you can hand it off to a Singleton that any controller has access to.
Depending on the model graph and how your UI maps to the data objects (you didn't say), keep in mind being memory friendly. I defer creating the NSFetchRequests until there is a controller that needs the data (CRUD).
If you want to edit your question or add comments that may provide more clarity... the answer may change
Frank

Load different views depending on the category of data on tap of tableview cell iPhone sdk

In my aplication, I want a tableview with different cell structure depending upon the category of data that's getting loaded in it [I have different categories like video, editorial etc with different structure of data like video has a single label, editorial has 3 labels etc]. I can load different nib files based on the data coming from xml parser.
Now when the cell is tapped, I want to show its detailed view on a new viewController. So my question is is it possible to use only 1 viewController show different fields depending upon the category of data in the cell. Or do I need to create different viewControllers for each of the categories?
You can use single view controller. Only thing is you need to feed the data to be displayed in that view controller.
But keeping separate controllers for different functionality will make your code pretty neat and easy to handle. So It would be better if you keep separate controller for handling the data.
You can write code to do whatever you like. But using the same object to display multiple object types wouldn't be considered good practice, assuming that the elements you will be displaying are different.
In OOP, we normally create different classes to simplify code, and share code using various strategies, of which subclassing is would seem appropriate to this case.
Meaning: create a class to handle the general cases applicable to all the object types you want to display, and subclass for the specific requirements for each type.
It depends on what kind of data you have in each of your categories. If the format of the data in each categories is different and you already know it, design viewControllers such that they directly read the data and display it however necessary. The viewController should itself handle the displaying logic.
On the other hand, if all categories are of the same type, you can create multiple instances of the same viewController, use them and release them as necessary.
In your case, it sounds like the second option can be preferred.
Edit: It would be wise to go with different sub-classes of viewControllers keeping design pattern in mind - "Closed for modification and open for extension".