пʼятниця, 18 листопада 2011 р.

Flight status data providers

In response to Flight status API StackOverflow questions:
There's no free opportunities on this market unless you scrap web results of one of the paid services. With our experience when you start scrapping web results you are promptly spotted. The scrapped site might continue to give you web results but with a rather long lag e.g. 10 secs. This can be OK for the development stage but is too much for production.
We are using XML based FlightAware API. They are the cheapest data provider we found. If you make up to 10K queries per month (Class 3 queries that we employ) you pay only $0.002 for a query. With more queries a fee for a single query decreases. Down to $0.0003 if your application is lucky to generate millions of queries per month. See pricing for details.
FlightAware has excellent coverage of US flights (including non-passenger) but European and especially Asian sectors are missing a lot. There are too many non-US airports and airlines are not supported by the service.
Our statistics shows that we have 35% of searched flights not found by FlightAware for 60% of our customers in Europe & Asia. This is rather dissatisfying and we plan to employ FlightStats API for flights not found by FlightAware. Unfortunately each FlightStat query will cost us triple of FlightAware (see FlightStats pricing).

FlightStats API is used by a handful of mobile app in the Apple's AppStore Travel section. We've analyzed customer feedback for several of them and found that FlightStats tends to provide reliable flight status data all over the globe. Nevertheless we found some complaints on their data accuracy.

Flightradar24 might look like a good alternative if you are interested only in European flights. Unfortunately it looks like there's no public API now. We didn't contact developers directly as Jets app requires world-wide coverage.

неділя, 14 серпня 2011 р.

Objective-C memory management - copy method and retain cycles

I've been hunting for memory leaks in the Jets project this afternoon. One of the things I love so much about programming is that you keep finding new and amazing things day after day.

While trying to remove a leak today, I found out that copy method of immutable objects complying to NSCopying protocol may not actually copy. Sounds weird? It just doesn't make a copy of the object but rather returns same object with incremented retain count.
According to this article - Assign, retain, copy: pitfalls in Obj-C property accessors - this behavior is immanent to NSString immutable class. Well, why do you need a copy of an NSString if it's immutable and its content cannot change?

Another article I would like to recommend in connection with my leaks-hunting is Rules to avoid retain cycles from the same Cocoa with Love blog. I can remember reading it two years ago but it's still fresh and important. I think it becomes even more important with the announced compile-time garbage collection in iOS5.

субота, 30 липня 2011 р.

Network Link Conditioner for poor connection testing

According to this post, there's now a network link conditioner in the new Mac OS X Lion. It looks like there's no more need to run across the city trying to find a place with poor connection in order to see how an app will behave or configure ipwf. You can just set the connection type and quality you are about to test for.

If you still use Snow Leopard (like I do) or you want to configure the downlink to a particular bit-rate, you can use ipwf on your Mac.

понеділок, 13 червня 2011 р.

JQTouch - makes web closer to mobile (Beta 3)

I've just checked out the appearance of JQTouch and the abilities it gives to develop HTML interfaces which closely resemble native iPhone interfaces (can't wait checking it on the iPad ).

Open http://j.mp/EOjPS from your iPhone and check it yourself.

Tables and grouped tables are looking very nice and behave pretty much like native. This alone is enough for me right now to quickly develop a tree of information pages for my application. HTML coding is generally simpler and can be faster accomplished. The system feedback is much faster (no boring builds :) ).

The framework also provides a set of animations and input elements which will help to build a certain number of apps non-distinguishable from native. I guess there are more and more HTML apps appearing in the AppStore nowadays. I can remember seeing a document processor app (like Quickoffice) developed using HTML5 but cannot remember its name.

The developers said on the website that even Swipes (!) are supported but I didn't succeed swiping through the table cells.

I hope that getting web interfaces closer to native ones will facilitate more and more web-sites looking just like native app from your iOS browser (probably same is true for Android). The WWW will unite with Mobile ;)

вівторок, 7 червня 2011 р.

XCode - Custom build rules

I did think that the only way of customizing XCode build system can be a "Run Script" script.

Cocoa with Love opened for me the world of custom build rules that can be applied onto a certain subset of project files - Custom build rules, generated tables and faster floating point.

понеділок, 30 травня 2011 р.

iPhone SQLite data encryption - SQLCipher and CommonCrypto

If you ever need to encrypt an SQLite database for using it within an iPhone app you basically have 2 options (if you don't want to invent a wheel):

- CommonCrypto library. It's a part of the iPhone SDK but not "explicitly". Apple's Security Coding How-To's says "The CommonCrypto library is used for symmetric encryption, hashing, and HMAC operations". If you don't want to go deep into CommonCrypto methods right now you can check an AES-256 Encrypt/Decrypt NSData extension ( The details can be found in Apple's manual, don't forget to link CommonCrypto framework to your project). You can use CommonCrypto methods to encrypt the contents of some of your SQLite table fields.

- SQLCipher extension to SQLite from Zetetic. It seamlessly integrates into SQLite library on the file page read/write level and uses OpenSSL to secure your data. All you have to do in your code is to provide a key to use with your encrypted database.

You can enjoy it right after you managed to build OpenSSL and SQLCipher. I suggest you using this tutorial on MobileOrchard. The tutorial on the sqlcipher.net is almost identical (except it contains just a bit more information) but the images are missing. So combining these 2 you will definitely build the library sooner or later - I spent a bit more time than expected due to my mistakes and some flaws in the tutorial.

Guys from Zetetic promises that the encryption will slow down DB operations not more than 10-15%. CommonCrypto might probably be faster if you need only a fraction of your data to be encoded. In case you want all fields to be secured SQLCipher should be the option.

Using encryption inside your app is a controversial issue due to the US export restrictions. There's a step in Apple's app publishing where you need to specify whether your app uses encryption. Stephen Lombardo insists in his blog post that using any kind of encryption including HTTPS requires a special export authorization. There are also some rumors on the Web. I suggest you to read the post, google around and take your own decision - getting the export authorization might be a cumbersome process.

пʼятниця, 20 травня 2011 р.

CGAffineTransformInvert - singular matrix error

Being inaccurate with affine transformations (and in some other cases) you can easily get a kind of this CoreGraphics error:

<Error>: CGAffineTransformInvert: singular matrix.

There are at least two possibilities why you get this:

A) Probably you tried to use singular transformation matrix somewhere in your code. You should check your transformation matrices and avoid matrices like:
0 0 0
0 0 0
0 0 1
and others - check out Google how to tell singular 3x3 matrix (hint: it has determinant = 0).

B) What can be worse - you don't have a clue about affine transformations and matrices and have never used them in your code but still get this error. One reason I have found is scaling you UIScrollView instance to 0 scale using either setZoomScale:animated: method or zoomScale property. Check your scroll views.

четвер, 14 квітня 2011 р.

Sorting NSArray with blocks

iOS4 blocks introduced a new way to sort NSArray. There is no need to provide selectors or functions as comparators any more. All you need is to provide a comparator block which returns one of 3 NSComparator values and take to objects as an argument. The input and output is same as for the outdated selector/function way (you can hardly change general comparator interface) but now your comparator block captures you function context! Additionally all the code is in the same place.

Below is a bit of my recent work code that changes the order of sorting based on the class instance variable m_seatQuality value:

featuresArray = [[unsortedFeaturesArray sortedArrayUsingComparator: ^(id a, id b) {

DMSeatFeature *first = ( DMSeatFeature* ) a;

DMSeatFeature *second = ( DMSeatFeature* ) b;

if ( first.quality == second.quality )

return NSOrderedSame;



if ( eSeatQualityGreen == m_seatQuality

|| eSeatQualityYellowGreen == m_seatQuality

|| eSeatQualityDefault == m_seatQuality )


if ( first.quality < second.quality )

return NSOrderedAscending;


return NSOrderedDescending;


else // eSeatQualityRed || eSeatQualityYellow


if ( first.quality > second.quality )

return NSOrderedAscending;


return NSOrderedDescending;



}] retain];

пʼятниця, 8 квітня 2011 р.

Know your place

Jets app, designed to make you fly with ease. Our promo site is eventually released to the public. Next - AppStore submission. I hope to show you my dream app pretty soon :)

WARNING! Creating precompiled collator because collator is out of date. This is expensive!

Today I've found a nice iOS warning every second time I start up my application on the device: "WARNING! Creating precompiled collator because collator is out of date. This is expensive!". Apple's programmers are informative about the consequences but not that much about the causes. I don't get any other errors or warning.

Google also can hardly help to comprehend what's happening. There are only some anecdotal evidences that it happens on iOS 4.2.1 - same as my device is running. Some other sources suggest that the warning is due to framework bug and I will get rid of it tomorrow after iOS 4.3 installation (or iPhone SDK 4.3 setup).

вівторок, 29 березня 2011 р.

whiteboard distribution

Having a team of 3 persons currently working on a project from 2 different locations we are using DropBox service heavily for all our images exchange (with source codes stored in SVN). Although there are a lot of free online sketching tools in the market, we opt for a standard office whiteboard you can find in any shop out there. It does cost some money but speeds up drawing and discussion just around it a lot! A single problem with the whiteboard is that you cannot save its state with a single mouse click. The easiest solution for this we found using DropBox iPhone App - 4 taps and the current whiteboard status is saved to the DropBox folder shared to all the team members.

Now the only problems you might face - no version control, if you file system doesn't support it, as well as some non-frequent bugs and lags of the service. No software is ideal unfortunately.

пʼятниця, 25 березня 2011 р.

iOS blocks aka closures

iOS 4 blocks (Apple's closures) are awesome! Much more power for callback code and asynchronous execution. Though blocks require a bit more attention to memory management then function calls due to capturing calling method variables.

On the other hand, my tests with calling UIKit code adding 322 labels of 2 latin alphabet length each to the view controller yielded 3.5 seconds of execution on the main thread. Compare this with about 10 seconds of execution through dispatch_async call on the global queue with HIGH priority having nothing else added to this queue (iPhone 4 device). At his point more information required to compare blocks performance to exclusive thread execution. Or does it have something to do with non-thread-safety of UIKit?