Notes on developing web apps for phones and tablets

A few notes on developing web apps specifically for phones and tablets. My goal is to create a toolkit that makes it easier to build a web application with a small UI that can scale from phones to tablets to desktop browsers, and gracefully handle orientation changes.

Some assumptions:
• Layout will be different in landscape and portrait modes.
• You might want to pack more stuff on tablet pages than phone pages, for example.
• The dektop version could simulate a tablet or phone layout by placing the controls inside a pre-sized rectangle in landscape orientation, centering the rectangle on page.

Some issues:
• Safari on iOS seems most reliable at handling orientation changes.
• Firefox on Android has a different event/property for orientation changes than WebKit. It’s possible to hack support into your Web Edition app with some JavaScript when the first page opens in your session. There’s a feedback report on this issue:

      <[https://xojo.com/issue/27846](https://xojo.com/issue/27846)>

• WebSession.BrowserType and WebSession.PlatformType need constants for Windows Phone and Tablet. However, IE on these devices doesn’t seem to have orientation events/properties yet.

      <[https://xojo.com/issue/27849](https://xojo.com/issue/27849)>

• If you want sound, like for games, it’s easy to whip up a simple sound player. I added one to Studio Stable Web Essentials last week. However, the Chrome Android people think sound should only be played in response to a click. A click in a Web Edition app that talks to the server, and then your Xojo code sending back a command to play the sound doesn’t count. It’s easy enough to detect Chrome on Android and set some onclick events via JavaScript, but that doesn’t solve the issues of page startup sounds or sounds played in response to logic on the server side.
• Knowing the orientation, and not just deducing it from the width/height, is important on Android because in both Chrome and Firefox, the page is resized when the onscreen keyboard is displayed. You can be holding the device in portrat mode (width < height), tap in an edit field, keyboard shows, then you get a resize that shows width > height even though you are still in portrait mode. If you’re wholesale rearranging controls from portrait to landscape, the edit field might jump elsewhere while you’re typing. So it’s imperative to know what the device thinks its orientation is.
• Chrome on Android (and Firefox w/a JavaScript hack) tries to send the resize event first, then the orientation changed event. But often enough, the server gets them out of order. Recall from last point, that you need to both the size and the orientation of the device to arrange controls correctly. Since the order that you get to handle these events is not guaranteed, I arrange controls in response to both events.
• Occasionally, your requests to move controls get lost in a reply that the browser bails on or loses, typically leaving your controls laid out for the wrong orientation. You might think using a tap in the main window to arrange controls would help. It won’t, because on the server side, they positions and sizes are correct, as you set them. Not so on the client side.

As I understand it, the last two issues should go away when we get WebSockets, as a single bi-directional channel is kept alive and commands are necessarily serialized, so everything on both sides happens in order.

There are some great possibilities for apps in this space, targeted rather than just tolerant of mobile devices. Xojo is fairly serviceable for creating such apps that run well on what most people have. But there are definitely some issues to watch for.

For what it’s worth, just adding constants for windows phone and tablet don’t get you much. We still need to add all of the hacks for the appropriate browser(s), assuming there is something like IeMobile.

On the topic of event order. It’s not the server that gets them out of order. You need to remember that two messages from the same browser often take two very different routes back to the server. So if the first event takes a longer route than the second event, they’ll arrive in the other order.

Greg,

The constants at the very least let me know the general form factor. For example, on a phone or tablet, I know the user can’t arbitrarily resize the window. For the most part, it will stay about the size it starts, close to if not at full screen.

I know the server isn’t processing things out of order. As long as the client is establishing a new connection for each message sent, order isn’t guaranteed. However, the two-way protocol could potentially be more robust if the client assigned an incrementing message number, and the server waited for them in order. Similarly on the client side, it would be better if responses from the server had an order and were processed in that order. We’d get this implicitly with WebSockets, of course.

I have a sneaking suspicion that letting my WE app serve the pictures is what’s bogging everything down. It’s possible enough, even with dynamic pictures, to offload that serving duty to Apache, so that’s what I’ll try. The pictures aren’t a lot of data, and I’m currently testing on my local network.

Looking at Microsoft’s website, it doesn’t look like we can tell if the device is a tablet or a phone. What we can tell is if it is a touch device:

http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx#touch

For the time being, if you already know that it is IE, you can just look at the user-agent header and see if it contains the word “Touch”

Unless you’re doing something special with a custom control, lots of pictures could bog you down as they all get loaded into memory. One trick you might use is to make the WebPicture objects global and set the WebPicture.Session property to nil. That will allow you to keep just one copy of each picture in memory.

Hi Brad,

My WE app show the search screen and after found some record, show the thumbnail and finally and enlarged image of the one image.

What is the best way to accomplish this?? I am using WebPicture and loading and unload images.

[quote=17891:@Greg Olone]Unless you’re doing something special with a custom control, lots of pictures could bog you down as they all get loaded into memory. One trick you might use is to make the WebPicture objects global and set the WebPicture.Session property to nil. That will allow you to keep just one copy of each picture in memory.
[/quote]

Well, this bog down turned out to be related. I had intended to make each picture available to all sessions, but had not set the WebPicture.Session property to nil. Mobile browsers weren’t happy being denied pictures after the first session, turned flaky.

Also, Windows Phone IE user-agent, as of January 2013:

http://jonathanstark.com/blog/windows-phone-8-user-agent-string

Not sure where this is documented on Microsoft’s site.

[quote=17908:@Richard Duke]Hi Brad,

My WE app show the search screen and after found some record, show the thumbnail and finally and enlarged image of the one image.

What is the best way to accomplish this?? I am using WebPicture and loading and unload images.
[/quote]

I feel like I’ll know this and have an in depth practical explanation in about two days :-). In the app I’m building now, the collection of pictures is fixed over the runtime of the app, and each client will see most of the pictures early. Presumably, they’ll remain in browser cache. Sounds like your pictures are more dynamic, less likely to be in browser cache when needed.

Basically the WE app is not going to be use by many people… max 5 user… min 1 user. the WE app is just a web front end to the client stock, so i need to do search on certain word or words and then show what stock item is there.

So you are right about it being more dynamic and might not be in the cache. currently i am using one image for the thumbnail and enlarged image. Do you think it might help if i have a small image for the thumbnail??

Probably. In the app I have right now, I have about 10 different dynamic images – user pictures – that are displayed to each client. They are displayed in a several different sizes, driven by device size. For example, I might want a WebImageView to occupy 90% of the available height and 45% of available width of the particular device in landscape mode. So I set the WebImageView to that size, then compute a WebPicture for it. I cache that WebPicture so that if the same client or a similar sized device accesses, I don’t need to calculate the picture again. Having 5 clients (2 phones, an iPod Touch, 2 tablets) bang this thing on my LAN, I barely peak at 5% CPU on my MBP for that process. Ideally, the clients are caching the pictures as well, so I only have to ship one out when a new size is encountered for the client.

In short, try it and benchmark it. If it performs well enough, that’s great. If not, dig into what the bottleneck is.

thanks Brad.