With various upgrades and new hardware in the house only one machine was left running Vista, my wife's Gateway laptop. It has a 1920x1200 screen that she runs at a different DPI to read it easier. Once you do that Chrome screws up and you can't use the upper right button to minimize, maximize or close it. Vista was also having some other issues and since it was the only copy running in the house I decided it was time for it to go.
I had a buddy with exact same hardware do the upgrade and it went smoothly for him. I had a Win7 Ultimate DVD from a MS one day conference so there was no cash outlay. Just to be safe I used my Win7 Ultimate 64bit DVD hoping the key from MS would work. The MS conference DVD just listed 32bit but this was running 64bit Vista and I sure as heck did not want to downgrade that.
Put in the DVD and started the upgrade process around 2 PM. It got down around 7 PM. Really? Why the heck did an upgrade take that long? I really have no idea. It had 6 steps to the process and various steps would get stuck at 20% or some other percentage for over 30 minutes. I just left it alone checking on it every so often and finally the percentage would move. I thought that would only happen during one of the steps but it happened over and over. Plenty of space on the HD and this is not a slow machine but it really drug out the process.
Once that was all done I had to grab some patches off the web and reinstall the video driver with a couple of reboots to make sure it was all happy. Running like a champ and she likes the enhancements offered by Win7. Chrome works, you can right click on task bar items such as Word to see and open recent files, task bar is cleaner, easy to move items between monitors, shake to minimize all others, etc. Plus it is much easier for me to do phone support if every computer in house on same OS. Only the file / print server is on XP. I feel no real need to upgrade that box right away although I do feel the printer / fax / scanner support under XP for the Canon printer we have is a big buggy.
If I would have known it was going to take that long I would have started it earlier in the day. I was worried the upgrade would screw up so I have been putting this off. With a friend pulling it off on same hardware I felt better but I was also using a MS key from a slightly different OS, 32 vs. 64 bit, but all accounts on web said this would work. I did not want to lose any of her existing programs - Quicken, MS Office 2010 and others as she uses it on a daily basis. Anytime you upgrade someone else you want it to go perfect otherwise you hear about it for days. Doing your own hardware is not so bad, you can put up with a lot, but dealing with others is a bear.
Feels good to have this off the books. Nice way to end the weekend and she is happy. I also took some weekend time to rip more of my CD collection to give me some variety of tunes at work. I listen to a lot of older music (80s, 90s) and I have it all on legal CDs that just sit in a cabinet. Good to be able to hear the old hair metal at work. Listening to "The Dark Saga" from Iced Earth right now. My son wanted to try some other songs out too and along the line we lost some stuff I ripped a number of years ago. He wanted Adam Ant back in his play list. I will have to listen to that today too. Good stuff.
Monday, January 30, 2012
Thursday, January 26, 2012
Bigger dual monitors = productivity gain
Pretty much any programming shop you know will have dual screen monitors for their developers. There are a bunch of posts and studies about the potential productivity gains. I have been running dual 20" monitors at various jobs for a number of years. I have a 21" monitor and a 17" at home.
Generally when gaming at home I don't use the second monitor but maybe I need to get some work done but I want to monitor a football game. I can leave it running via a web page on the second screen or I will have the browser there with Java Doc for my current coding project. They gave away some older 17" LCD monitors at work so I grabbed a couple of them a few months back. I hooked one up to my wife's laptop and she can't believe how usable it has become. She does a lot of Excel / Word / Browser work.
I gave one to each of my sons. The one in high school uses his to keep the homework assignment up while working in Word. Much easier to keep track of all the requirements for the paper when you don't have to toggle between windows.
My other son has his hooked up to his laptop in mirrored mode. This allows his tutor to monitor what he is doing without hovering over his shoulder. All of them getting plenty of use and in a variety of methods.
Great, you love dual monitors but what is the deal with bigger ones? Generally bigger is better, up to a point at least and that is also the case for monitors. Just going bigger without the up in resolution would not have mattered. We needed some monitors for our medical coding department. We figured we could give them our existing monitors and we could get the upgrade. Just like it works at home where my old machines filter down to family members when I upgrade.
None of us wanted to lose vertical resolution. We were running 1600x1200. If you go 23" you end up losing vertical as most are 1080 for that dimension. Once you get used to see X number of lines of code you don't want to give it up. Almost all monitors are widescreen now. The new ones are 1920x1200. Bonus extra width, same height in pixels. My boss is thinking of just using one as they are so wide. I am running dual and loving it. The extra width means I was willing to split PSPad and Chrome on one screen and Eclipse and Explorer++ and other apps on the other. I can still see the same amount to code but I don't have to toggle between windows.
I keep all my random thoughts on program ideas, to do list, etc. in various tabs of PSPad. I copy things from the web into there and into Eclipse all the time. Now I feel I have the screen space to keep everything on screen and open. That is a productivity gain.
The new monitors also have better color making my graphics artist work easier too. Newer tech, not the newest as these are still the value line Dell monitors but better than the old ones for sure.
If you develop and you don't have dual monitors you are really missing out. If you do have dual monitors and have been running 20" for a long time then at step up to 24" may well be worth your time.
Generally when gaming at home I don't use the second monitor but maybe I need to get some work done but I want to monitor a football game. I can leave it running via a web page on the second screen or I will have the browser there with Java Doc for my current coding project. They gave away some older 17" LCD monitors at work so I grabbed a couple of them a few months back. I hooked one up to my wife's laptop and she can't believe how usable it has become. She does a lot of Excel / Word / Browser work.
I gave one to each of my sons. The one in high school uses his to keep the homework assignment up while working in Word. Much easier to keep track of all the requirements for the paper when you don't have to toggle between windows.
My other son has his hooked up to his laptop in mirrored mode. This allows his tutor to monitor what he is doing without hovering over his shoulder. All of them getting plenty of use and in a variety of methods.
Great, you love dual monitors but what is the deal with bigger ones? Generally bigger is better, up to a point at least and that is also the case for monitors. Just going bigger without the up in resolution would not have mattered. We needed some monitors for our medical coding department. We figured we could give them our existing monitors and we could get the upgrade. Just like it works at home where my old machines filter down to family members when I upgrade.
None of us wanted to lose vertical resolution. We were running 1600x1200. If you go 23" you end up losing vertical as most are 1080 for that dimension. Once you get used to see X number of lines of code you don't want to give it up. Almost all monitors are widescreen now. The new ones are 1920x1200. Bonus extra width, same height in pixels. My boss is thinking of just using one as they are so wide. I am running dual and loving it. The extra width means I was willing to split PSPad and Chrome on one screen and Eclipse and Explorer++ and other apps on the other. I can still see the same amount to code but I don't have to toggle between windows.
I keep all my random thoughts on program ideas, to do list, etc. in various tabs of PSPad. I copy things from the web into there and into Eclipse all the time. Now I feel I have the screen space to keep everything on screen and open. That is a productivity gain.
The new monitors also have better color making my graphics artist work easier too. Newer tech, not the newest as these are still the value line Dell monitors but better than the old ones for sure.
If you develop and you don't have dual monitors you are really missing out. If you do have dual monitors and have been running 20" for a long time then at step up to 24" may well be worth your time.
App released for App Store
It took 13 days to get the app released to that Apple App Store this time. I sent them a note yesterday as I was worried about the "review requires additional time" status. From what I could tell on the web this can be a death knell. It appears to mean Apple does not like something and wants to really review it to see if you are breaking any rules.
I sent them a note explaining we just send the data back to our server for it to be processed by the back office staff. Everything is pretty darn tame. I research everything to make sure I am not using a private API, all the graphics are legal, tool bars are in the correct place, back button works like it should, etc. We do store a lot of data on the phone due to CPT, ASA and Diagnosis codes for quick look up later. I wrote my own pop-up menu system that works on both iPhone and iPad to mimic the one I use on the Android but that is just a custom control. I explained all that in my note and it appears to have worked.
I have a couple of guesses. One they might have accidentally put it in the wrong status. I am sure this is easy enough to do especially if you are just choosing from a combobox. Second they could have been worried we were making money with the app by sending claims directly to insurance and they wanted a 30% cut of that. This app is just a simple tool to get data to the back office for processing. It saves the anesthesiologist time and money by not needing to drive back to the office to drop off paperwork.
In the end it is released and ready for our clients. We will be calling them today just in case they don't notice an update is available via the OTA process. I hope to hear some good news from them as I believe I have fixed all known issues at this time.
Previously it was released in a more timely manner: 5 days, 2 days, 2 days and 13 days for this round. Being in release limbo sucks.
Monday, January 23, 2012
Why you don't get crash reports from Apple
I thought our little app was doing great, never a single crash report but then clients said they are crashing it. So what is the deal? Turns out to get a crash report the end user MUST connect their phone to iTunes and OK the submission of crash reports. Our clients are Doctors, they never connect their phone. They use it for scheduling etc. as a smart phone. We will never see a crash report from them.
I looked in the logs and I see they are running iOS 4.1. Yep pretty old but since Apple did not support OTA (over the air just in case you don't know) OS updates they never update their phone. Now 5.0x is not all that great on old phones, they run pretty slow with it, but since many users never attach their phone they never even see good updates and patches. Face it, iOS is fragmented but in a different way than Android.
On the Android side we see crash reports. When the app dies you are given the choice to send the report over your 3G / Wifi / whatever data connection. Our app is based on being connected so sending this data is no big deal. Apple decided to bundle up all the crashes on the phone and horde them like a dragon.
When I attach an internal beta testers phone to my Mac I get to see all the crashes from our app and all other apps on the device. Stuff crashes a lot from what I see. Those developers never get to see their crashes either. This is a damn shame and a total false sense of security. I pretty much wanted to scream at how annoyed I am at Apple for not giving me access to crash reports so I can make my app better.
I am now going to have to look into some user written crash handlers. You can catch exceptions at a higher level and then you need to try and save the crash somewhere then write it to your server during the next log in. When your app is crashed you can't do much with the data and since there is no central support you are on your own as to how to handle it. We will need a new API on our server to accept the crash data so I can log in and get it at a later time to analyze the situation. They need to fix this. Apple has been less than developer friendly through this whole process and they continue to piss me off.
On the Android side my Motorola Xoom updated to Ice Cream Sandwich and I am happy with the upgrade. The fonts look a lot nicer and I like the new back / home / menu button look. I don't care for the "clear all" vs. "clear individual" notifications from the status bar.
I wish my phone could be upgraded but they stopped that at Froyo. This is a big downside on the Android side. Each manufacturer gets to decide how much they want to hose over the phone so it is unique to them but when they do that they can skip all future Android releases. As a developer I want the latest stuff. End users don't seem to care and just want it to run. See the iOS stuff above to find out the a lot of iOS users never upgrade. With OTA maybe that will change on the iOS side but the 4.x to 5.x upgrade was not friendly to me or others causing you to lose everything if you did not back it up first. Doing that OTA is not a good idea.
I understand not getting ICS on my phone but I really want Gingerbread as Google sped up various aspects of the UI with some new memory management etc. Guess I will look into rooting it at some point in the future and if it works for me I will do it on my wife's phone too.
Friday, January 20, 2012
Ouch - App Store rejection!
After a full week of waiting to review our app got rejected by the Apple app store. They found a crash, a legitimate and easy to reproduce crash that should have never made it past me or QA. A crash that occurred in all previous versions of the software. A crash that made it through to the store multiple times.
It involved turning off some of the editable sections via the admin tool. I was using a tag as an array offset, if all sections are enabled the tag would equal the offset, but in the one test case this was going to cause an index out of bounds. I screwed up and should have labeled the variable as tag instead of as section. I probably was going to do that at one point but the crappy refactoring support in Xcode means I skip doing work like that from time to time.
It is my fault for not catching this earlier. For the test log in we sent to Apple you had three practices to choose from. The bug only occurred on the third practice in the list and only when you pressed the (+) to add a new image to list. Very glad Apple found this issue. I did not want a crash out in the hands of our users and I am sure many would have run into this issue as the layout of the editable items is totally configuration via our administration tool. That tool is not a mobile app but how each client configures what they want the doctor to enter is totally up to them. Annoying this was not caught by QA. As a developer you don't have time to configure piles of test cases in the admin tool then test things out on the mobile side of things. Something like this I should have tested though as it is pretty easy to configure and verify.
It works just fine on the Android. Due to language and GUI component differences the code is not a direct port between the platforms. Could be I was doing a quick conversion to the iPhone or I did the iPhone side first and caught the issue during the Android conversion or the Android code is so different that bug would not occur or I forget to go fix it under iOS post Android conversion. I was back and forth between the two on a daily basis.
Being the sole developer for two platforms is just not easy. I have no one here that can do Objective C code reviews. Someone could look over the Android Java code but I am the only Android developer so some parts of the API would not be familiar too them. Java tends to be Java so I am sure they could find issues if they looked hard enough. Heck, I could find issues if I gave it all a once over. I fixed the issue, ran some tests and we submitted it again.
Within an hour it was back in "In Review" status so Apple obviously saw we got right on the fix and did not move us back to the end of the line. I really did not want our clients to wait another full week for Apple to just start looking at the app again. I am hopeful it gets through the review process in a few hours and we can contact clients starting Monday to let them know a new version is ready that fixes the camera issues and this new issue.
I just got another note from Apple that they need additional review time but they will keep me posted. Must be time for a real test instead of the past two times where it was just shuffled right out into production.
We don't appear to be getting crash reports from Apple. When we look in the crash report section nothing is listed even though clients reported crashes. I wonder if it is due to them running 4.1 iOS and the tabs for the crash reports start with the 4.2.x series. Does Apple throw away older iOS reports? We could tell clients to upgrade but we list support as 4.0x and above. Plus upgrading to 5.x series is not for the faint of heart. You darn well better back up everything because I know multiple people that had everything blown away. That was not the case when doing 4.0.x -> 4.1.x -> 4.2.x upgrades and people got a false sense of security. A lot of doctors just get the device and never connect it to a computer. I really don't want to walk them through that process.
Here's hoping the new update is available at the store on Monday!
It is my fault for not catching this earlier. For the test log in we sent to Apple you had three practices to choose from. The bug only occurred on the third practice in the list and only when you pressed the (+) to add a new image to list. Very glad Apple found this issue. I did not want a crash out in the hands of our users and I am sure many would have run into this issue as the layout of the editable items is totally configuration via our administration tool. That tool is not a mobile app but how each client configures what they want the doctor to enter is totally up to them. Annoying this was not caught by QA. As a developer you don't have time to configure piles of test cases in the admin tool then test things out on the mobile side of things. Something like this I should have tested though as it is pretty easy to configure and verify.
It works just fine on the Android. Due to language and GUI component differences the code is not a direct port between the platforms. Could be I was doing a quick conversion to the iPhone or I did the iPhone side first and caught the issue during the Android conversion or the Android code is so different that bug would not occur or I forget to go fix it under iOS post Android conversion. I was back and forth between the two on a daily basis.
Being the sole developer for two platforms is just not easy. I have no one here that can do Objective C code reviews. Someone could look over the Android Java code but I am the only Android developer so some parts of the API would not be familiar too them. Java tends to be Java so I am sure they could find issues if they looked hard enough. Heck, I could find issues if I gave it all a once over. I fixed the issue, ran some tests and we submitted it again.
Within an hour it was back in "In Review" status so Apple obviously saw we got right on the fix and did not move us back to the end of the line. I really did not want our clients to wait another full week for Apple to just start looking at the app again. I am hopeful it gets through the review process in a few hours and we can contact clients starting Monday to let them know a new version is ready that fixes the camera issues and this new issue.
I just got another note from Apple that they need additional review time but they will keep me posted. Must be time for a real test instead of the past two times where it was just shuffled right out into production.
We don't appear to be getting crash reports from Apple. When we look in the crash report section nothing is listed even though clients reported crashes. I wonder if it is due to them running 4.1 iOS and the tabs for the crash reports start with the 4.2.x series. Does Apple throw away older iOS reports? We could tell clients to upgrade but we list support as 4.0x and above. Plus upgrading to 5.x series is not for the faint of heart. You darn well better back up everything because I know multiple people that had everything blown away. That was not the case when doing 4.0.x -> 4.1.x -> 4.2.x upgrades and people got a false sense of security. A lot of doctors just get the device and never connect it to a computer. I really don't want to walk them through that process.
Here's hoping the new update is available at the store on Monday!
Thursday, January 19, 2012
The land of JXLayer
I am deeper into the MigCalendar to JIDE conversion process. I am still working on the prototype for the scheduler control and have a good hunk of the rendering working. That means I get to play with drag to size and drag to move. I am using a JXLayer to handle this as the main JIDE grid needs to do its own row height and column width sizing that I don't want to screw up.
JXLayer is really nice in that your can paint anything on a glass pain after all the stuff under the glass has already rendered. I have appointments so I keep their rounded rectangle associated to them. If the cursor is over / near the top or bottom edge of the rounded rectangle I paint a thicker border for the rectangle in the JXLayer. The JXLayer also watches for mouse press / release actions for the thick border rectangle so I can start dragging operations allowing the user to resize the appointment to a new time frame.
Next up was the auto scrolling of the JideScrollPane as they near the edges of the screen. I have to monitor the viewport rectangle for changes while I am in my dragging code to adjust my rectangles. Lots and lots of point and rectangle processing going on in this code along with clipping and offset calculations. At this point it is all working rather nicely although I can get it to screw up a bit from time to time. I need to figure out snapping to time slots. I don't want to increment by the minute but maybe 15 minutes is too much. They can always popup a true time editor dialog to get exact numbers. The drag to size needs to be reasonable but not so crappy you will never use it. Dragging the appointment to another cell in the grid also needs to happen. For that I am thinking of a simple drag to let you move it anywhere, a CTRL + drag to only move the appointment vertically (i.e. change start time) and a SHIFT + drag to only move horizontally (i.e. under another provider, facility, room or category depending on the current column configuration). There are a lot of time you only want to change one axis and I know a lot of paint programs use CTRL, ALT and SHIFT to lock the mouse movement.
With that in mind I am considering a "status bar" custom control to show the tool tip text, row (time slot) and column (provider, etc.) information as multiple level row / column headers can be off screen meaning you don't know exactly where you are in the grid always without this special status information.
Writing a scheduler has been a unique experience for sure. You see various 3rd party .NET controls that emulate Outlook in one fashion or another. There is almost nothing other than MigLayout on the Java side. We need to be cross platform so .NET is out even though I know how to code in C#. The other choice would be a web based product but we a lot of support data that needs to be cached leaving that out too.
Sometimes writing your own control is the only option. I have used JXLayer in the past to draw spinning busy cursors. I had not used it for mouse interaction. It has been pretty easy so far once you figure out your painting offsets based on the scrollpane and other JComponents you are dealing with. Not sure what I would do if I need to port this to a touch interface for iOS or Android. My boss got Ice Cream Sandwich on this Xoom this morning. My updates always seem to be a day or so later in the staggered refresh cycle but I am excited to give it a shot when it magically appears. He tried our mobile app out under it and it appeared to work fine. Not a big surprise as the same code base works on phones and tablets. I am using 2.1 as minimum required API so I am not using any cool fragments or other tablet features that appeared in the 3.x series. I just want to see the bad boy running and to play with the new OS stuff.
Next up was the auto scrolling of the JideScrollPane as they near the edges of the screen. I have to monitor the viewport rectangle for changes while I am in my dragging code to adjust my rectangles. Lots and lots of point and rectangle processing going on in this code along with clipping and offset calculations. At this point it is all working rather nicely although I can get it to screw up a bit from time to time. I need to figure out snapping to time slots. I don't want to increment by the minute but maybe 15 minutes is too much. They can always popup a true time editor dialog to get exact numbers. The drag to size needs to be reasonable but not so crappy you will never use it. Dragging the appointment to another cell in the grid also needs to happen. For that I am thinking of a simple drag to let you move it anywhere, a CTRL + drag to only move the appointment vertically (i.e. change start time) and a SHIFT + drag to only move horizontally (i.e. under another provider, facility, room or category depending on the current column configuration). There are a lot of time you only want to change one axis and I know a lot of paint programs use CTRL, ALT and SHIFT to lock the mouse movement.
With that in mind I am considering a "status bar" custom control to show the tool tip text, row (time slot) and column (provider, etc.) information as multiple level row / column headers can be off screen meaning you don't know exactly where you are in the grid always without this special status information.
Writing a scheduler has been a unique experience for sure. You see various 3rd party .NET controls that emulate Outlook in one fashion or another. There is almost nothing other than MigLayout on the Java side. We need to be cross platform so .NET is out even though I know how to code in C#. The other choice would be a web based product but we a lot of support data that needs to be cached leaving that out too.
Sometimes writing your own control is the only option. I have used JXLayer in the past to draw spinning busy cursors. I had not used it for mouse interaction. It has been pretty easy so far once you figure out your painting offsets based on the scrollpane and other JComponents you are dealing with. Not sure what I would do if I need to port this to a touch interface for iOS or Android. My boss got Ice Cream Sandwich on this Xoom this morning. My updates always seem to be a day or so later in the staggered refresh cycle but I am excited to give it a shot when it magically appears. He tried our mobile app out under it and it appeared to work fine. Not a big surprise as the same code base works on phones and tablets. I am using 2.1 as minimum required API so I am not using any cool fragments or other tablet features that appeared in the 3.x series. I just want to see the bad boy running and to play with the new OS stuff.
Friday, January 13, 2012
Submitted to the app stores today
I have fixed all the client reported issues, a few things I found, a few things QA found and I updated to the new favorite / default favorite processing that works across URL instances and new table loads. It started out being a small thing that got a lot bigger once I dug into what it was going to take to save favorites / reload tables / reload favorites properly across log in sessions. I am very happy with this release and feel good not calling it beta.
The big fix on the Android side was working with slide out keyboards. It was an easy manifest only fix, tracking it down and finding a device to test against were the fun part.
Under iOS the fix was crashing during picture taking due to low memory conditions. I had some bad pairing of create / dealloc between the viewDidLoad and viewDidUnload methods. Once that was straightened out and I was able to get hold of an older iPhone 3GS to test low memory on a device I am pretty darn sure I have this one licked. It did really show me how much Apple has moved forward with the later iOS versions. Before everything was killed instead of being put in the background. If you were mid edit on a case and accidentally hit the Home button to bad. Now the app is in the background and you can get back to it. Something I never had to think about on the Android. I am leaving some of the devices on the old iOS version to remind me of the pain. Plus a lot of users don't upgrade their iDevices because it is not OTA. They never hook it up to their PC. If you upgrade to iOS 5.x you must be careful and backup as it is going to wipe our your data.
Android update is available on the Market now so I can ask the client with the slide out keyboard to test it right away. Hopefully Apple will follow form and have the new release accepted by Sunday and we can have the clients test it starting Monday. They have hit the last couple of releases on the 2 day mark.
In between bug fixes I have been back to working on the JIDE grid based scheduler. I am wrote a custom label for showing the date with the day of the week in a smaller font over the month day, year. I have a pop-up calendar showing when you click on that control allowing you to quickly hop to any date. I added a gradient JPanel I used in some older projects to give the header where the date control lives a nicer look and have started to hook up some of the other buttons. Pretty soon I will move all of this over into the main product and actually load real appointments and display them in the new grid. I need to mess around with the renderer a bit before I do that so it can handle overlapping events and events that only occur in part of the time slot.
It has been fun to work without a device, emulator or simulator. Press and a window just appears and you start testing. Very small proof of concept app so everything loads in an instant allowing you to play around with very little pain. After awhile all apps become huge with features just slowing you down as you are tweaking the GUI. I also don't need to log in as I am not using real data which is also nice. Always good to have a small test harness to piddle around with new programming ideas.
I have Skyrim sitting on my desk, plan to install it tonight along with the patches. There goes this weekend, the next, etc. until the wife and kids don't recognize me.
The big fix on the Android side was working with slide out keyboards. It was an easy manifest only fix, tracking it down and finding a device to test against were the fun part.
Under iOS the fix was crashing during picture taking due to low memory conditions. I had some bad pairing of create / dealloc between the viewDidLoad and viewDidUnload methods. Once that was straightened out and I was able to get hold of an older iPhone 3GS to test low memory on a device I am pretty darn sure I have this one licked. It did really show me how much Apple has moved forward with the later iOS versions. Before everything was killed instead of being put in the background. If you were mid edit on a case and accidentally hit the Home button to bad. Now the app is in the background and you can get back to it. Something I never had to think about on the Android. I am leaving some of the devices on the old iOS version to remind me of the pain. Plus a lot of users don't upgrade their iDevices because it is not OTA. They never hook it up to their PC. If you upgrade to iOS 5.x you must be careful and backup as it is going to wipe our your data.
Android update is available on the Market now so I can ask the client with the slide out keyboard to test it right away. Hopefully Apple will follow form and have the new release accepted by Sunday and we can have the clients test it starting Monday. They have hit the last couple of releases on the 2 day mark.
In between bug fixes I have been back to working on the JIDE grid based scheduler. I am wrote a custom label for showing the date with the day of the week in a smaller font over the month day, year. I have a pop-up calendar showing when you click on that control allowing you to quickly hop to any date. I added a gradient JPanel I used in some older projects to give the header where the date control lives a nicer look and have started to hook up some of the other buttons. Pretty soon I will move all of this over into the main product and actually load real appointments and display them in the new grid. I need to mess around with the renderer a bit before I do that so it can handle overlapping events and events that only occur in part of the time slot.
It has been fun to work without a device, emulator or simulator. Press
I have Skyrim sitting on my desk, plan to install it tonight along with the patches. There goes this weekend, the next, etc. until the wife and kids don't recognize me.
Thursday, January 12, 2012
Android app disappears with slide out keyboard
While checking in with a client on our mobile apps they mentioned that on an Android phone with a slide out keyboard the app disappeared every time they slid out the keyboard. I had not tested on any devices with a slide out keyboard so this was news to me.
One of the ladies in support happened to have a slide out phone at home so she brought it into work today. I set it up for debug and plugged it in to my machine to monitor it under Eclipse. No errors in the log, the app just disappeared. I put in break points and found onDestroy was being called but why?
Searching the web and I found you need to add keyboardHidden to your manifest file so the activity will not be destroyed when that event occurs. All my activities looked like this:
android:configChanges="orientation|keyboard"
Now they look like this:
android:configChanges="orientation|keyboard|keyboardHidden"
This solves the issue. I thought keyboard would handle things but you must have both keyboard and keyboardHidden for it to work on all devices.
One of the ladies in support happened to have a slide out phone at home so she brought it into work today. I set it up for debug and plugged it in to my machine to monitor it under Eclipse. No errors in the log, the app just disappeared. I put in break points and found onDestroy was being called but why?
Searching the web and I found you need to add keyboardHidden to your manifest file so the activity will not be destroyed when that event occurs. All my activities looked like this:
android:configChanges="orientation|keyboard"
Now they look like this:
android:configChanges="orientation|keyboard|keyboardHidden"
This solves the issue. I thought keyboard would handle things but you must have both keyboard and keyboardHidden for it to work on all devices.
Of course you only want to do this if you gracefully handle orientation and keyboard changes in your code. All of my activities are very friendly to orientation changes and to the on-screen keyboard appearing or disappearing. The term keyboardHidden does not say to me "the hardware keyboard is sliding out" making it an very unfortunate term on Googles part. A better name might be hardwareKeyboard. I have a feeling the percentage of users with a slide out keyboard is pretty small too but you want to make sure your app works on as many devices as possible.
I have run our app on my Xoom with a bluetooth keyboard. Even though it operates to the OS like a slide out keyboard in that the on-screen keyboard does not appear it did not have any crash issues. The slide out keyboard must trigger special events. Glad to have it fixed in our code.
Wednesday, January 11, 2012
Big Xcode frustrations
My developer provisioning profile expired. After pressing [Update] twice Xcode asked if I wanted to send a message to my account manager (my boss) to renew it. I agreed to that. He got an email and renewed it. I hit [Refresh] and got the new one and tried to build. Failure again. A closer look showed a new error message telling me there are multiple provisioning certificates.
I delete one but no help so I open up Keychain Access and delete the expired on that has the exact same name as the good one. Why does the system not prompt you to save or replace or just do it automatically for you? What good is an expired certificate? It is no good at all and just another annoyance getting in my way of getting real work done.
This allows me to build for a provisioned device or the simulator but I can no longer build a release version. What the hell is going on now? I can see the release / distribution profile in the Developer Profile table in the Xcode Organizer but that table is read only. I search the web trying to find the correct wording and finally figure out you have to drag the .mobileprovision file to Xcode. You can't drag the .cer file, it has to be the .mobileprovision file. I find that on my HD and drag it to Xcode which now allows me to build release.
We need to provision another device to do some testing as I am having crashing issues on older iPhones. Everything works find on newer iPhones, both iTouches I have and the iPad. No fragmentation here. I send the device ID to my boss and he adds it to our developer profile. I press [Refresh] and the new device appears but the release profile disappears and another expired profile I deleted reappears. Screw all of that. This process is a totally screwed up mess.
I drag the distribution profile back into Xcode and delete the expired one again and all is good or so I think. I plug in the new provisioned iPhone and press (>) to run the new build of the app on it. No go but why? First off the console log window disappears again from the debug window. I click the layout button to have that appear again and it is full of UUID mismatch warnings. I copy one of those to the clipboard and it turns out the is a common problem where you have to delete the files in /Developer/Platforms/iPhoneOS.platform/DeviceSupport/ for the device version you have then restart Xcode, reattach the device and let it resync itself before you try to run it again. After all of that I get the program installed and the console window disappears again but we can start testing. So far my fixes appear to be working. I then install on one of the iTouch test devices and have to let it resync too before I can install the app update.
Pretty much I wasted a good part of the day on really stupid crap on my Mac. I also know that anytime I update my provisioning profiles I am hosed and have to delete one and redrag in the correct one. Thanks Xcode for being such a pain in the ass constantly. This is not a friendly IDE, this is not a nice way to treat developers, this is a massive waste of time just to get a freaking build ready. These are not uncommon issues. I found a lot of folks on the web having the same issues. I have not run into this craptastic fun on the Android side of things using Eclipse. I don't have to sign anything to install on any device. I don't have to provision anything. The one signature I use for a release is good for 30 years. I am not constantly hassled to be doing something I should be able to legally do. I don't have developer and distribution certificates expire at different times. I don't have and IDE that gives less than helpful error messages that I must search the web to have any hope of decoding.
Some of this might not happen if I was the Apple account owner and the sole developer. That part of the equation has been a huge headache repeatedly with Apple. I finally have to give up using my work email account and use my personal email account with Apple as they could not get their own system straightened out. It gets to the point you hate to try and build the app on the Mac. I just don't trust it do it correctly ever.
Tuesday, January 10, 2012
Saving database favorites on mobile devices
After a number of missteps I think I have database favorites savings in place on both our Android and iOS applications. How hard can saving favorites be you ask? Much worse than I originally thought for a number of reasons.
With a mobile device a number of things come into play. First there is no log out. As programmers we like symmetry. Open file / close file, log in / log out etc. Matching pairs are awesome. Load when they start, save when the exit, what a beautiful world that would be. You really can't guarantee log in / log out pairing on a desktop application but you have a better shot of it happening. On the mobile side your app can be kicked out due to low memory conditions or the user Task Manager killing it.
My users can log into a specific URL instance then pick the practice which has an associated provider name for their log in name. There are some tables that are static per URL instance, in my case ASA, CPT and Diagnosis, and some tables, which I call session tables, that need to be reloaded per log in. The user wants their favorites and default favorite to carry over between log in sessions and between table reloads from the server.
Between log in sessions the system administrator can add, remove or modify records. That is why we reload things per session. These are generally small tables such as Facilities, Referring Physicians and the like. The large ASA, CPT and Diagnosis tables are updated on a yearly basis. I download a permanent cache table per log in session to see if the ASA, CPT or Diagnosis code table needs to be refreshed even if all my other rules make it look stable. Even when the powers that be decide there are new Diagnosis codes I don't want to lose your list of favorites.
Just after a successful log I check to see if there was a previous successful log in. If there was and the URL is not the same I save all database table favorites to a favorites table if the current database table has at least one row. All tables are loaded on demand meaning I only load them if you need data from them, I don't just load them at start up all while you twiddle your thumbs, that would be a huge waste of time and bandwidth. If the URL is the same but the Practice or Provider is different I save favorites for session tables before I clear them. I don't actually clear the table but I mark it as stale. If during this session a user needs data from that table it will be cleared and reloaded.
Once all that is done I save the URL + Practice + Provider to user settings. That would be NSUserDefaults on iOS and getSharedPreferences on Android. This is the last known good log in. Basically I check for previous session log out during the log in processing. I use the special preferences area on each platform as that is maintained even if the program is ejected from memory or killed by the user. If the user uninstalls the application then all settings are gone and a new install will start the process all over.
In general the ASA, CPT and Diagnosis tables are the same across URL instances but not always. The tables are loaded from the same text file but ProgreSQL does not maintain the same order during record inserts for some reason. We were saving the unique key in the favorites table but now need to save the Code + optional Modifier instead allowing me to match favorites across URL instances. I convert back and forth between ID and Code + Mod as I want to do comparisons on the much faster integer instead of slow string checks once things are up and running.
If you log in to the same URL as the same user and select the same practice every time then I don't save / load favorites to the backing table for the big three. They are just flags set on each table as you toggle the favorite flag on records. The main ASA, CPT and diagnosis tables will only refresh from the server when they get a new master load. Session tables will get a save / load of favorites per log in. It will all be pretty transparent the user. They get a quick busy screen as I load session tables from first time use and after that the data is quickly available for the rest of the log in session.
Keeping it all straight was fun. I need a fully qualified previous log in that I don't touch until all favorite saving is done. I don't want to gut any of the old table data until all favorites have been saved and I have to use backing table data for everything as just saving to the program objects is not persistent enough. When I access the table for favorites saving I need to make sure I don't do any of my stale data checks which would force the table to clear and be repopulated with new data. Post successful log in I don't want to know about the old log in. Tables can be reloaded from the server at any time as the user does an ASA search for example. When the table is stale I need to load it from the server then apply the saved favorites, if any, from the last time they were saved for the current log in URL + Practice + Provider log in. Keep in mind those might have been save 20 log ins ago because the user may have used the ASA table just once in the past 20 sessions even though they logged in over and over.
There can only be one default favorite set per table per unique log in so I have to delete the old before I set the new if we have one.
The best way to handle all of this in testing was to use the emulator for Android and the simulator for iOS. You can't get to the database on a device unless you have a rooted device. Great for security, not so fun for a developer. The emulator in Android is not exactly fast so it made testing less than fun. Plus I have to copy the database file from the device to my hard drive then open it with a third party tool to view the data. I had to log in repeatedly as different users. At last both platforms support the keyboard so I did not have to mouse click on-screen keyboards for the URL, User Name and Password over and over.
The simulator for iOS is faster than the device which is very nice. I use SQLite Manger under FireFox to view the database. The only issue there is anytime you update the simulator you have to track down the database under /Users/{your name}/Library/Application Support/iPhone Simulator/{iOS version}/Applications/{GUID}/Documents/{app}.db and you have to remember to click "All Files" under Format: before you do this as the default is *.sql. If you navigate all the way down the directory path and go "where the heck is my file?" then change to "All Files" you get to navigate all the way down there again which is not user friendly. SQLite Manager remembers the last file opened so you don't have to do this very often. Of course if you test under iOS 3.x, 4.x and 5.x you will have to navigate to each directory for that test. At least the iPhone and iPad share directory for a given iOS version. At first that threw me off, I thought when I switched between iPhone and iPad simulators I would get different data but it loaded up my favorites from the iPhone.
The updated applications are in the hands of QA now. Hopefully I will get them submitted in the next couple of days and go back to my JIDE scheduler table work. It has been a rough couple of days under the old wireless headphones pounding away on both platforms.
With a mobile device a number of things come into play. First there is no log out. As programmers we like symmetry. Open file / close file, log in / log out etc. Matching pairs are awesome. Load when they start, save when the exit, what a beautiful world that would be. You really can't guarantee log in / log out pairing on a desktop application but you have a better shot of it happening. On the mobile side your app can be kicked out due to low memory conditions or the user Task Manager killing it.
My users can log into a specific URL instance then pick the practice which has an associated provider name for their log in name. There are some tables that are static per URL instance, in my case ASA, CPT and Diagnosis, and some tables, which I call session tables, that need to be reloaded per log in. The user wants their favorites and default favorite to carry over between log in sessions and between table reloads from the server.
Between log in sessions the system administrator can add, remove or modify records. That is why we reload things per session. These are generally small tables such as Facilities, Referring Physicians and the like. The large ASA, CPT and Diagnosis tables are updated on a yearly basis. I download a permanent cache table per log in session to see if the ASA, CPT or Diagnosis code table needs to be refreshed even if all my other rules make it look stable. Even when the powers that be decide there are new Diagnosis codes I don't want to lose your list of favorites.
Just after a successful log I check to see if there was a previous successful log in. If there was and the URL is not the same I save all database table favorites to a favorites table if the current database table has at least one row. All tables are loaded on demand meaning I only load them if you need data from them, I don't just load them at start up all while you twiddle your thumbs, that would be a huge waste of time and bandwidth. If the URL is the same but the Practice or Provider is different I save favorites for session tables before I clear them. I don't actually clear the table but I mark it as stale. If during this session a user needs data from that table it will be cleared and reloaded.
Once all that is done I save the URL + Practice + Provider to user settings. That would be NSUserDefaults on iOS and getSharedPreferences on Android. This is the last known good log in. Basically I check for previous session log out during the log in processing. I use the special preferences area on each platform as that is maintained even if the program is ejected from memory or killed by the user. If the user uninstalls the application then all settings are gone and a new install will start the process all over.
In general the ASA, CPT and Diagnosis tables are the same across URL instances but not always. The tables are loaded from the same text file but ProgreSQL does not maintain the same order during record inserts for some reason. We were saving the unique key in the favorites table but now need to save the Code + optional Modifier instead allowing me to match favorites across URL instances. I convert back and forth between ID and Code + Mod as I want to do comparisons on the much faster integer instead of slow string checks once things are up and running.
If you log in to the same URL as the same user and select the same practice every time then I don't save / load favorites to the backing table for the big three. They are just flags set on each table as you toggle the favorite flag on records. The main ASA, CPT and diagnosis tables will only refresh from the server when they get a new master load. Session tables will get a save / load of favorites per log in. It will all be pretty transparent the user. They get a quick busy screen as I load session tables from first time use and after that the data is quickly available for the rest of the log in session.
Keeping it all straight was fun. I need a fully qualified previous log in that I don't touch until all favorite saving is done. I don't want to gut any of the old table data until all favorites have been saved and I have to use backing table data for everything as just saving to the program objects is not persistent enough. When I access the table for favorites saving I need to make sure I don't do any of my stale data checks which would force the table to clear and be repopulated with new data. Post successful log in I don't want to know about the old log in. Tables can be reloaded from the server at any time as the user does an ASA search for example. When the table is stale I need to load it from the server then apply the saved favorites, if any, from the last time they were saved for the current log in URL + Practice + Provider log in. Keep in mind those might have been save 20 log ins ago because the user may have used the ASA table just once in the past 20 sessions even though they logged in over and over.
There can only be one default favorite set per table per unique log in so I have to delete the old before I set the new if we have one.
The best way to handle all of this in testing was to use the emulator for Android and the simulator for iOS. You can't get to the database on a device unless you have a rooted device. Great for security, not so fun for a developer. The emulator in Android is not exactly fast so it made testing less than fun. Plus I have to copy the database file from the device to my hard drive then open it with a third party tool to view the data. I had to log in repeatedly as different users. At last both platforms support the keyboard so I did not have to mouse click on-screen keyboards for the URL, User Name and Password over and over.
The simulator for iOS is faster than the device which is very nice. I use SQLite Manger under FireFox to view the database. The only issue there is anytime you update the simulator you have to track down the database under /Users/{your name}/Library/Application Support/iPhone Simulator/{iOS version}/Applications/{GUID}/Documents/{app}.db and you have to remember to click "All Files" under Format: before you do this as the default is *.sql. If you navigate all the way down the directory path and go "where the heck is my file?" then change to "All Files" you get to navigate all the way down there again which is not user friendly. SQLite Manager remembers the last file opened so you don't have to do this very often. Of course if you test under iOS 3.x, 4.x and 5.x you will have to navigate to each directory for that test. At least the iPhone and iPad share directory for a given iOS version. At first that threw me off, I thought when I switched between iPhone and iPad simulators I would get different data but it loaded up my favorites from the iPhone.
The updated applications are in the hands of QA now. Hopefully I will get them submitted in the next couple of days and go back to my JIDE scheduler table work. It has been a rough couple of days under the old wireless headphones pounding away on both platforms.
Subscribe to:
Posts (Atom)