UIWebViews, UIKeyboards, and UIToolbars. Oh My.

You know the toolbar that appears above the keyboard when you tap on a form field in a UIWebView? Its called an inputAccessoryView. You can customize the inputAccessoryView for a UITextField or a UITextInput objects but not for a UIWebView. For whatever reason Apple decided to not support a custom inputAccessoryView for a UIWebView and has instead added their own view with buttons for navigating between form fields and dismissing the keyboard. Sometimes you might prefer to use a toolbar of your own design rather than the default one Apple supplies. While this is possible it is not without certain risks. This article will consider a few techniques for removing the default toolbar in order to replace it with one of your own.

Continue reading

ContentEditable, Rich-Text Editing, and Mobile Safari

Have you had a chance to play around with HTML5′s contentEditable feature? Basically it lets you make any supporting element editable. Its pretty cool, check out the demo.

This feature offers up lots of potential for rich text editing. And, while the Mozilla demo doesn’t show this, you can even insert adhoc html which opens the door to inserting more complex html elements like images, tables, audio and video. It just takes a little extra effort.

ContentEditable is supported in modern desktop browsers but things get a little dodgy on the mobile front. The docs say it is not supported in the iOS browser but this is no longer the case since iOS 5.0. There are, apparently, a few quirks one of which involves the events that an active contentEditable node will dispatch.

Continue reading

Fun with PhoneGap and jQueryMobile

Until recently the iOS apps I’ve worked on have all been native apps — partly because I’ve felt that you get the best quality app from native development and partly because hybrid libraries haven’t supported all the features I needed. Now I can say I’ve built my first hybrid app using PhoneGap and jQuery Mobile and I want to share my experience.

PhoneGap is a light-weight mobile framework that promises to let you build your app once with HTML, CSS and JavaScript and then deploy it across all the major mobile platforms. It basically provides a native wrapper for a web app, exposing a variety of native OS features that would otherwise be unavailable — the camera and photo library for instance.

jQuery Mobile is a mobile targeted version of the popular jQuery and jQuery UI frameworks. It promises to be lightweight, flexible and easily themeable (your mileage may vary) but appears to still be dependent on the core jQuery library.

The app was fairly basic. It would be powered by an API, needed a login screen, a screen to display a list of a user’s saved images, and let a user either upload a new image from their photo library, or their phone’s camera. These are all features supported by PhoneGap, and jQuery Mobile looked like a great resource to get a jump start on the UI. Also, I’d only be concerned with the iOS version of the app… for now.

Continue reading

Preparing Graphics for Multiple Mobile Platforms

If you are a graphic designer preparing graphics a multi-platform mobile app, there are a few things you should know before you start, to make things easier on yourself and the developer implementing your design. This article focuses on the iOS and Android platforms, beginning with a brief overview of the layout tools for each OS, then looking at how to deal with different screens, sizes and orientations.

Continue reading

Strange iOS App Exit When Testing with the Debugger

Today I was testing a new build of an iOS app and experienced what I think is a weird conflict with a previous version of the app. Here’s what happened:

I was testing a developer build of the app on an iPhone 3G running 3.1.2 and an iPhone 4 running 4.0.1. Before testing I installed an updated developer provisioning profile on each device. Everything worked perfectly on the 3G, but on the iPhone 4 the app would show the splash screen for a split second then close. It was as if the app was crashing on the iPhone 4 but there was no crash information showing up in the debugger. As far as the debugger was concerned there was nothing wrong to report.

I opened the Organizer window and checked the Device Logs tab for any crashes but there was nothing regarding the app I was testing. Next I checked the Console tab and saw the following:

Tue Sep 7 15:59:11 My-iPhone com.apple.launchd[1] (UIKitApplication:com.appname[0x2d1][6531]) : (UIKitApplication:com.appname[0x2d1]) posix_spawn(“/var/mobile/Applications/…/AppName.app/AppName”, …): Permission denied

Tue Sep 7 15:59:11 My-iPhone SpringBoard[28] : Unable to obtain a task name port right for pid 6531: (os/kern) failure

Tue Sep 7 15:59:11 My-iPhone com.apple.launchd[1] (UIKitApplication:com.appname[0x2d1][6531]) : (UIKitApplication:com.appname[0x2d1]) Exited with exit code: 1

Tue Sep 7 15:59:11 My-iPhone SpringBoard[28] : Unable to look up event port name for pid 6531: (os/kern) successful

Tue Sep 7 15:59:11 My-iPhone SpringBoard[28] : Unable to send activation event to com.appname animate activate: safe animationStart = 406459.5189769584 deactivate: : (ipc/send) invalid destination port

Tue Sep 7 15:59:11 My-iPhone SpringBoard[28] : Application ‘AppName’ exited abnormally with exit status 1

I Googled for explanations about the different warnings without success. Not knowing what else to do I decided to test the app one more time from a clean slate, so I deleted both the app and development profile from the iPhone 4. I tested again and to my surprise the app launched and worked flawlessly.

So what happened? An ad hoc build of a previous version of the app was already installed on the iPhone 4 and I did not delete it before testing a new developer build. Maybe Xcode 3.2.3 doesn’t completely remove a previous version of an application when testing a new version, and instead only updates relevant parts of the application’s bundle. If the bundle wasn’t updated correctly I suppose it could explain this weird behavior, though I really would have expected the app to be replaced completely or for an outright crash when i tried to run the app.

Anyway, if you are testing your app and you see similar behavior and an error message like the one above try deleting your app from the phone and then testing. Maybe it will work for you as well.

Gripes About Android’s WebView

I’ve been a little disappointed with my experience using Android WebViews. Perhaps naively, I expected WebViews by default to just work and behave the same way as the Webkit-based Browser app. I was wrong. Android WebViews seem to start out as very basic browser implementations and require you to manually enable or implement support for various behavior that you just expect from a browser.

Continue reading

Developing for iOS and Android

I’ve had the opportunity to develop on both the iOS and Android platforms, something that, statistically speaking, makes me part of a minority of developers. My experience has been that the iOS platform offers better tools for developers, but that the Android platform offers more freedom in what a developer can do with a device. I thought I’d share some of my observations on the differences between the two platforms for anyone who is curious what its like developing for the other device.

Continue reading

Apple, what were you thinking?

At the end of June Apple sent a notification out to members of its developer program advising them that all new iPhone apps and updates would have to be built with the iPhone SDK 4. The important bit of the email read thus:

Make sure that your applications are compatible with iOS 4. All new applications and updates to existing applications must be built with iPhone SDK 4. In addition, the App Store will no longer support applications that target iOS 2.x.

This seems reasonable and, by itself, is not a problem as apps can still target previous versions of iOS even though they are built with iPhone SDK 4. The problem arises when you realize that any third party libraries your app uses will also have to be recompiled.

Several months ago Apple purchased QuattroWireless as their ad solution and recently relauched it as iAds. Most third party library publisher will be very quick to provide an updated version of their compiled library (if they don’t just provide the source code), and this is where I think Apple dropped the ball. This is not the case with QuattroWireless, at least at the time of this writing. The existing QuattroWireless library can not be used in apps built with SDK 4 without generating compile errors. The library needs to be republished for the updated SDK, however an email exchange with QuattroWireless reveals they have no plans to do this

As you may know, QuattroWireless was bought by Apple. As a result we are moving forward with our iOS 4.0 support in the new iAd platform. There will be no immediate update to the QuattroWireless SDK to support 4.0. We hope you join the iAd Network for 4.0 ads. Please let us know if you have any further questions

So why not just go with iAds? Including iAds in your app means you limit your audience to just people who have upgraded to iOS 4. Including iAds in your app means your app will not run on the iPad (the iPad has no iOS 4 support at this time). Basically implementing iAds means limiting your potential audience, at least for the time being.

I guess this means all the apps that currently use QuattroWireless and who are unwilling to lose audience by updating to SDK 4 will be looking to another ad solution such as AdMob.

Apple, what were you thinking?

Using ResponseCache in an Android App

I’m currently working on an Android app and I’ve decided to use the java.net package for making HTTP requests. While the java.net package includes support for caching requests it does not include a default caching implementation like some other libraries — apparently Android developers are left to roll their own. I looked into it, and it seemed pretty straightforward to implement the ResponseCache, CacheRequest and CacheResponse classes, but there was a surprise waiting for when I tested my work. It was annoying so I thought I’d share. What follows is a simple example of how to implement ResponseCache, the surprise I found, and how I dealt with it.

Continue reading