Wednesday, June 22, 2011

More Interface Builder fun

I installed my app on an iPhone for QA. In the appointment list view I had moved the toolbar to the bottom of the screen to put it in the proper iOS location and to avoid the mis-taps that happen all the time on the phone causing the "back" button in the navigation area to be accidentally pressed. The Tap zones on my rev 4 iTouch seem to suck and there are know issues with clicking anywhere near a button on a navigation bar triggering a hit.

The QA person had a large list of appointments. When you drag scroll you can get the bottom one to appear as you can overscroll, handy feature on most mobile devices. Of course when it settles back down the last appointment was under the toolbar. Here IB bit me in the ass yet again. Clearly the toolbar is there in IB and clearly the scrolling table is above it but once the code runs all bets are off. Apple seems to feel if you have a scrolling view on the screen then it should own the whole screen all other widgets be damned. I had to fix this issue with the table painting under the navigation bar by adjusting the table view content inset at load time and during interface rotation changes. So I adjust it now for the toolbar too.

After talking to QA this is not a rare issue. He has a number of iPhone apps that don't take this into account so sometimes he has to overscroll then tap really quickly on the last item in the list. That is crappy UI. It is a crappy UI that occurs much to often because the crappy tool you use to build you crappy app makes it look like it will be fine when it is actually screwed at run time.

Every time I see a comment or article on how wonderful all iOS apps are and how awesome the tools are that let you create them I just want to scream! This stuff needs a ton of improvement.

Tuesday, June 21, 2011

Interface Builder how I hate you

I hate Interface Builder. I hate the way iOS deals with layouts. I must be doing something wrong, if you have any suggestions I am totally open to them.

Here is the stupid layout for a simple enter the patient name view controller.

Last   [              ]
First  [              ]
Middle [              ]

That is it, three stupid labels and three stupid text fields. I want them to show up in both portrait and landscape mode with room for the keyboard to appear without overlaying them.

First off I drop the fields on the View align them to the top of the view. Run the code and guess what? Last is under the damn navigation bar. Why does this happen? Why are the controls not automatically moved down? What the hell am I missing in IB? I don't even know what to search on in Google to find out and I have tried. If you turn on a navigation bar in IB is just shows how much screen spaces it uses but it does not affect the way it operates when you run the program. That is not what I expect from the self appointed Gods of UI at Apple. I tried all kinds of autosizing anchoring and most made it way worse, moving the controls as I rotated so they overlapped each other.

So I move all the stupid controls down in IB and get them to show up in the running program. Then I rotate to landscape and guess what? It looks like crap again. You can't design for both portrait and landscape in IB, pick one ONLY. Everything else you have to do in code unless you want to double the fun in IB and then double all your connections in the code and double the reason you want to fly out to California and start smacking people for having such a crappy way of doing this.

Your other choice, and the one I took as I have had to do this is other areas of the code already, is to manually move controls on orientation changed notification. What a massive waste of code and time. I hardcoded, as that seems to be the Apple way again, the move value. Since the navigation bar is 44 pixels high in portrait and 32 high in landscape I move everything 12 pixels. What if Apple were to change this size? A lot of broken code that is what would happen.

I added the waste of variables, 6 floats in all, to the controller to remember the Y position of each widget during initial view load. I adjust all the controls when the view appears  as could appear in the seemingly evil landscape mode of course and when it rotates. It all works now, things appear just below the navigation bar and just above the keyboard in both modes. The text entry fields expand to fit the width.

Really people, this is so easy to do on the Android. I don't go through this hell when I do portrait and landscape. I don't have to make stupid adjustments to account for a navigation bar or to write a bunch of worthless code. What if I had 12 controls?

The Android layout manager GUI editor is not as slick as IB, really pretty barren, and I have to tweak the XML but it works in both portrait and landscape and it does not screw me over when I have a navigation bar.  Controls can be relative to other controls so moving one can move a whole group. If I want to make portrait look different from the landscape I just do a second XML file with the landscape suffix using same IDs and the OS deals with it. I don't have to manually code the crap out of all of it. I can rotate in the ever improving GUI editor to see how it looks. If I need to use another language things can flow to match the new text.

IB needs to take the navigation control into account. IB needs to allow you to create both portrait and landscape layouts without doing double connection work. IB needs an overhaul, it is not friendly to use, it is not obvious what to do, it has a crappy user interface. It does not open the correct associated file when you want to drag and drop connections. It fights me constantly. I hate to create a new view controller as I know the next part of my day is going to suck.

I am ready to drop kick IB to the curb. I know many iOS developers have already done that. Creating and positioning everything in code, which I am half doing already, is as old school as you can get. Really, that is the solution from the "Graphics and UI masters" of Apple? I have not started on the iPad side of things yet but I am guessing is a new nightmare ready to scare me right back into Linux / PC and the Android. The Doctors want this running on the iPhone but I have to say I can not recommend the iPhone to anyone for use or coding after all the hell I have dealt with on it. The Android side is so much cleaner and easier to do in my coding opinion.

If you have not coded on both then please don't tell me I just don't get it. If you know how to make IB in the list bit usable I beg you to post a comment or a link to a site that covers how to make it work. If you have given up on IB tell me how wonderful life can be without it shackles.

Tuesday, June 7, 2011

Programming solo on a development team is not easy

How do you code solo on a development team? If you are the only one who knows a technology and believe me it is not easy for necessarily fun. We have 5 developers on staff, one being the boss so he is also in meetings and what not. He takes care of various pieces of the infrastructure, a lot of the Jasper reports, database stuff and some Java coding. Two others do a lot of the Ruby on Rails work, DB work and some Java programming. The other guy does Java and a bit on the server side. For the first few months I was doing Java work on the Front end and a bit of Android work.

Now I am the one and only person that knows anything about iOS (which I learned on the job) to clean up the existing iOS app and to write the new one. I also wrote the Android port of the original iOS code. Others can help on the Android side and I can bounce ideas off them them as it is Java based. They can also do code reviews. My boss has written and published an app on the Android market outside of work as have I.

On the iOS side of things it is just me. No one can answer any iOS development questions, review my code or give ideas on how to make things look good on a small device. I can check stuff in that does not build and no one will notice. There are no checks and balances. I have a feeling this is a bit what it is like to work from home each day although even then you might have others in the company to look over your code and give suggestions.

It is getting to be a large chunk of code too. Over 500k of source code for a measly dozen screens most of them being some sort of table leading you to detail screen or to a data picker. There are also 17 SQLite tables with all the support code that goes along with that.

Before I began work here I had done a lot of work in C, C++, Java and C# with the most recent stuff in Java. I had not done any real SQL work and in fact got turned down for jobs because of that. For the small DB work I am doing it was really easy to pick up SQL. I am not dealing with stored procedures or a myriad of joins so I would in no way consider myself any sort of expert.

On the iOS side I have never owned a Mac or programmed in Objective C. It is a mix of C/C++ and Java so I was able to apply that knowledge to the task at and. I am not a big fan of Objective C or Xcode but it is serviceable. Someone needed to learn it and I volunteered for the task so here I sit. I have used a Mac before as I was the one at the previous jot to make sure all the Java code worked properly on the Mac.

I have never worked someplace where I was the only one that knew an isolate specific thing. Sure I have been the go to guy for an area of the code but it has always been in a language that others know. I was the TIFF and other image format guy at my last job but it was still just Java.

My wife and kids don't program so I can't go home and talk to them about it and now I sit at work and don't really have anyone to discuss my issues with either. Sure, I talk about the problems I am having but I just get blank stares. There is team interaction as I consume the data generated from the DB by the Ruby guys. We can talk XML format and all of that but I share no code with them. Objective C is a totally different world. I can't share any of the existing Java code. When I worked on the Android side I could share a lot of code making things go so much faster. Now it is all written from scratch and even though Objective C base language is just as terse as C the iOS API is not. I have manually converted a lot of Java code to Objective C.

Auto complete helps in Objective C but if you scroll though a file you will find it very dense. Parameters are named but without the big benefit of being able to put them in any order, default them or skip any you don't need. Easy to tell what you are passing but there is a lot of text. All strings start with @ which stinks. If that is the normal and not the exception then you should not have to type it over and over. This is a preprocessor for C thus it acts like a tacked on language syntax at times.

Programming for mobile devices is another difference. On a PC/Mac you tend to have a lot of pixels. Even if you code for 1024x768 you have a lot of room. Plus mice are pretty accurate where fingers are not. You need to leave big touch zones. Adding to the fun is lack of the standard 4 buttons found on the bottom of any Android device. Instead you have to add Menu, Back, Search support elsewhere in the interface. Home is there as the one big button you get on the iPhone. You have to break your UI into small chunks. Entering a date involves a full screen whereas on a PC you might have 10 dates on one screen in comboboxes.

You also deal with screen orientation changes. The Android side is easier here, design one screen in portrait and another in landscape, the system auto picks up the right one. Under Interface Builder you are really given no help. You can design two screens but you have to manually tie everything back into the code and swap views or skip IB move it all around in the code. Neither way is very friendly. UI items change size between the orientations too, the navigation bar is small as is any menu you may have added to the bottom of the screen. I forget to test landscape when running in the simulator, simple key combination to check, but then I realize I hosed something up when I hook up the device as it is easy and natural to rotate that.

This brings up the QA side of things. I have to get the code to them on a device and they need to check everything out in each orientation along with changing from one to the other and switching back and forth between screens. This is the type of thing you don't think about on the PC. We also have to worry about loss of connectivity. People on a PC tend to not lose the network connection unless something really bad happened. Laptops are a little more prone to a wireless loss but they still sit in place most of the time. I am working with Doctors who roam various facilities. I don't need an always on connection but I do need to communicate with the server from time to time.

I am writing so much code just to get the basics in place I am not doing a lot of testing. We are going to hit up QA and there are going to get a pile of new functionality all at once. This has not been an iterative process. With the Java code it is built as it is checked in. They can take a stable version at any time and test things. Can't do that with iOS due to many annoying limitations. First, you have to have a Mac. Our Java stuff builds under Linux and we run it on PCs, Macs and Linux machines. iOS apps have to be built on a Mac, the Mac has to have a developer license from Apple, and it can only be run on a device that has been provisioned for the developers license.

We can build the Android app with a developer license we create and it can be installed on any device via a command line tool to install the APK if you are USB connected to your PC, Mac or Linux box. I can also have any user run the emulator and play with the product without an actual device.

We only have one other Mac in house over in QA. I have to do all building, provisioning and installing. That is a waste of my time. The Apple way is just not developer or QA friendly. It really hurts us on the Sales demo side too. Much easier to send out a quick patch for the Android to a sales guy in the field. Nearly impossible to do on the iOS side. Plus we can never publish an actually release date for the iOS as we are at the mercy of Apple even though our program requires a login to our servers so it is stupid to have it in the App Store but the ad hoc distribution plan is not feasible. We are going Android on the demo and sales side to avoid the Apple hassles.

This covers a lot of ground but hardly touched the solo developer side. At times it is depressing. Working in a cave and doing a lot of Stack Overflow searching to get answers to questions. Writing reams and reams of code that only gets tested after months of work instead of weekly or at times daily. Needed to stop what I am doing to install the new build on a device and hoping when they drop by that I have a build that is currently stable enough to install. Not having people to bounce coding ideas off of means a lot of time under the headphones with my head in my hands. I am so ready to be back on the Android side where I can have people look at my code and tell me where I did something stupid.

I hope we are able to add another staff member at some point that can help on both sides of mobile development. I would really like someone to look over my code and find areas where I cheated or really screwed up. I can take the criticism and would feel much better with a second set of eyes on it and for someone to make sure what I am checking in builds on another system.

Thursday, June 2, 2011

When is an enum not an enum? When you use Objective C!

I have been using enums in my Objective C code and they are starting to bite me in the behind. The issue? They are not unique, they really just go up in a big global named item pool. I had two classes (or interfaces as they are misnamed in this stupid language) both had enums and each had a enum value named "Text". Not a big deal in Java as you prefix the enum you want with its name when you use it. No way to do that in Objective C. They don't support namespaces for anything so I guess it should not be a surprise it is not supported for enums either.

I really did not notice this until I needed to include both interface header files in another interface. Then it got annoyed that I redefined "Text". I see others that use enums prefix every freaking enum with the enum name. What is the point of the enum name at this point? What a waste and gives long and stupid looking enums but I guess you want to use the "convenience" of an enum in Objective C that is really the only way to do it otherwise you will be bite over and over. Hate to think what happens if some 3rd party software does not do this.

Please don't give me the "just follow the language standards and shut up" argument. This is crappy compiler design. I will follow the standards to get around something the compile should handle for me but arguing that I am the one at fault is crap.

The more I work with Objective C the more I understand why it has not been ported to other environments. It is not a modern language. You have to use it on the Mac. It was written as a C preprocessor, not as a full language, and it has been tacked on to since then. Learning to get around its lousy limitations is not making my job fun. PC folks steal everything, good or bad, but they have not bothered to steal this language and I totally understand why. It does allow the Mac crowd to feel more unique.

I am also sick of the "iOS is harder to write so we have better developers, anyone can write on the Android and it shows" line of poop. You should not have to fight the compiler to write code ever. Fighting Objective C does not make me a better programmer, it makes me a bitter programmer and a hell of a lot less productive. I am learning to get around the issues and I try to not make the same mistake twice but I still cuss at the stupid thing for making me write too many lines of ugly code.

Wednesday, June 1, 2011

How does cached XIB files in the simulator make any sense?

I just got done with another major iOS development frustration. The iOS Simulator caches XIB files. When I am writing code I expect a Clean and Build to actually mean something. But it does not for iOS and it really pissed me off this morning.

I got sick of trying to get a layout to look correct using IB. IB sucks. IB does not help you with a portrait and landscape layout. IB gets in the way a lot. People on the web recommend throwing it out the window and just doing what you need in code. So I did that. I deleted the XIB file from the project and I did it all in code and it appeared to work like a champ. Today I added a background image to the view in question and I found I needed to change the label text color to show up. I change it and nothing happens. WTF? I do a search on Google and find out that the stupid simulator caches stuff and you have to gut it to make it stop.

This is MY code and I have to gut the simulator, which guts out all my test images and my whole database so I can see the code I wrote that I did a clean and build actually run - you have got to be kidding me! But you are not and this is acceptable behavior of an IDE and simulator? Not in my book. Damn Apple how many more times do you have to royally piss me off? I will be so happy to get this product done so I can work on the Android port.

I gut the simulator then the program does not run at all because of another deleted XIB file. I found no references to it, deleted it, ran fine, committed the delete action and thought the world was good. But this is an Apple world full of stupid crap. I had to recover the file from SVN today so I could get things to work again. At least the second area where I am doing code only and no XIB is working now too.

Give me one good reason why the code I just cleaned and built is not the code that actually runs in the simulator. Am I going to have to totally reset my iTouch back to factory settings every time I delete an XIB file?

I also found out I had to uninstall the app on both the iTouches to get it to stop using the XIB file. That is some extra stupid there.