Google+ Badge

Tuesday, March 3, 2015

iOS battling 3rd party tools

I have been battling various items in iOS over that past week and it is getting really frustrating.

First up I really wanted a dialog with some text entry and a few buttons. They pulled the "custom view" part out post iOS 6 so I found a few GitHub repositories that should solve the problem. First once just did not pan out and the UIView just did not look right. Second one appeared to work OK at first but then it did not play well in iOS 8 in landscape.

Apple decided to change the way you get back height and width of the screen in iOS 8. Previously you always got height and width as if you were in portrait mode. Now they give it back for the current screen orientation. Huge change for programmers. People had height / width swapping code to handle this and you still have to do that for iOS 7 and older.

I fixed the code so landscape worked for iOS 8 on the simulator. Once I ran it on a real device things went to crap again. Extra things being painted and the keyboard popping up really screwed things. Lesson learned - iOS really does not like this sort of popup with editing.

Gut things yet again and go with a UIPopoverController on the iPad and navigation to a UIViewController on the iPhone. Can't say I am super happy with the iPhone version but it works and popping up the keyboard does not screw anything up.

Next up was the menu. iOS 7 has a bug. If you have too many items in a UIActionSheet on an iPhone you can't tap the top most item if it happens to cover the main navigation area. Works fine on iOS 8 but broken on iOS 7. UIActionSheet expects just a few items.

So I found a popup menu that allows up to 9 items per screen and you can swipe to scroll and see more. It is call btSimplePopUP. Now I should have known that someone using two menus - btSimplePopUp and btSimplePopUP - in the same directory structure was going to be iffy. The demo screens look nice though. I put in the code and I get the menu to appear but with a black background. What? It is not blurring out my UIViews, just blanking them out. Then I look for known issues and it turns out the control does not work in landscape which is a requirement for me.

Punt that control. I am now looking at KxMenu which seems to be working in portrait and landscape and takes up a lot less screen space than UIActionSheet. Hopefully it will be the solution.

Lots of GitHub projects lose support. iOS 8 was a big change and it takes some recoding especially with custom controls due to the changes Apple made. Stinks people don't have the time to keep things updated. Even worse when I waste the time trying to get them to work. I need to start looking at the known issues first. Anytime it does not support landscape I am not going to use it. Hopefully they also list if there is iOS 8 support issues as well.

Tuesday, January 20, 2015

MacOS has lost its stability

I do both iOS and Android development thus I have a MacBook Pro has my main development device. I have had one for the last 3 years. Since upgrading to Yosemite it has become the least stable development box I have worked on in a long time.

I leave the machine on and lock / put it to sleep when I am away from my desk. This may be going to a meeting, going to lunch or home for the evening. When I come back from lunch there is a very good chance, 2 out of 5 days, that the machine has rebooted. This also may happen during the day when I am actively working on the machine but that is pretty rare. The sleep cycle seems to be the main trigger.

This is an upper end machine with an SSD drive so the reboot does not take too long but it does interrupt my day and it may happen a couple of times a day, when I come in, after lunch and then maybe after a meeting. Yes, all the programs restart but they don't show up in the same position or with the same data showing. Sublime text appears on screen 1 instead of screen 2. Finder does not have the same tabs open. Chrome might be annoyed in some manner. I will not have the tabs in iTerm on the same directories.

This was never a problem in the past. The MacBook just worked. Now it reboots and has issues with DNS getting lost part way through the day as well. Ping will not find a machine but NSLookup will.

I also have a Dell PC that is used for my Windows activities running Windows 8.1. I leave Outlook, Hipchat, Sublime Text, Chrome and a few other things running on it as well. I do a lot of my graphics work on that machine because Paint.NET is free and pretty darn full featured. We also use TFS for version control and I do that work on that machine along with anything I need to do in Visual Studio including C#. I don't have a massive love for Windows but at least that machine is only rebooting when it needs to do updates, which does occur too often for an OS, but otherwise it is there ready to go.

iOS has become less stable as well. I think Apple needs to stagger the releases instead of trying to do MacOS, iOS and iOS hardware release all at the same time. I bet their QA department is hammered during that yearly cycle and it is really starting to show. I love new and exciting things but they need to be stable. Right now Yosemite is not stable and is highly annoying.

Tuesday, January 13, 2015

Why I have given up on Interface Builder and Story Boards

I just ran into another case where Interface Builder did not allow me to do what I wanted to do and I finally just gave up and pulled everything but the first view controller from the storyboard. This is the story of how I got to this point.

My first iOS app was one of "finish this". Another developer who was no longer with the company had developed the app. I had the job of finishing the app and converting it to Android. I already knew Java and had written an Android app that was in the store. The iOS version used NIBs as this was back in the iOS 4 timeframe.

I continued down the NIB path and converted the app to be universal with special code for iPad layouts. There was special cases for landscape vs. portrait on one of the screens as well. Seemed to work OK but it was a fairly straightforward app.

I worked only on Android apps for a some time before my next position where I did both iOS and Android work again.

The next iOS app I worked on was written by another developer and he used storyboards. Still using the old style layouts with pixel perfect positioning. I kept the storyboards in place seeing some of the advantages of using them and added the iPad storyboard side of things. I liked how much easier it was to get things going, used segues and like the idea of seeing the program flow in a visual designer. Took quite a bit of web research to understand how it all tied together and a lot of clicking on tabs in IB to find all the secret nooks and crannies where you could set things.

I did a couple of other apps for the company that I got to write from scratch. I used the new found storyboards for them as well. Sadly none of these apps went to market as they never finished the server side of the work. Lots of pretty apps to demo at sales meetings but they were just demos.

For my current job I am again getting to write the app from scratch. I am doing the same with the Android side of things. I started out using storyboards and it was time to get into autolayout. Since I have been doing Android work and I have also done a lot of Java desktop work I have a solid understanding of doing layouts that scale.

I dove into autolayout and found it rather confusing. It appears to me to be written in the land of academia instead of the land of real world programming. One layout to rule them all no matter how you have to force things into it. Very verbose in one code only format and very terse in the other. If you do it in Interface Builder then you just have to know how to do things. Click here, Ctrl + Click here, set up constraints, delete them, set them up again, have them conflict, pull hair. Always something wrong and it get really bad when you have a complex layout. For a company that prides itself in UI and UX I must say IB is not a good reflection of that goal.

After fighting it and working with other iOS devs over chat I found Masonry and switched to that. Yes, it is code and not WYSIWYG but I could create complex layouts and have them work. I could do different layouts for iPad and iPhone and follow them logically. I still have storyboard layouts but most of them were empty as the code created the real layout. I was just using them for segues and to see program flow. That was until yesterday.

There I was back in Interface Builder. I just wanted a UITableView to move down one level, to have another UIView as its parent. IB fought me tooth and nail. I could and a UIView to the list but it would not show up under the UIViewController no matter how I dragged and dropped and clicked. I then said screw it and deleted that entire view controller and created a new one where I could re-add the UITableView but then all my segue links broke and all the IBOutlets into the code broke and I would have to do it again for the iPad storyboard and all the work went on and on. Plus Xcode crashed more than once while I was in it doing simple things.

Storyboards end up sucking pretty quickly. There is not enough screen room to see your iPad layouts. You get to see one scene at a time. Sure you can zoom out but the minute you edit something it zooms back in. Just opening a storyboard seems to trigger Xcode into thinking there was a change. If you look in the XML you will see it changed x = 4.0 to x = 3.999999999 or something just as stupid. Everything I did I had to do twice, once for iPhone and once for iPad. The IDE does not tell you if you forget to wire up a UIView to an IBOutlet. Objective C does not care if you send messages to a nil object. Moving a UIView can screw up the whole layout quickly. You can't see all the constraints in one place, you have to look in each level of the layout to see them and they are terse and unrelated to each other. When you try to Ctrl+Drag a UIView into the code you hardly can see anything else on screen.

I gave up. IB was fighting me not helping me. I converted all the code to Masonry and I was able to control that layout exactly. I had to move all the segue processing in code as well. It took me all day to get my code back to where it was before but now I am in control of all of it.

I don't have to do things twice. iPad and iPhone both work from one code base. I may have some if statements in code to tweak layout for iPad but I don't have to double layout it out in a crappy UI editor called IB and I don't have to double connect every UIView to a IBOutlet.

I can move a control around in my layout by changing a few lines of code instead clicking a bunch of times in IB and having it get pissed and redo other constraints.

I can name my controls so when I do get log messages about my layout being screwy I know exactly which UILabel it is mad about instead of guessing.

Another issue that bit me, I fixed, that bit me again and I fixed the right way arose. I needed a second line for the title area on iPhone. iPad has enough horizontal space to not need this. I was using the navigation prompt property which adds a second line of text to the title area. On Android I could use title / subtitle to do same thing but on Android this requires no extra vertical space.

How did this bite me twice? A number of months ago I wanted to add a UILabel above my UITableView but I could not due to same issues that I just covered, I could not get the UITableView hosted by another UIView. Thus I used the prompt property. It worked OK. After the conversion away from storyboards everything in this UIViewController aligned just fine the first time I displayed it but when I tapped a table row and moved to the detail screen then back to the table screen setting the prompt caused the navigation area to grow and it covered up part of my table. Rotating to landscape and back would fix it. I tried all sorts of relayout, needs display, calculation of offsets etc. and could not get it to work. Why autolayout would not stay in sync is beyond me but I got sick of fighting that.

Then I remembered what I originally wanted to do - put a UILabel above the UITableView on iPhone only. Now I am in control as I am using Masonry. Put the UILabel in place and changed all code references from prompt = to promptLabel.text = and I have a working layout the way I originally wanted.

I have no plans use prompt again due to it screwing up layouts and I will not be using storyboards or Interface Builder either. They just are not stable and cause more trouble than they are worth. I also do most of my work in AppCode instead of Xcode as AppCode does a much better job in a lot of areas. Better editor, much better refactoring, GIT actually works properly and it is stable. I have had it crash on me once in the two plus years I have been using it.

The other added benefit - I can take my code and drop it in another project and it will work. I have no dependencies on copying the layouts twice and having to manually reconnect every single freaking UIView to an IBOutlet. My code is self contained. It lays itself out and knows how to talk to all of its controls.

Goodbye IB and storyboards. I don't miss you.

Friday, August 29, 2014

Switched to autolayout via Masonry

I have known for some time that I needed to start using autolayout for my iOS development. My current app is universal so I was doing things twice already in Interface Builder which was getting to be a real pain. Add the control, drag and drop the IBOutlet connections and don't forget to do it on the other side.

I tried to use autolayout in Interface Builder and finally got my fairly simple login screen to work but I cussed at it the whole time. Move a control, have IB tell you the constraints and form are out of sync, correct it and repeat. If you move a control that was used as a reference anchor for other controls then it got really lost. You end up manually deleting constraints that show up either below the control you are moving or maybe at the root view. Just way to painful and error prone.

Here is where comes into play. I have used a number of layout managers in the past including standard Java layouts, MigLayout for Java and the Android XML layouts. Masonry is similar to each of them in a number of areas.

A new layout with about 35 controls was the tipping point. No way I was going to do that after all the venom I spewed at IB doing the login view with only 7 controls. I got the new layout working pretty quickly in Masonry then I went back and ripped the login from IB and did it in Masonry where I can easily see the exact constraints and view relationships.

I attempting to use the Apple flavor of programmatically doing autolayout but I found it to be very verbose and nearly as confusing as IB. The other shorter syntax messed with my mind also. Masonry seemed to go right down the middle.

Not a huge fan of checking in the code for iPhone vs. iPad but for a universal app where you want special layouts that is what you get to do. Not sure what will happen when the new iPhone 6 comes into play.

I am now skipping story boards and all their headaches and just doing my layouts in code. This also means is a new developer was to come on board we would not be walking on top of each other when we change a layout which stinks with storyboards and version control. That developer would get to learn Masonry but it is reasonable straight forward. I still run into some odd layout issues that send me scrambling to stack overflow but in general it has been pretty smooth.

UIScrollView gave me the most fun but once I figured out how to anchor the scroll view to the main view then anchor child views of the scroll view to the scroll view it all worked out.

The error messages given by autolayout are not super helpful. Some trial and error is involved but I don't run into errors very often anymore.

Monday, July 14, 2014

When do you learn a new library?

When do you take the time to learn a new library? I decided now was as good a time as any since I was at a new job and working on a new application. In the past I have used straight JSON parsing and hand written HTTP code. This time I decide to see what RestKit had to offer for both areas and I am happy I did that.

It can be very hard to retrofit a new library into old code. The design most likely does not follow the new pattern. No one wants to start from scratch when an existing product is already working. Kind of a shame because a lot of the time doing that can really make things work a lot better and make it easier to catch odd exceptions.

Per usual I got the Android side up and running pretty quickly. I did use the GSON library, which I have used in the past, but I used it in a deeper way. I set up the objects with the correct annotations and I let the library create my objects from the HTML body of the response. Worked like a champ. I implemented loaders to pull in the data and images for everything to happen on a background thread.

Next up was the iOS version. I found a lot of RestKit information on the web so I figured I would give it a shot. Not only does it handle the HTML / JSON request / responses but it also deals with JSON to object mapping. It took a bit more work to get that going though. You have to return object mappings instead of doing simple annotations. Once I had it figured out it worked very well. Some trial and error as I made the request over and over to the server to see what else I screwed up in the mapping. The JSON objects I am parsing go 6 levels deep. I did not write the server side so I am not in control of that aspect.

The image side was a different story at least when it comes to requesting a lot of images via queue in a background thread. There is a lot of documentation about the older .10 version of RestKit but less for the newer .20 code base. I fumbled around with things for a bit then found the SDWebImage library which did exactly what I needed in very few lines of code.

I am using CocoaPods for all my iOS work along with AppCode for the IDE. Yes, I have to switch back to Xcode from time to time as I can't find ways of doing things such as adding a Font to the project. This is not a super straight forward thing in Xcode either. I really want AppCode to do everything. I have been doing my Storyboard work in AppCode. Took a little bit of time to figure out where to drag from to get the IBOutlet connections to work. Xcode is confusing in this area too, nothing leads you down the path, you need to know to hold down the right keys and drag things and drop them on the right area. They improved this with Xcode 5 where you drop directly in the code but boy does the screen get cluttered when you try and have an iPad Storyboard open with code too.

Working with iPad Storyboards is a pain in both products. The screens are big and even though I am running the IDE on a 24" monitor there still is not enough space. I guess I need to have the IDE span both of my monitors as anytime you need to set up a segue between two screens you just don't have the space to do it. Even running the simulator on a 24" monitor for an iPad Retina at 50% leaves scrollbars in place. This outright sucks. I use GenyMotion for my Android work and I am able to easily scale that window to fit on screen.

Tuesday, June 10, 2014

Back to mobile dev

While my stint doing AngularJS work was interesting I am back into full time mobile work. Man I missed it and I am happy to be back into it.

Of course you are always surprised about how much you forget when you spend time away from something. I get to do both iOS and Android again. I started on the Android side first as I have always been more comfortable in Java than Objective C. I have the main login, logout and initial REST calls working under Android. Today I was working from home on the MacBook so I started to tackle the iOS side of things.

First I wanted to make sure I did autolayout from the start. Apple is pushing it and there are signs that Apple will release a different sized phone and maybe side by side program running on iPads. This means your code should be able to run as resolution independent as possible. Something you do almost by default on Android.

Autolayout is a bit weird but I got the login screen to work without any code for both portrait and landscape in the iPad storyboard. I started experimenting with AppCode 3.0 but ran into issues just getting my images into the xcassets area so I switched back to Xcode for this round of fun. I will switch back to AppCode once the UI is in place and I am doing gut level coding.

I had to create the various icons and launch screen images. I had large sized assets so I used Seashore for simple scaling. It annoys me that Mac OS does not bring an app to the front when you hover over it like Windows does. I wanted to DnD the images from Finder to Xcode. Luckily I am running a dual screen setup so I just moved Finder to the other screen and did it that way.

I copied over some other code and utility files I use and got the basics of the login screen in place. Now I get to decide which JSON library to use. I might just go with NSJSONSerialization this round. I have used YAJL in the past but I did that because I needed to stream things as the data was too big to hold in memory multiple times. Right now I do have that issue. I did not need to stream on the Android side, I am using GSON over there. I do like GSON parsing right into my natural object format where NSJSONSerialization just does a generic dictionary. Makes method name traversal impossible. The objects are rather deep for the JSON I am getting back so I need to find a decent way to get to the info I need. All the REST calls are done via C# and IIS so none of it is really optimized for Java or Objective C consumption but it is JSON which I find easier to deal with than XML.

I will need to all pull to refresh and navigation menu support too. Guess I need to get my head back into Objective C and review the list of CocoaPods I used in the past.

Since all the news about Swift as been in the news as of late I have started to sniff around. To me it looks like a nice step in new direction. I like they syntax having never been a big fan of [ ] []]]]]] [[[][][]]] all over in Objective C. Swift looks JavaScript like. Don't think I care for the .. vs. ... for the loop construct where on does inclusive start / end index and the other does start / end - 1. I would rather have a more distinct syntax between the two.

Sadly I don't have current access to Xcode 6 so I am not playing with that. From what I have read neither Swift nor Xcode 6 is ready for primetime meaning it is best for me to concentrate on the old Objective C via Xcode 5 and AppCode for now. Documentation is also sparse. I hope they hammer out the issues quickly as I would like to move away from Objective C sooner than later.

I have picked up a lot of info on the Android side again too. I have done JSON work there before but again I forgot a bunch of it having not messed with it in nearly a year. Good thing Google works most days. 

Wednesday, April 30, 2014

Living in AngularJS for a few months

What is it like for a Java / Objective C / Mobile guy to live in Angular for a few months? It has been an interesting ride for sure.

The mobile work, which I dearly miss, is at a stand still while marketing decides on various issues such as it being free or having a price. This means I need to help out in other coding areas and for right now. They decided to toss me into AngularJS.

It takes some time to get your head wrapped around Angular. What is a service, controller, directive or manager? How does this magical binding work? Where is the GET call for the REST service?

I was using the 30 day trial of WebStorm as that seemed to be the tool of choice for every video I watched doing a demo of Angular code. I like the IntelliJ product line. I use AppCode for iOS work and Android Studio for by Android projects. We get a multiple user site license of IntelliJ which includes the WebStorm plug-ins so I switched to that. WebStorm 8.0 EAP has better Angular integration which will be merged into IntelliJ at some point. For my personal use I am waiting on the next IntelliJ sale to pick up a copy for home use.

Using IntelliJ allows me to run our Java based application server too. That code is a Maven project making it easy to import as an IntelliJ project. Nice having one IDE for both of those projects and I especially like the Dracula theme. I run a dark theme in Eclipse but it has some minor UI issues.

IntelliJ ties in to our JSHint settings as well. The Jenkins integrated build system will kick out the project as failing to build if you don't follow our JSHint settings. Having the IDE show them to you as errors before you run the GRUNT process is very nice.

Using GRUNT SERVE allows me to start the web process and then have any changes I make to the HTML, CSS, SCSS or JS files automatically built and pushed out to the web. I am using Chrome which also integrates with IntelliJ for JavaScript debugging. I also use the integrated Chrome web developer tools but the IntelliJ debugger is more feature rich to track down the harder issues.

I run GRUNT before I set up a STASH pull request. That runs JSHint, Unit Tests, Minification and all the other fun which is the same process Jenkins runs. I try to always check in clean code.

How is Angular? It appears to be a really solid API with a lot of helpful features. The live data binding is one of them. You set up {{ variable_name }} in the HTML and if that variable is defined in the controller the HTML will automatically update when you change the variable value in your JavaScript. There is also all sorts of boolean logic you can apply to show and hide HTML elements using ng-??? tags.

Angular is like Android in a number of ways. You need to understand 3 or 4 objects before any one thing works. In Android you would need to know the Activity houses a Fragment and they are both using a layout defined in XML that pulls data from strings.xml and the List in the Fragment is using another java class that uses one or more other XML layouts to display the data. Very confusing at first. Angular has a similar tie in of controllers, HTML layouts, CSS styles, etc.

I did not write the initial version of the Angular app. I got to wade into the deep end with a list of bugs and feature requests to see how much damage I could do. Took a few weeks to start knowing where to look and the initial project did not follow the best file naming conventions, which has since been cleaned up.

Now I have a pretty good idea of what is possible, what bootstrap widgets are available, how to look up and use underscore.js helper methods, available moment.js methods and how to get around the other 3rd party code bits we pull in via BOWER.

Of course general programming knowledge always applies. There are loops and IF statements and all that fun. It was basically learning a new framework. The fun comes in when you get to test in various browsers. So far the Angular side has not caused any issues but HTML and CSS play a different ballgame. I am on a Mac as I do iOS programming. Things were working fine in Chrome, where I spend most of my time. The UXD staff uses FireFox and ran into various minor issues that I was able to quickly fix. I also test in Safari and have not had to do anything special in there yet.

The real fun begins in Internet Explorer. I have a VM set up with Windows 7. Things were not looking so good in there. Turns out we have some bad HTML which the other browsers ignored. Specifically an extra end tag of
. IE gave me a non-helpful error message deep in the bowls of Angular for that. The other browsers just blew it off. Simple fix. The other changes were setting some bonus CSS styles for the modals - commonly called dialogs in other frameworks. All the changes I made did not affect the other browsers so I was not required to put IF statements around them just for IE.
I went ahead and set up a pretty full environment in the Windows VM which included GIT, GRUNT, Ruby, BOWER, NPM, Node.JS and Sublime text editor. I did not set up IntelliJ on that side as I would have to kill it on the Mac side and start it on the PC side each time. I am generally making small changes for IE so that has not been a big deal.

The web tools in IE are not as full featured as FireFox or Chrome but are servicable. I was able to change CSS styles live and see the effects which is very happy. CSS seems to be a lot of trial and error to get things right. Not a big fan of that mode of development. When I see something out of place in my Android layout XML I generally know why it is messed up and I can quickly fix it. With CSS the whole team plays the "throw stuff at it until it works" approach. Try setting margin, now set DIV to overflow = auto; or toss in a float: left. When it works I am happy but I always want to know why that made it work. Plus the CSS has a lot of inheritance which is not obvious when the styles are defined in multiple CSS or SCSS files. At least the web tools in the browsers will show you where various things came from and what overrides what.

We plan on turning most of the HTML and CSS manipulation over to the CSS team. I believe they will do a better job laying things out in the CSS files getting more object reuse there and they can keep track of how changes will affect various areas on different screens. They won't touch the binding areas or the i18n areas.

Like most of the projects I have worked on we have done the i18n work and have had the project localized into Spanish and Korean. A member of the sales staff plans on doing a French localization for us when the code is closer to complete. I always put strings into separate resources just in case someone wants to localize the product.

For QA to test this we generally hijack a rarely used locale and do a simple reverse English version of our test. That way QA can quickly see on any screen if the text is not reversed then we have not pulling it from the resource but they can still read everything on screen. Reading backwards is tricky but sure is a lot easier than guessing at a language you don't know at all.

I wrote a small Java utility to reverse the strings for this file. Big deal right? Reverse a string, grade school 101 that task. The issue is you don't want to reverse macro replacement text. The string "You have {{carrot_count}} carrots\nBuy more!" is reversed to "!erom yuB\nstorrac {{carrot_count}} evah uoY".  Don't want \n to be n\ and the variable name cannot change.

In the end I am not minding my time in Angular but would really like to get back into mobile. Anytime you learn a new framework it opens your toolbox even if it to steal ideas on how to do things differently in your "old language and framework". The Angular app is not large but it looks good and is very functional. It beats the heck out of the previous JQuery app I helped out on.

What don't I care for? JavaScript is not statically typed so a number of programming errors don't appear until you run the project in a browser. IntelliJ does its best to keep you honest but it can't catch everything. Misspelling a variable in HTML that is bound to a JSON field will burn you more than once. Dynamic variables of this type, that type, array or not at different times will also burn you. It also causes havoc with the intellisense / autocomplete features of the IDE. You end up keeping multiple files open just so you can reference variable names. Refactoring is a lot tougher too.

The worst part is browser differences. Sure, in Android land you deal with different SDK versions and screen sizes. Under iOS you have a couple of different screen sizes and some hardware differences. Here I sit on a single computer and I have to test in 4 browsers minimum. It appears IE is the pickiest of the bunch so I should start in there but it has the least useful web tools and I would be working in the Windows VM all day long which does not add to the fun factor.

Like every new program language and framework it has been an experience. Some good, some bad, some fascinating. I will steal as many ideas as possible from this experience when I get back into mobile land.