In one of my previous blogs, I wrote about my desire to move forward with converting my site to HTML5 and CSS3. Obviously I can't make a FULL transition due to browser backward compatibility, time, and what is supported with newer browsers. However, the longest journey begins with a single step. My first step in this transition is to replace the top image header, with a pure CSS3 solution. Having the ability to apply gradients with CSS3 I was able to completely remove that banner image with just a few lines.
Lately in the PHP/Zend Framework blog world there has been much discussion concerning what constitutes a model in an MVC app. In the current implementation of the MVC apps at work our ZF Form implementations are processed in a corresponding model class as well as a 'notify' method which handles emailing a response after successful submission. I was able to abstract all aspects of the email properties except for the message body.
Most of the time the requirement is to have, basically, the same form view but with the values populate. That usually means creating some long and kludgy looking heredoc or worse a huge string of crazy html intermingled with escapes. Neither solution was very appealing to me. I kept thinking more and more that the email body was really a view. So I treated as such. So my solution was to create a global views directory and a view script that was the email body template and passed it's render method to Zend_Mail instance. This allows for further separation of models and views. I know that technically the email body should be apart of the model, but far too many times I have to change how the body of the mail looks, not the data, so it lends itself to more of a view. Please feel free to comment. ::NOTE::Forms as model architecture taken from http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html
I was presented with a project where the client wanted a form that would accept credit card payments via paypal. I could either write it in PHP or Java. While I am a big fan of both languages I felt in this instance that PHP was the most time efficient route. However, PayPal doesn't offer an API for PHP. Only Java and .NET. As to not be discouraged I decided to spend a little time trying to come with a custom validator that would handle the validation of the credit card validation.
::Warning::My use case was very specific. I only needed to authorize credit card sales. Basically their simpliest form of transations. Since all the applications that I write now are us the Zend Framework I was able to reduce "inline-code" by creating a custom validator that I assign to my preValidation method inside of the model. :: I worked on this concept with Jeremy Kendall :: There is definitely room for improvement, but this is might be helpful to others. For example, the paypal options should really not be declared as Zend_Config instance, but checked for an instance of Zend_config and then set as an array with the toArray method.
// Validator
One of the many growing requirements that I am experiencing at work is for internalization of our forms. In this particular use case the languages available are limited to English and Spanish so I am not able to use Zend_Locale::BROWSER exclusively. To make sure that correct form displays, in my form model class I created an array of allowed locales. Before the form instantiated in the controller the language param is set the registry, and then that locale is checked against allowed locales.
References:Translations - located in my models directory: Models/Languages/En.php and Es.php
If locale is allowed then the form label translation is set.
It is forgone conclusion that if you need to present a large amount of data with a UITableView then you should do so using an index and index sections. As with most tutorials that I have read on this topic, the scenarios used got me 80% of the way. In my humble opinion, the solutions where either over engineered or they didn't apply to my use case. Hopefully this tutorial/sample project will bridge the gap.
The tutorial that I got the most from is: iPhone Development: Creating Native Contacts like screen. One of the biggest hurdles that I had to over come, that was different from the contacts tutorial, was that I wasn't using a database and therefore didn't have a predefined sub-result set for each character. I was having to do the opposite. I had to iterate over my result set, array of states, grab the first letter from each item, check to see if there was already a dictionary key that existed for that letter and proceed accordingly. Logic FlowIterate over states
Get the first letter of that particular state
Check to see if there is a key in the objectsForCharacter dictionary
- YES: add the state string to the arrayOfNames array and then set the arrayOfNames to the objectsForCharacter dictionary for the appropriate key
- NO: remove all objects from the arrayOfNames array and add the firstLetter to the arrayOfCharacters. Then proceed on to the above "YES" steps
Once all the states have been "proceed" then reload the table data Final Model
Though it sounds some what complicated with all the arrays, dictionarys, etc. once you break it down to a visual model then the code is easier to comprehend.[[objectsForCharacters objectForKey:@"A"] objectAtIndex:0]; // Alabama
[[objectsForCharacters objectForKey:@"A"] objectAtIndex:1]; // Alaska
[[objectsForCharacters objectForKey:@"A"] objectAtIndex:2]; // Arizona
[[objectsForCharacters objectForKey:@"A"] objectAtIndex:3]; // ArkansasDownload Example Project (comments/enhancements are welcomed)
IndexedTable.zip
Not My Idea
Erin always asks me if I use one-third of the apps on my iPhone. Truthfully I don't. There are probably four apps that I use 80% of the time. The others I download or purchase because they inspire me. I might like the way that the app is designed or handles a particular usability feature or the combination. Then there are the few that I downloaded because my daughter REALLY likes them.
As a developer I knew what I wanted to put into the app, as far as, functionality goes, but I really wanted my wife's thoughts/opinions/feedback since she:
1. Came up with the idea
2. Is in sales/marketing and knows "people" better than myself
In the beginning she started the conversation with, "Can the phone do this?". I stopped that immediately because I wanted to hear what she envisioned as the perfect break-up app. After getting a list of all the "wants" we sat down together again to go through them and make our first round of cuts which basically amounted to me explaining that the phone didn't have that functionality. Over the next few days we came together again and made a list of three or four major features that needed to be included with some "nice-to-haves" added at the end. Let the coding fury begin.
Hard DecisionsAs I started down the path of coding the app things went VERY smoothly and I was quite happy with my progress and my continued growth of knowledge of not only Objective-C/CocoaTouch, but mobile usability as well. When I got about three-fourths of the way done with the project I hit a fork in the road. I came up with a handful of features that I thought would be GREAT to add into the application, but would extend the project at least 4 weeks. The features included various Facebook integrations, a "breakup/erase wall", video recordings (for those 3GS users), canned messages, top 10 breakup songs from iTunes, etc. However, I had to make the tough decision to keep the current feature list and mark it as version 1.0 and save the others for future releases. I am working currently working on version 2.0. What Made the Cut?
The simplicity of the app is what, IMHO, makes the app pretty good. I decided to keep, what I considered, core functionality. The ability to send a photo and/or an audio recording and/or a written message via email. I did add in the persistence level of the data and the ability to create multiple audio files, as well as, manage those files. In Apple's Hands
Finally, after months of development, in the wee hours before work and after my daughter went to bed, I incorporated the custom UI elements, create a product site, and submitted EraseUrX to the App Store. Fingers crossed.
Release
Seventy-two hours later, I got an email from Apple saying that app had been approved and was for sale in the App Store. Like a kid at Christmas I couldn't click on the link fast enough. To my dismay I got the equivalent of a 404 error. I wish they would have had a little note in the email saying that it might take up to X amount of hours for the app to propagate to all their servers. None the less by the afternoon it was there. I had successfully planned, created, designed, and deployed an app to the App Store. Hindsight
Looking at the complete process I do not have too many regrets. The things that I would do differently are as follows, and in no particular order:
1. Start the marketing for the app earlier than right after I submitted the app.
2. I should have kept a development "diary" online that showed the progress and little teasers.
3. Had a promo video that went along with the app. Not a technical video of what the app does, but a marketing video.
4. Done more research on successful, and maybe, unconventional ways of marketing the app.
What's Next
While I don't think that EraseUrX is a revolutionary app, I do think that it is decent, but like any creation it can, should and WILL be improved. There will be the option to either send the "breakup" via email or to Facebook, more fine grained control over what is saved on your phone for later review, video support, and a cleaner design. As stated in my previous entry, the completion of this project has just fueled my desire to work more exclusively on iPhone apps. Some will be personal projects, but for right now I'll concentrate on contract projects. I am currently working with a local photographer to create an app to showcase the work that he does. It is more than just another photo gallery slide show application and I think will have some nice additions to what people normally expect.