views:

377

answers:

4

I'm taking the plunge into iPhone development after about two years working with django. As I've done tutorials and read documentation, one of the things that strikes me as inconvenient about the various libraries used in iPhone development is the amount of repetition required when creating user input forms for data models.

I know of two conventional approaches to user input form creation:

  1. Create a group of UITextFields in Interface Builder that correspond with the properties on the model class and link them up to corresponding IBOutlets on a custom form controller.

  2. Create a form view programatically with UITextFields in tables with a custom form view controller class. The class keeps a list of names that correspond to the properties of a model in an array, and then iterate over the array to create UITextFields for each table cell. Use special casing to determine which model attribute is being iterated over, and use that information to create table cells with corresponding UILabels and UITextFields.*

Of the two, only the first seems practical for iterative development, the second is painfully verbose and extremely difficult (for me) to read. With the introspective capabilities of Objective-C it seems like it would be possible to write code that accepted a model class as an argument and generate a form controller (and perhaps even a form view) from that information at runtime.

So I have three questions:

  1. Are there conventional alternate approaches to creating form views and controllers for models other than the two I've listed above? I'm not loving either approach I've listed there.

  2. Is automatic generation of form controllers / views at runtime feasible in Objective-C, or am I just barking up the wrong tree?

  3. Has such automatic generation been attempted or accomplished already? (a little googling turned up nothing)

*My main reference for this comes from Example #6 in Chapter 9: Navigation Controllers and Table Views of Apress' "Beginning iPhone 3 Development"

A: 

It seems like your trying to write an iPhone app like you would a Django website, but the two are completely different.

Here is a quick rundown of MVC in cocoa:

  1. Write your model classes independent of any controller or view
  2. Write a controller that stores the model class as a key (e.g. -[MyController model] and -[MyController setModel:])
  3. Open interface builder and design your view. Use bindings or code in the controller to make the view interact with the model
Tom Dalling
I described two approaches above for creating an input form for data to go into a model. I'm not sure how what you've written here differs in any way from what I described in #1.
Prairiedogg
"Re-declare the properties of a model class as a group of UIView subclasses" sounds as if you're putting UIView subclasses into the model, which is the wrong way to do it. I don't think your question is clear enough to get the answer that you want.
Tom Dalling
Thanks Tom, I've edited my question a little, you're correct that it was not clear enough originally.
Prairiedogg
A: 

Keep in mind that systems like Django are based on completely scripted environments. The language constructs can be dynamically created, interpreted, and re-interpreted many times during the execution process.

Concepts like business rules and forms logic can literally be written as pages are being sent to the client/browser.

For compiled languages, all of these moving parts must be pre-created and fully resolved (for the most part). Most of the classic UML based source generation or template based systems were complex behemoths that generated very difficult to use code.

The MVC model and libraries like Cocoa and Carbon, though possibly not as "elegant" as the techniques possible in Django, did evolve around the need to tackle some of the same challenges.

Although other alternatives exist, such as marrying Objective-C to an interpreted language like LUA or Python is feasible. And there are several open source projects focused at building completely dynamic "over the air" user interface clients that sit on top of server based systems which broadcast details of how the interface looks and behaves. (I can't find the project but will edit when I do)

I'm not aware of any major work in this area and suspect that most normal iPhone applications simply haven't been complex enough either in scope or degree of variability to warrant the effort to create these automated systems.

Rarely is the user interface the complex part of an iPhone application, perhaps with the exception of a few unique games out there.

Barney

Barney Mattox
Thanks for your thoughtful reply, you know - it's EXACTLY because of what you say "Rarely is the user interface the complex part of an iPhone application", that I think the boring details that you have to repeat over and over again are likely candidates for abstraction. Isn't that how it should be? Cases are handled implicitly by convention when they are generic, and overridden when they get complex and application specific. Right guys? ... Guys
Prairiedogg
To further your point, Barney, I think the iPhone developer license agreement prohibits one from using an interpreted language in the Cocoa Touch environment.
Quartz
I'm familiar with that reference in the legal document, but I believe it is not quite as restrictive as it sounds (I'm no legal expert of course). At least two of the commercial engines for iPhone include scripted engines and several products have shipped with LUA based cores. Apple forbids user generated code or dynamic code (that might differ from the reviewed product) from running, but seems to allow interpreters within certain strict limits.
Barney Mattox
I just -1'd this answer because it's completely wrong about Objective-C not being sufficiently dynamic compared to scripting languages like python. In fact ObjC is fully capable of doing what you want and is just as dynamic as python or ruby, although the syntax can be a little bit messier when you are doing it.
sbwoodside
@sbwoodside - I've actually updated my thinking on this as well. I'm using dynamic systems which I've created for Cocos2D quite successfully. It's not "scripting" as such, but it does provide the ability to create "dynamic" content. I had not come back to this question in so long I'd forgotten about it. Many apologies.@quartz - Your are correct, but Apple has left some gray area for "burned in" scripted content. Several programs use Lua and Python now, as long as the scripts can not be changed after release.
Barney Mattox
+1  A: 

I'm working on the same problem now, in my case I have a complex set of models that are coming from WSDL, and there's a LOT of form elements that can change from time to time. I definitely do not want to be doing the forms by hand in code or in IB.

Objective-C is a fully dynamic language and you can definitely do what you want to do in a fully dynamic fashion. Assuming that your models are Core Data models, you can find all of the properties using something like [[myCoreDataObject entity] propertiesByName]. You can then iterate through these properties automatically creating the appropriate form fields depending on their types.

You would then create a subclass of for example UITableViewController which you pass an NSManagedObject to, and it will automatically create a form which matches the model object.

sbwoodside
Thanks - I was very new to Obj C when I wrote this question, but everything seemed to indicate that what you could do in python, you could do in Obj C. Glad to have the confirmation. Thanks also for the code snippet.
Prairiedogg
I think that using Interface Builder is better in the situation where you have small manageable forms. But in my situation I'm looking at dozens of forms with dozens of elements, defined in WSDL in my case, which would be prohibitive to implement in IB. Also, I know that they will be changing in the future.
sbwoodside
A: 

Those are two approaches to solve the same problem, really, and neither is more correct than the other. You can certainly do the first one quite easily -- ObjC is a fully dynamic language.

However, I would personally recommend not "fighting the framework." Just as how it's totally possible to take route #2 in Django, the framework isn't built around that approach and you'll end up writing a lot of code that you wouldn't have to write otherwise.

Cocoa's approach -- route #1 -- certainly has its merits. I would highly recommend giving it a chance.

Colin Barrett