October 29th, 2008 Rusty
I’ve certainly done my share of complaining while I developed an application for the iPhone. I can honestly say that I’ve come from completely lost to comfortable on the platform and gained valuable skills and insight during the process. It was not easy. I am fortunate that my company is founded on the ideal of bringing technology into finance to produce valuable tools and the iPhone is an obvious vehicle for that.
Apple Support was Awesome
Credit where credit is due, right? While resources were difficult to find and the NDA made things very complicated, when I contact Apple with questions or issues, they always responded and helped me get through my roadblocks. I had a few problems with the App Signing process and exchanged several emails with Apple support. The responses were thorough and thoughtful. In the end, these very complicated requirements were overcome and I was able to focus on development.
The Submission Process was a Breeze
Relatively speaking, submitting the completed release was pretty straight forward. Of course, I’d learned the Apple way by then and knew where to look for the guidance I needed. The only thing that was confusing was the SWIFT code for our bank. This is simply an international standard for identifying a financial institution and you can usually find it by checking out your banks website. We also called our bank and they were able to confirm the code.
Review was FAST
I don’t want to set any unrealistic expectations for anyone but let me just say that review and approval of my app could not have been faster. I’m sure it helped that our app was well tested and had a clear purpose. We also followed Apples UI guidelines carefully and tried to make it as natural to the iPhone as possible. Needless to say, you can now purchase "StockRazor by Ockham Research"
Posted in iPhone, iPhone SDK | No Comments »
October 23rd, 2008 Rusty
Early on in the MVC Previews, the method RenderUserControl was provided. It was a perfect fit for the concept of rendering a "control" or a "partial" as it did all the work of executing the lifecycle of that control and then returned the html as string output. You could then use that html in any way you saw fit. You may have wanted to store that output in a database or add it to an object structure and then serialize that as JSON. Whatever! You were left to your own ingenuity and resourcefulness to accomplish your business objectives.
That method is GONE. There is no equivalent, that I can find, that will give you access to the html output as a string. It looks like the solution is going to be to replicate that behavior some other way and write all the code yourself. This is really, really unfortunate. See, there are a lot of cases where a control from web forms worked in Mvc except for some strangeness. There might be some view state or a bunch of extra markup that you don’t want or you may have wanted to modify or clean up the html before adding it to your page. Furthermore, there may be an expected render error that you aren’t able to prevent because the control is compiled and you don’t have the source code. Wrapping RenderUserControl in a try catch gave you the ability to catch that problem and deal with it. Gone. Just gone.
Since we used RenderUserControl 61 times in our website, I was not prepared and do not have time to refactor and test all that code. My unit tests will no longer work because I cannot test the output of rendering a control, I can only embed that control in the mark up. The problems that I was handling before are now going to blow up my page. I suppose I can inherit from and extend the Controls in question but that is just big waste of time when all I want to do is handle the errors that the author didn’t.
So I’m rolling back to Preview 4 until I have about a week to dedicate to the update.
I suppose I should have known better than to use Preview Code on a production app but my alternative was either Castle or WebForms. Neither is as pleasing as Asp.Net MVC.
Posted in Asp.Net, Mvc | 2 Comments »
October 23rd, 2008 Rusty
Nothing like self-correction. Following up on this post
I tried something else. It also has html dependencies but its less icky than the "endMarker"
In the ascx file
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ChildRenderer.ascx.cs" Inherits="MvcTestApp.Views.ChildRenderer" %>
<asp:PlaceHolder ID="ContentRoot" runat="server">
I am the top stuff
<div>
<asp:PlaceHolder ID="ChildContent" runat="server"></asp:PlaceHolder>
</div>
I am the bottom
</asp:PlaceHolder>
and the ascx.cs file
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
namespace MvcTestApp.Views
{
[ParseChildren( false )]
public partial class ChildRenderer : System.Web.Mvc.ViewUserControl
{
protected override void AddParsedSubObject( object obj )
{
if( obj is Control && ( obj as Control ).ID == "ContentRoot" )
{
base.AddParsedSubObject( obj );
}
else
{
this.ChildContent.Controls.Add( obj as Control );
}
}
}
}
While not perfect, it is pretty darn easy and takes very little code to accomplish.
Posted in Asp.Net | No Comments »
October 23rd, 2008 Rusty
For some reason, I still struggle with creating declarative controls in asp.net that can have child controls between their tags. Custom controls are the correct solution but what about all those cases where you have some ascx markup and you want to place the output of embedded controls inside a placeholder, for example?
I just hacked a simple answer to this problem and thought I’d share for your critique.
This happens to be an MVC ViewUserControl but it should work for any ascx Control
Heres the ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ChildRenderer.ascx.cs" Inherits="MvcTestApp.Views.ChildRenderer" %>
I am the top stuff
<div>
<asp:PlaceHolder ID="ChildContent" runat="server"></asp:PlaceHolder>
</div>
I am the bottom
<div runat="server" id="endMarker" />
And the ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
namespace MvcTestApp.Views
{
[ParseChildren( false )]
public partial class ChildRenderer : System.Web.Mvc.ViewUserControl
{
private bool _endOfAscxParse = false;
protected override void AddParsedSubObject( object obj )
{
/*if( obj is System.Web.UI.Control )
{
this.ChildContent.Controls.Add( obj as System.Web.UI.Control );
}
else
{
base.AddParsedSubObject( obj );
}*/
if( obj is Control && ( obj as Control ).ID == "endMarker" )
{
_endOfAscxParse = true;
return;
}
if( _endOfAscxParse )
{
this.ChildContent.Controls.Add( obj as Control );
}
else
{
base.AddParsedSubObject( obj );
}
}
}
}
Now, when the last div is parsed, it sets a flag and all additional content is placed inside the placeholder.
It works. Its a little nasty? Ok. But it works!
Posted in Asp.Net | 1 Comment »
October 22nd, 2008 Rusty
With each preview release of Asp.Net MVC, I’ve had quite a few issues to resolve. Most of these were well documented and I was able to resolve them by reading the release notes and the upgrade instructions. Unfortunately, Beta is a little different.
Blame it on Apple
I’ve been iPhone bound for a while. I skipped Preview 5. I would have caught this issue then and probably avoided the problem that I am currently facing as I believe we wrote most of this code after the Preview 5 drop. Thanks alot, Apple, for making iPhone development so freakin’ cumbersome!
Rendering Partial Views
One of the features of Asp.Net MVC that I absolutely LOVED was the ability to render a user control to a string and then mess with that html. Seriously, that capability was incredibly valuable. Brad Wilson decided to axe it. He had a Microsoft-typical attitude that he should change the code to restrict the consumer into following his pattern for use rather than leaving it open as it was before. Yes, Brad, I am angry with you right now…
Listed incorrectly as an added feature…
- Added support for rendering partial views. You have several options for passing view data to the partial view. The partial view can be rendered by a different view engine than the containing view. Usage is <% Html.RenderPartial(…); %>. This method does not return a string, but instead renders to the TextWriter instance of the underlying response.
Here’s what I had before (yes, I could render partials before):
HtmlContent.AppendLine(
Html.RenderUserControl(
"~/Views/Components/Charts/RatingReturnChart.ascx",
this.ViewData.Model,
new { Weighted = true, CurrentTimePeriod = requestedTimePeriod }
)
);
After the html was rendered, it was passed to another control that accepted a string for "other stuff" that it wasn’t responsible for. There are other ways to solve this problem but this was something that was easy and didn’t violate our desire to keep separate concerns, separate.
Now the damn thing uses the TextWriter attached to the response object. So much for extensibility and object oriented programming. Let’s hardwire into the response object, just like webforms. Nice work, Brad. Love it. Great. Now I have to create a user control and move my page logic into the control because I can’t define my own context and behavior. Just like webforms. Hey, are you going to insert view state and post-back on your next big brain storm? That’ll be swell.
Back to the drawing board
Where did I put that Rails Recipes book?
Posted in Asp.Net, Mvc | 3 Comments »
October 21st, 2008 Rusty
Short and to the point. Either start your application by carefully designing for rotation, or don’t rotate. If you use a UITabBarController, each UIViewController that is associated with a tab will be asked shouldAutorotateToInterfaceOrientation. If any of them return “NO”, then its no. Furthermore, it is next to impossible (as of this writing) to force orientation on a View when navigating from a different View that supports an alternate orientation. For example, if your list navigates to a detail page that supports landscape and then the user navigates up to your list that does not - too bad. To avoid hours and hours of pain and anguish trying to correct for rotation and resizing issues, I have two suggestions: 1) design and test constantly from the very beginning OR 2) Don’t rotate.
In My app, I wanted to show a different view entirely, from my detail view, when the phone was turned to landscape. That should have been really easy, or so I thought. My other Views were not auto-resizing according to the documentation, and no code I could come up with would cause layout to display correctly in all cases, so I was eventually forced to suppress navigation when the landscape view was shown. That should have been really easy, or so I thought. When I rotated with the navigation and tool bar present, everything was displaying perfectly. Unfortunately, navigating to another view resulted in failure to resize and reformat. If I hid the tab bar using hidesBottomBarWhenPushed, returning to portrait caused the view to just vanish. I easily wasted 40 hours on the whole of this problem.
My solution, in the end, was to use a modal view by calling [self presentModalViewController:myViewController animated:YES];. This way, the modal view is shown on top of navigation. I can dismiss this view and everything remains where it should be (actually, it rotates back, but correctly). Now I can display a landscape view without exposing other views to this orientation. Keep in mind that any view associated with a tab on the tab bar can cancel rotation. Therefore, I set a bool to indicate whether the view has focus in viewDidAppear and viewDidDisappear, respectively. Using this bool, I can return YES when not focused assuming the other views prevent navigation back to the view that doesn’t play ball in that aspect.
I am pleased to announce that my app is finally ready for submission and I think its useful and of very high quality. I am not, however, even remotely excited to build another. I am actually looking forward to taking a break from the iPhone platform. I’ll be grateful when Apple brings the sdk up a notch in its quality, consistency and usefulness. The device is completely ground-breaking and a marvel of engineering. The development platform is not
Posted in iPhone SDK | No Comments »
October 21st, 2008 Rusty
I searched quickly for this on Google but like most iPhone resources, nothing turned up. Â Eventually, I did find a place to change it. Â In fact, I found two places - both equally counter-intuitive.
In XCode…Â
You can either select Menu: Â Project > Edit Active Target “your app name”
Or you can right click (ctrl click) on the target beneath the “Targets” node in  your project tree and choose “get info”
From there, click the “build” tab. Â Scroll down to “Packaging”.
Change “Product Name”
Posted in iPhone SDK | No Comments »
October 14th, 2008 Rusty
Atlanta iPhone Developer MeetupMy second (the fourth?) Atlanta iPhone Developer meetup was a success tonight.  Forgive me for forgetting names, I’m getting old. We had an excellent presentation using xml web services to populate a UITableView with search results from Amazon linked to a UIWebView.  I liked how (Brian?)  walked step by step through how the code interacts with the Cocoa framework.  I think he stated it well that you play a game of “Whose in charge?” using View Controllers.  You set up some outlets and actions and then wait for the user to trigger an event that’s tied to an action that you defined.  Once that action is invoked, you have the ball.  ice analogy for IB.Where’s the Documentation? Several people asked me to post some links to a few things I mentioned while stroking my   showing off my app.  While I haven’t done anything profound, I have applied my experience in enterprise development to iPhone app development.  I feel the examples you find today are lacking in strong design fundamentals.  I suppose, in an effort to baseline simple concepts, Apple opted to present the flea’s eye view in order to demonstrate specific solutions to granular problems.  That’s fine but I still want to sprinkle a little awesome in my app.This Again? Common cross cutting concerns: data transfer, persistence, caching, authentication, remoting. OK.  We’ve been here before.  How do we sove these common and prevasive software problems?  One at a time.Data Persistence I have something that I want to save.  What are my options?  I could send it via a web service call to my server, where I have the code that manages such things. or I could store it locally.  I want both.  Locally, I have file system access and SQLite.  I like SQL.  That’s personal but I prefer to stuff text in a DB rather than to file.  I am a big fan of theRepository Pattern.  My repository is going to accomplish both for me.  When I say “load” it will first look for a local copy and then try to update from the server.  Same thing for saving.  Considering that I’m jumping across language and platform boundaries and need to refer to the same data constructs across these disparities, we need something consistent between them.  Xml works but its verbose and tedious.  SOAP killed the internet star so we’re going with JSON.Here’s JSON in a nutshell.If <person><name><first>rusty</first><last>zarse</last></name></person>Then {”person”:{ “name”:{ “first”:”rusty”,”last”:”zarse” } } } Why is this better?  Its shorter (no closing tag, let typing) and its more consistent (should “first” be an attribute or an element? aw bugger)Part of my inspiration for pursuing a JSON solution was my first experience with the iPhone Xml parser.  Its germane and, frankly, annoying.  Here’s how to install JSON for the iPhone. and here’s how to use JSON for the iPhone.Got it, Keep itNow that we’ve retrieved our JSON, let’s cache it to avoid unnecessary or impossible return trips to the server.  I LOVE SQL.  However, I have no desire to write object mapping SQL.  None.  Zero.  EntropyDB sounds nifty!  Note:  (big note) this version doe NOT INSTALL on the iPhone device.  Sorry for the shout but it caused me some lost time.  However, there is a device friendly build of EntropyDB  that does not work in the sim.  Its not in the files section of the Gogle code project and is near impossible to find.  Regardless, the library woks well enough to be worth the trouble of renaming the files to switch from simulator to device.   Entropy will serialize your object and save it to SQLite.  I a not enough of an expert to explain exactly how.  The fact that it’s meeting my business need without worrying out exactly how is testament to why its a valuable utility.  The Google project author indicates he intends to charge a license fee.  Pay it and don’t waste your time writing repetitive SQL unless that’s  fun stuff for you.What , no Code?I prefer code when I read tech blogs.  Sorry.  I’m lazy tonight.  I you would absolutely LOVE some code examples: comment or email me.  I’ll ablige.I’ll post more when I can…  Â
Posted in iPhone SDK | 1 Comment »