Sunday, 6 September 2009

MKMapView overlay

This short blog post will be for iPhone OS v.3.0 programmers who use MapKit framework for displaying maps in their iPhone applications.


I faced a problem with MapKit which other programmers on the internet also seem to have, but I couldn't find a solution anywhere. But let's start from the beginning:


Why I have encountered the problem

I wanted to display map scales on top of MKMapView, so I have created MapScales subclass of UIView. My MapScales class has a reference to MKMapView and whenever it is displayed (drawRect is called), it checks the distances on the currently shown rectangle on MKMapView and draws nice scales. I made my MapScales instance semi-transparent and put it on top of MKMapView in my hierarchy of UIViews. Next I wanted my MapScales to be dispayed only when at least two user's fingers are on the map - so that the scales are shown only when the user pretends to zoom in or out. So I had to intercept the touch events in my MapScales. And here is:


The problem

MKMapView doesn't work correctly when it is not the first interceptor of touch events.


What happens:

  • Some of the standard animations in MKMapView are not working any more.
  • MKMapView is still usable, but it doesn't react to standard user interactions in a normal way any more.

When exactly it happens:

  • When some other component (like my MapScales) intercepts the event first, and then sends it to MKMapView.
  • It doesn't matter of the other component (MapScales) is a subview of MKMapView or a subview of MKMapView's superview.
  • It doesn't matter if the other component is sending events directly to MKMapView's instance or to the object obtained by calling hitTest:withEvent: on MKMapView's instance.
  • I also tried to fix the problem by making my MapScales a subview of MKMapView, but I couldn't get a satisfactory solution.

I don't know what causes this problem, but I suspect that MKMapView's behaviour may depend on UITouch'es read-only view field, which will be different whenever MKMapView is not the first event interceptor.


Well this problem is so ugly, that it invalidates the benefits of creating MapScales in my application.


My solution

It is not very clean solution, but it let's you create the MKMapView overlay that intercepts the events and doesn't spoil MKMapView's behaviour.

Before the events are distributed to UIView hierarchy, they first get to UIWindow, so I have created a UIWindow subclass (MyMainWindow) and made the main window of my application an instance of MyMainWindow. Then inside MyMainWindow I have implemented the method:


- (void)sendEvent:(UIEvent*)event {

[super sendEvent:event];

[listeners sendEvent:event];

}


As you can see I have also implemented a simple mechanism of observing MyMainWindow (listeners attribute). Then I have registered my MapScales instance as MyMainWindow's listener.


Of course I also had to disable user interaction flag in my MapScales instance, as now it is getting events from different source.


This solution has some disadvantages. For example, MapScales always gets all touch events, even when the user touches something else than the map - this is the price of skipping standard event delivery mechanism. Though it works very well for me.


If you find a better solution, please let me know.

Tuesday, 9 June 2009

Symbian S60: Orbit and DirectUI vs Avkon

It has been revealed on http://blog.symbian.org/ that a new UI framework will be added to Symbian OS and that most probably it will replace the old Avkon completely. It will be built of:
  • Qt libraries ported to S60
  • Orbit - a new set of mobile-specific widgets built over QT
  • Direct UI - a new UI layout & logic
The change is planned to happen in Symbian^4 which should be functionally complete by the end of July 2010 and hardened by the end of 2010.

Looks like long time to go, however it is a huge compatibility break which will make all current S60 applications unusable on new Symbian, so it is worth to prepare for it in advance.

How can we prepare?
Symbian should publish the new components (Orbit, Direct UI) soon, as it has done with Qt port to S60, so that we will be able to experiment with them early and port our applications to the new framework. I'm sure it will not be not easy, but if you want to feel better think that Nokia will have to port all standard S60 applications too. If particular application is well-written and is using things like MVC pattern for separating UI layer from the application logic, it should be enough to rewrite its UI layer. However, I guess in many cases most of the code of the application will have to be re-written. This is why this planned compatibility break has the potential of being very painfull for the application developers and many of them are already lobbying against it. So here is the lesson: whenever creating an app remember about separating the UI from the rest of it!

Or if you are a manager, whenever you need a software engineer for porting an application to Qt / Orbit / DirectUI, I'm ready to help you or I can help you in finding the right person for doing it!

Benefits of the change
Symbian's decision of replacing Avkon with Qt completely is very probable, but it hasn't been confirmed yet. Regardless the problems it creates, it also has many advantages:
  • Avkon is quite old and maintaining compatibility has always been costly in terms of complexity of the Symbian OS code, quality of the new Symbian APIs and the innovation. 
  • Given the competition from Apple, RIM, Google, Palm etc. isn't it the time to start from scratch with beautiful QT APIs loved by thousands of developers?
  • I guess that in some cases maintaining Avkon apps would be more expensive to application developers than re-writing them for Qt. Compare Avkon hello world application with its Qt version: Avkon -> many classes and files, Qt -> 10 lines of code, as in my previous blog post.
Why not use both Avkon and new DirectUI on one phone then? This would allow us to be in the Qt heaven without breaking compatibility.
  • Avkon takes lots of phone's resources, like memory. This adds to phone's Bill of Materials.
  • The old-style Avkon applications wouldn't integrate nicely with new Direct UI in terms of look&feel.
  • Avkon is heavy. It would be a huge cost for Symbian contributors to maintain Avkon backward compatibility and possibly it would constrain the new framework.
Symbian is far from being as successfull in providing third-party applications to the end users as Apple is, which probably makes the drastical decision easier. Such decision is also another impulse to use Qt, which is now promoted by Nokia as its multi-platform technology.

Still, as Symbian is Open Source, some third party developers may try to port Avkon back to Symbian^4. We will probably see the results of such trials soon.

Tuesday, 28 April 2009

Deploying S60 Qt application to single SIS file

Aim of today's experiment:
  • To create one S60 installation file (SIS file) containing an arbitrary Qt application and all binaries necessary to run it on the phone (Qt binaries among other things).

Benefits of doing so:
  • The user of Qt application doesn't have to download and install Qt libraries separately, before installing the application.
  • While uninstalling the application, Qt libraries will be uninstalled automatically - the user doesn't have to remember to uninstall them separately,
Preparing single SIS file with libraries embedded inside of it is not a difficult task, however I thought that many people, especially Qt developers with no prior Symbian experience, are not aware of such possibility.

In order to make things easier, I will go step by step through the whole process, from installing SDK to running Qt application on Nokia E71 phone. As always in mobile world, things are not as easy as writing several lines of code and pressing 'Run' button in the IDE, so some people may find this guide helpful. Of course, I'm not able to describe here all the trouble you may run into, however if you find a problem please email me, and if I know the answer I will add a note to this post.

First... some basic backgroud:
  • Qt is not pre-installed on any mobile phone because it is very fresh technology in hands of mobile phone vendors.
  • So you need to install Qt on the phone first before installing your Qt application.
  • The latest Qt for S60 release is called Garden. You can find more information and download it here.
  • While installing the Garden release, you will build it for your S60 emulator, as descibed on the web page mentioned in the previous point.
  • After building Qt libraries for emulator you can create your Qt application using Qt APIs and build and run it on the S60 emulator too.
  • In order to install your app or the real phone, you neeed to build it for hardware and create an installation package (SIS file).
I will go step by step through creating the application and building for hardware until I have single SIS package that can be installed on Nokia E71 phone. However first there is some...

Legal stuff worth considering before you proceed
Qt Garden release is distributed by Nokia under Technology Preview Licensee Agreement. This means that you can use it for evaluation, but you are not allowed to distribute it to other parties, so please be careful! Hopefully properly licensed Qt for S60 will be released soon.

Step 1 - Prepare the environment
You have to download and install:Step 2 - Create the application
For the purpose of this blog post I have used very simple Qt application. You can do the same by creating hello_world directory for the application and then put the following content into main.cpp inside this directory:
#include <qapplication>
#include <qpushbutton>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QPushButton hello("Hello Anand!");
hello.resize(100, 30);

hello.show();
return app.exec();
}
[Anand is the guy who has lent me his Nokia E71 for a while so I could perform this experiment]

In addition to main.cpp I used simple Qt project file hello_world.pro:
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
Input
SOURCES += main.cpp

Step 3 - Preparing build files
First we need to generate Symbian build and configuration files out of Qt .pro file. In order to do so:
  • Start command line and change directory to hello_world
  • Invoke the command:
    qmake
Lots of files will be generated by qmake, saving us a lot of trouble - normally Symbian developer would have to create these files manually, and their syntax is not too obvious. Among the files we have:
  • Symbian build files: bld.inf and .mmp file.
  • pkg files that will let us create SIS files for the hardware.
    • pkg file describes the contents of SIS file and acts as input for SIS-creation tools.
    • one of them will be hello_world_armv5_udeb.pkg which will describe package with debug version of hello_world targeted for the hardware. Please remember that as SIS files contain binaries, you need separate SIS file for each platform (ARM hardware or emulator).

Step 4 - Building for emulator
Now you can build the application for the emulator by invoking the following Symbian build commands from the command line:
bldmake bldfiles
abld build winscw udeb
As result the exe file with your application should be built in your SDK directory under epoc32\release\winscw\udeb. You can enter that directory and execute the exe to see how it works in the emulator.

Step 5 - Building for hardware
Invoke the following command from the command line (you don't need to invoke bldmake bldfiles now as this has already been done in Step 4):
abld build armv5
If everything goes right, executable files for the mobile phone should be created under epoc32\release\armv5.

Step 6 - ESSENTIAL IN THIS GUIDE - Modifying pkg file
Now we can think about creating the installation file (SIS file) for the Nokia E71 phone. We already have the specification of the SIS file hello_world_armv5_udeb.pkg generated by qmake. We could use it straight away, however first we would like to change the pkg file so that Qt binaries are be embedded into resulting SIS file together with our application.

Let's first copy the required binaries into our application's hello_world directory so that we can easily point to them from the pkg file:
  • Qt binaries
    • They are located in qts60binaries subdirectory of Qt installation directory.
    • There are two versions of binaries located in separate subdirectories: 3.x and 5.0. We will use the version from subdirectory 3.x as Nokia E71 works under 3rd edition of S60.
    • The file to copy is: qt_libs_armv5_udeb.sisx
  • PIPS binaries
    • This is Nokia Open C/C++ library. It is necessary to include this library for Nokia E71 as Qt depends on it. Newer Nokia phones with latest versions of S60 will have this library pre-installed, so there will be no need to include it in the SIS file.
    • Please download the library here: http://www.forum.nokia.com/Resources_and_Information/Explore/Runtime_Platforms/Open_C_and_C++/
    • Name of the downloaded archive: Plugin_For_S60_3rd_Ed.zip
    • And this is the file we are interested in that should be decompressed from the archive to hello_world directory: pips_nokia_1_3_SS.sis .
Now as we have the libraries locally accessible, we can modify the pkg file in order to include them. The following lines need to be inserted in hello_world_armv5_udeb.pkg, just after 'Unique Vendor name' section:
IF NOT package(0x20009a80)
@"pips_nokia_1_3_SS.sis", (0x20013851)
endif

IF NOT package(0x2001e61c)
@"qt_libs_armv5_udeb.sisx", (0x2001e61c)
endif
Of course, if your phone already has PIPS built in, you should skip the first IF statement.

Now the pkg file is ready to use.

Step 7 - Create the SIS file
After pkg file is updated, we can run the command that will create unsigned sis file:
makesis hello_world_armv5_udeb.pkg
The resulting file should be hello_world_armv5_udeb.SIS.

Step 8 - Sign the SIS file
You will probably not be able to install unsigned sis file on your Nokia phone. I will not describe here the various signing methods, however I will help you to run the application on your phone. In order to do so, you can use Symbian Open Signed Online service. It will sign the sis file for development purposes and to be used only on your phone. Application signed in this way will display ''Application is for development use only. Continuing installation may cause serious problems to your device. Continue?'' during the installation.
After submitting the form you should confirm your email by following a link in email message you receive after a while. Then another email will be sent to you with a link to the signed application.

Download the signed application - hello_world_armv5_udeb.SIS.

The Result.
Now you can upload the application to the phone. It should install and work on your phone properly. There will be many annoying messages displayed during the installation, you should accept everything and continue installation regardless of the warnings. One example of such message: 'Component 'Symbian OS PIPS' missing. Continue anyway?' - this may be displayed even several times. Unfortunately I don't know how to get rid of them - any ideas?

And this is all. I hope this guide was helpful. Please let me know if you had any problems not mentioned here. I would be very happy being able to help and fill the gaps in the guide.

Sunday, 5 April 2009

Introduction

I'm a software engineer with 10 years of commercial experience in various industries: internet marketing (Adv.pl), digital tv (Osmosys), mobile applications (Midlet.pl), mobile phone development (Symbian and Nokia). For years I've been a happy employee of corporations - I've been often given exciting tasks such as creating new UI framework that happened to change industry's expectations for good UI (see Osmosys EGG) or optimising graphics performance of newest Nokia platforms. However it was always my dream to become independent technology expert, and as I have been given a chance with Nokia VRP, I'm planning to pursue this dream now.

This blog will be part of the dream. For the beginning, while I'm still on the notice period, I'm planning to publish here some results of my weekend bedroom development experiments. The blog should get up to speed in about three month's time.

I can't forecast what ideas the future will bring to me, however I'd like to focus especially on technologies which I'm using in Nokia now - Symbian S60 platform and Qt framework. As you may already know, Qt is a new asset in Nokia's hands. Given that Nokia is the leading phone manufacturer in the world and Symbian Foundation is going to publish Symbian S60 open source code pretty soon, I believe that very interesting times are coming.