Life at the new job has been interesting. They did not have an official place for me to sit on the first day so I took over the office of a guy who is on vacation. They found a place over in customer support so I moved there for a bit and now will move to a more permanent home in what use to be a small conference room that is being divided into 4 cubes. I will be in there with another Android developer and two iPhone developers. Will help us share a lot of ideas.
For my main testing device they gave me a Galaxy Note - original version not the new II. For some reason I thought it was going to be much larger as all the reviews jump all over that. It is larger than my main phone, a Galaxy S Vibrant. I actually like the size. Larger than my phone but not a tablet. I have been using it a lot a night to see what I think of it as I have considered getting a Note II when it goes on Black Friday sale, or at least I hope it goes on sale.
I wish the S-Pen worked a bit faster. I am hoping it does a better job keeping up on the Note II. On the model I have I must slow down my standard writing speed to have it draw what I think it is going to draw. I should not have to adjust to what the device can do, it should keep up with me. I have used the phone as a mini whiteboard. Again, drawing speed is a little slow but if I match the pace it works well. Using it to jot down notes at home is also handy, it sits right next to me and saves me from hunting down paper to remember something like "out of cat food". You can easily erase mistakes in your drawings too. I think this could be a great feature.
As far as a testing device it is really nice. Samsung seems to be very quick to grab back memory you once used and to kill activities as you move between them. It allows me to simulate low memory usage that would occur on a phone. This really comes into play as I am doing a lot of importing of images from the camera activity which is one area you can quickly run into memory limitations. I have been able to fix all the issues I have run into and make my code much more low memory proof than previous code I have written. Allowed me to learn all sorts of interesting things about Android programming.
After using the phone for about a week I would say it is a winner. I have been using it at night instead of my Xoom when I put my son to bed. At that time I am generally reading web pages, using Pulse or maybe playing a game. Being able to do that with one hand is really nice. I don't know if a 7" tablet would allow me to do the same thing or not as I don't have access to one. The Note fits in the hand without cramping. The screen is very bright and readable. I only charge is once a day. Web pages tend to be read in landscape mode but that works just fine. You get the side to side space you need for most websites but you do have to to a bit more scrolling vertically as you read pages. Nothing that is annoying, just something to keep in mind.
After I have time to test the S-Pen drawing speed on a Note II and it goes on sale I will probably buy one as my next personal device. I love the Xoom tablet and use it a lot. My phone is getting older and it only runs 2.2 which is pretty crappy. I need to use some of the new Android OS features to keep up with the programming world.
Working strictly on mobile development at my job has been nice. No shifting gears between iOS, Android and desktop Java during the day. One keyboard, mouse, language and IDE to keep straight. I am happy I know Objective C so I can look at the code and see what they did as my first project is a conversion of the automatic check deposit functionality, thus me taking a lot of pictures. I am sure my cube mates are sick of hearing the sound of a camera shutter as am I. Friday morning I fixed my threading issue so I stopped taking pictures and started looking into the server API for send the deposits.
Being as I am a contractor I get to work Monday which the perms have the day off for Veteran's Day. I will be happy when I convert to a full time person allowing me to have all the bank holidays off like I did when I worked in the stock market industry.
Showing posts with label iphone. Show all posts
Showing posts with label iphone. Show all posts
Saturday, November 10, 2012
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!
Tuesday, September 27, 2011
Converting a phone app to Android tablets and the iPad
Just as I thought I was winding down my Android and iPhone development the Doctors tell us they have bought iPads and Android Tablets to use to enter all the data. Can't blame them as it is much easier to enter data on a tablet. The problem is we were going to target those devices on the next release. Time to quickly switch gears.
The app ran fine on the Xoom but the home screen needed to scale better. I searched the web and found new graphics for that area. With more room using larger fonts also seemed the way to go so I tweaked a few other XML files. I ended up creating a new values-xlarge directory under the res directory to hold a styles.xml file for the tablet. I find the way Android handles this to be super easy. I had to go back into a few of my other XML files to make sure they were using the named styles but that was all. I only have a few files in my layout-xlarge and layout-xlarge-land directories to handle all the changes I wanted to make on the Android Tablet.
Android does handle your app getting kicked out out memory in a way that screwed with our app. We have some global static data (I know wrist slap in order) but I need it for the SQLite database and some other login credentials. When you get booted from memory the OS tries to run your onCreate method of the visible view again. For most apps this would be great, you just pretend you started fresh and go. But with the global variables this is not so fun. I added enough checks that I don't [Force Close] any more but tell the user that the session has expired and they need to login in again. I kick them back to the login screen to get going with a fresh database and session variables.
Initially testing this case was a royal pain. You needed to leave your phone on overnight or run so many apps that it got kicked out of memory. Of course that is stupid and a few internet searches pointed me in the right direction. Fire up the emulator, run your app, use "adb shell" from the command line then "ps" then "kill #id" of your process. This will cause same sequence of events to occur. I brought up each possible activity / view and did that over and over until they all exiting clean to the login screen. You can't do this when running on a device but you can use the DDMS view in Eclipse and hit the red [stop] button to achieve the same results.
Once you start running on a real device, especially a dual core tablet, you hate to go back to the emulator. Of course QA came and took the tablet a few days after I had it in my hot little hands so I am still missing it. So much nicer to type on it and code changes are sent over to it and are up and running in a blink of an eye.
Now for my iPad experience. You can set up a universal binary in Xcode. Once you do that it will automatically switch you to the latest version of iOS as your target which is not a good thing. I wanted to target 3.0x as the minimum iOS version. Since Xcode is smarter than me things quit working on my iTouch until I figured out what it did. Simple enough to change that back.
Initial runs on the iPad looked like initial Android tablet runs. Most things looked pretty good as I was using list views and text editors. The home screen looked crappy though. I was able to use my @2x images for the retina display on the iPad. I used the stretchableImageWIhtLeftCapWidth to simulate the nine-patch image I was using for the shelves on the Android.
topShelf = [[UIImageView alloc] initWithImage:[shelf stretchableImageWithLeftCapWidth:25 topCapHeight:0]];
Worked like a charm and was much easier than I assumed it would be. I had to put in manual positioning code for each of the icons on the shelves for the iPad but there are only 6 images so that was easy enough.
I am adjusting for the height of the status bar in my code too. On the iPhone the status bar height is different between portrait and landscape but it is one height on the iPad. I put code in place to handle those special situations and everything looks pretty darn nice.
Since I have more title bar room I wanted to show the practice name on the home screen. Of course that changed the "back" button on any screen that launched from the home screen which is not what I wanted. Turns out you can do this:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
self.navigationItem.title = [NSString stringWithFormat:@"Home - %@", [RESTCaller practiceName]];
UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
[self.navigationItem setBackBarButtonItem:backButton];
That code allows you to set the title text to one thing but the back button used by all other areas to something else. Not the way my mind thinks but I understand the logic behind it now that it is in place.
I want to increase the font size on various screen on the iPad. Since there is no real layout manager for iOS, everything is hard coded for widths / heights in the XIB file, this is a royal pain. You can either do secondary XIB files where you have to tie everything exactly back to the code via drag and drop or you can try and tweak things in code playing with bounds and what not. Both are sorry excuses for layout editing. I have made slow progress in this area but find the amount of work involved to be stupid.
The iPad cannot use the same call to show the picture gallery as the iPhone. I had to update the code to make the new call to show a pop-up image picker instead of a full screen gallery picker. I hope that is the only API I am using that they changed on me. Rough one to find, good thing we have QA to beat on it.
UIActivitySheets don't exactly work the same on the iPad either. They show up nice and centered but if you rotate the device while you are displaying one it will not stay centered. It stays relative to its original position. Looks ugly but this will be a really rare case so I did not fix it. There are some suggestions on the web as to how to fix it but nothing worked for me. The only thing left to consider is killing the sheet when you get a rotation notice and recreating it so it shows up in new orientation centered again. Of course if you do that really quickly you will have a new set of issues. Not worth it at this point. I see Apple cheated in this respect. Long tap a link on a web page. It pops up a menu. Rotate the screen. The Screen will not rotate until you dismiss the menu. Not what I would call a particularly user friendly way of doing things.
Camera support on iOS devices is totally hit or miss. If you want to determine if a camera is there you need to use iOS 3.2 and above calls. Seems Apple is not very forward thinking on these things and a lot of stuff gets added in later releases but I can't trust a user to be up to date. Instead I am using a call to get the machine name and basing the availability of a camera off of that. Crappy way to do things but it is working for me so far. I know iPad v1 does not have a camera and you have to be up to iPod (the iTouch) version 4 before you have a camera. The simulator never has a camera which sucks. On the Android side it simulates the camera by showing interface then returning a stock image. I had to test camera usage on an actual iOS device and I have to make sure it has a camera otherwise you get a nice crash. I don't even want to show the [Take picture with Camera] button in the UI if you don't have one.
Which brings me to the another WTF? for Apple. Why are Action Sheets index based? If I remove a button from my Action Sheet it shifts the index of all the buttons below that. Hard to write generic code and you always have to edit two places for each action sheet change you make - once where you create the buttons on once where you respond to their presses. Each button should call its own method or at least you should be able to assign tags to them so you can have one case statement. Honestly assigning tags to UI items seems pretty stinking crappy too. I do it where I can to keep track of things but it is not the most object oriented way of programming.
Some of my buttons had the dreaded "..." on them depending on what I ran it on. No device fragmentation here boys, move along. They were working find on the iPad 2 and both iTouch devices but not on the iPad 1 or an iPhone with an older version of iOS. I had to shorten the text on all devices to make sure it fits.
I have no idea if the Doctors will keep their phones up to date. At this point - pre iOS 5 - there are not OTA updates. If a Doctor never connects his iOS device back to a PC running iTunes he will have no idea there is an update out there. Will be interesting to see what iOS versions we have connecting once we roll this thing out into the wild. I have tried to test on as many iOS flavors as possible and each time I seem to find a new issue.
The app ran fine on the Xoom but the home screen needed to scale better. I searched the web and found new graphics for that area. With more room using larger fonts also seemed the way to go so I tweaked a few other XML files. I ended up creating a new values-xlarge directory under the res directory to hold a styles.xml file for the tablet. I find the way Android handles this to be super easy. I had to go back into a few of my other XML files to make sure they were using the named styles but that was all. I only have a few files in my layout-xlarge and layout-xlarge-land directories to handle all the changes I wanted to make on the Android Tablet.
Android does handle your app getting kicked out out memory in a way that screwed with our app. We have some global static data (I know wrist slap in order) but I need it for the SQLite database and some other login credentials. When you get booted from memory the OS tries to run your onCreate method of the visible view again. For most apps this would be great, you just pretend you started fresh and go. But with the global variables this is not so fun. I added enough checks that I don't [Force Close] any more but tell the user that the session has expired and they need to login in again. I kick them back to the login screen to get going with a fresh database and session variables.
Initially testing this case was a royal pain. You needed to leave your phone on overnight or run so many apps that it got kicked out of memory. Of course that is stupid and a few internet searches pointed me in the right direction. Fire up the emulator, run your app, use "adb shell" from the command line then "ps" then "kill #id" of your process. This will cause same sequence of events to occur. I brought up each possible activity / view and did that over and over until they all exiting clean to the login screen. You can't do this when running on a device but you can use the DDMS view in Eclipse and hit the red [stop] button to achieve the same results.
Once you start running on a real device, especially a dual core tablet, you hate to go back to the emulator. Of course QA came and took the tablet a few days after I had it in my hot little hands so I am still missing it. So much nicer to type on it and code changes are sent over to it and are up and running in a blink of an eye.
Now for my iPad experience. You can set up a universal binary in Xcode. Once you do that it will automatically switch you to the latest version of iOS as your target which is not a good thing. I wanted to target 3.0x as the minimum iOS version. Since Xcode is smarter than me things quit working on my iTouch until I figured out what it did. Simple enough to change that back.
Initial runs on the iPad looked like initial Android tablet runs. Most things looked pretty good as I was using list views and text editors. The home screen looked crappy though. I was able to use my @2x images for the retina display on the iPad. I used the stretchableImageWIhtLeftCapWidth to simulate the nine-patch image I was using for the shelves on the Android.
topShelf = [[UIImageView alloc] initWithImage:[shelf stretchableImageWithLeftCapWidth:25 topCapHeight:0]];
Worked like a charm and was much easier than I assumed it would be. I had to put in manual positioning code for each of the icons on the shelves for the iPad but there are only 6 images so that was easy enough.
I am adjusting for the height of the status bar in my code too. On the iPhone the status bar height is different between portrait and landscape but it is one height on the iPad. I put code in place to handle those special situations and everything looks pretty darn nice.
Since I have more title bar room I wanted to show the practice name on the home screen. Of course that changed the "back" button on any screen that launched from the home screen which is not what I wanted. Turns out you can do this:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
self.navigationItem.title = [NSString stringWithFormat:@"Home - %@", [RESTCaller practiceName]];
UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
[self.navigationItem setBackBarButtonItem:backButton];
}
That code allows you to set the title text to one thing but the back button used by all other areas to something else. Not the way my mind thinks but I understand the logic behind it now that it is in place.
I want to increase the font size on various screen on the iPad. Since there is no real layout manager for iOS, everything is hard coded for widths / heights in the XIB file, this is a royal pain. You can either do secondary XIB files where you have to tie everything exactly back to the code via drag and drop or you can try and tweak things in code playing with bounds and what not. Both are sorry excuses for layout editing. I have made slow progress in this area but find the amount of work involved to be stupid.
The iPad cannot use the same call to show the picture gallery as the iPhone. I had to update the code to make the new call to show a pop-up image picker instead of a full screen gallery picker. I hope that is the only API I am using that they changed on me. Rough one to find, good thing we have QA to beat on it.
UIActivitySheets don't exactly work the same on the iPad either. They show up nice and centered but if you rotate the device while you are displaying one it will not stay centered. It stays relative to its original position. Looks ugly but this will be a really rare case so I did not fix it. There are some suggestions on the web as to how to fix it but nothing worked for me. The only thing left to consider is killing the sheet when you get a rotation notice and recreating it so it shows up in new orientation centered again. Of course if you do that really quickly you will have a new set of issues. Not worth it at this point. I see Apple cheated in this respect. Long tap a link on a web page. It pops up a menu. Rotate the screen. The Screen will not rotate until you dismiss the menu. Not what I would call a particularly user friendly way of doing things.
Camera support on iOS devices is totally hit or miss. If you want to determine if a camera is there you need to use iOS 3.2 and above calls. Seems Apple is not very forward thinking on these things and a lot of stuff gets added in later releases but I can't trust a user to be up to date. Instead I am using a call to get the machine name and basing the availability of a camera off of that. Crappy way to do things but it is working for me so far. I know iPad v1 does not have a camera and you have to be up to iPod (the iTouch) version 4 before you have a camera. The simulator never has a camera which sucks. On the Android side it simulates the camera by showing interface then returning a stock image. I had to test camera usage on an actual iOS device and I have to make sure it has a camera otherwise you get a nice crash. I don't even want to show the [Take picture with Camera] button in the UI if you don't have one.
Which brings me to the another WTF? for Apple. Why are Action Sheets index based? If I remove a button from my Action Sheet it shifts the index of all the buttons below that. Hard to write generic code and you always have to edit two places for each action sheet change you make - once where you create the buttons on once where you respond to their presses. Each button should call its own method or at least you should be able to assign tags to them so you can have one case statement. Honestly assigning tags to UI items seems pretty stinking crappy too. I do it where I can to keep track of things but it is not the most object oriented way of programming.
Some of my buttons had the dreaded "..." on them depending on what I ran it on. No device fragmentation here boys, move along. They were working find on the iPad 2 and both iTouch devices but not on the iPad 1 or an iPhone with an older version of iOS. I had to shorten the text on all devices to make sure it fits.
I have no idea if the Doctors will keep their phones up to date. At this point - pre iOS 5 - there are not OTA updates. If a Doctor never connects his iOS device back to a PC running iTunes he will have no idea there is an update out there. Will be interesting to see what iOS versions we have connecting once we roll this thing out into the wild. I have tried to test on as many iOS flavors as possible and each time I seem to find a new issue.
One other big area I can into was the 1 meg blob limit of SQLite. We are taking pictures with the built in cameras and they can easily be over 1 meg on an Android. The lackluster camera on the iPad and the iTouch don't get you into trouble but an iPhone can. I use JPEG compression to shrink the image down as needed to avoid SQLite issues. It is a shame the iPad camera is so limiting in resolution. It is an unusable solution for our doctors, the images of sheets of medical paperwork are not readable with that camera. We also allow you to choose images from the device gallery which could easily be from another device and over the 1 meg limit.
Overall it was not very difficult to get a universal app running on either the Android or iOS platforms. We are not taking full advantage of the tablet form factor but at least we are not just doing a 2X version of our iPhone app, the images scale up nicely without being blurry, you get to utilize the extra space of the device and things look native in general.
QA is doing final testing then it will be off to the beta clients. It will be really interesting to get their feedback. Now I just need a little time to destress and I get ready to head back into Java + Swing + MigCalendar land to fix some issues in our appointment application.
Labels:
android,
development,
ios,
ipad universal,
iphone,
tablet
Subscribe to:
Posts (Atom)