Titanium modules (in)dependency

 

Creating applications in Appcelerator Titanium is quite easy unless you hit serious not-sure-what-it-is-going-on problem. Here you will find out what problems can cause Titanium module itself.

Recently we were asked to fix several bugs in our client’s mobile app. The application is distributed on both Android and iOS platforms and client’s developer chose Appcelerator Titanium framework – write once and run (no|every)where! Time passed by and new SDK has been used to develop new, second version of the app and the problems begun to appear.

Beside minor interface issues it appeared that application on Android was crashing when user was logging out. Additionally user’s position was not marked on the map despite using:

userLocation: true

Also

setLocation()

method was not navigating to desired GPS coordinates.

 

Titanium SDK and Ti.map module

Actually I should thank for this app crash caused by logging out issues as it put a light on that whole maps story. The crash provided a useful clue for that mystery. An exception, holding a key information:

[ERROR] TiApplication: (main) [18,11245] Sending event: exception on thread: main 
msg:java.lang.RuntimeException: Unable to destroy activity {com.*********/org.
appcelerator.titanium.TiTranslucentActivity}: java.lang.NullPointerException: Attempt 
to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.clear()' on a 
null object reference; Titanium 6.0.0,2016/01/05 20:37,11aa940 
[ERROR] TiApplication: java.lang.RuntimeException: Unable to destroy activity 
{com.**********/org.appcelerator.titanium.TiTranslucentActivity}: java.lang.
NullPointerException: Attempt to invoke virtual method 'void com.google.android.
gms.maps.GoogleMap.clear()' on a null object reference

So, inside of Ti.map module for Android something was seriously not OK. After reading carefully the whole application logic, looking for some insane code, and waiting for ‘eureka’ to come, I even copied an example code from docs to make sure everything was used correctly – without a luck. Then I created a sample application that used only example code from documentation and… bingo! The map still didn’t work and crashed in the very same place in the very same style. That lighted up a bulb – a map module!

Turns out that Titanium SDK doesn’t necessarily matches an appropriate modules for its version. I wondered how this version management between SDK and modules is being held. From what I have observed there are no such things. It turned out that downloading latest SDK didn’t download latest Ti.map module (version 2.3.6 at the time of fixing bug) for Android. Installing it manually did the trick and everything started to work like a charm.

 

And what about an iOS version?

Another story was with iOS. Building with latest SDK was working fine and tests (performed on iPhone 5, 5S, 6 and 6S) confirmed everything was fine and app was sent for deployment to AppStore and… it has been rejected due to crash on iPhone 4 (and 4S as well). App crashed in random places, especially when moving the process into the background and restoring the app. This time the logs were not so clear to read as it stated only:

Jan 21 22:48:13 iPhone ReportCrash[498] <Error>: task_set_exception_ports(B07, 400, D03, 
0, 0) failed with error (4: (os/kern) invalid argument)

and

1 22:56:39 iPhone com.apple.xpc.launchd[1] (UIKitApplication:com.**********[0xab7f][502])
<Notice>: Service exited due to signal: Segmentation fault: 11

Playing around with intermediate xcode project build by Titanium I was able to debug it properly and… guess what.

Thread 0 name:  Dispatch queue: com.apple.main-thread

Thread 0 Crashed:

0   APPNAME               0x0053a1be -[FacebookModule handleRelaunch] + 130

1   APPNAME               0x0053a288 -[FacebookModule resumed:] + 16

2   CoreFoundation        0x2bcaa0c2 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_
OBSERVER__+ 10

3   CoreFoundation        0x2bc03cb8 _CFXNotificationPost + 1796

4   Foundation            0x2c96539c -[NSNotificationCenter postNotificationName:
object:userInfo:] + 72

A Ti.facebook module… a module… what a coincidence. Unfortunately, at the time of testing,  I was using latest version of this module (5.0), so I decided to downgrade it to version 4.0.3 and yes, it worked.

Conclusion is that you should very carefully update Titanium SDK and validate that selected modules work properly with your SDK. It seems that there is no strict dependency control between SDK and modules, developer may freely switch between modules and gets no warning when creating a build.