Saturday, May 28, 2011

Now for something completely different...

Another midnight/early morning note to my blog so that I don't forget what went in my mind earlier.
  1. The current approach of embedding scripts for all browser support in libraries like jQuery, and embedding all available widgets in libraries like jQuery UI and jQuery Mobile - is completely wrong. The extra parsing and code complexity may not matter for Core i7 desktops, but it really hurts performance in mobile devices.
  2. If the uncompressed size of the .js file of the UI framework for your upcoming mobile app is 1.5MB+ ... you're doing something very wrong.
  3. Narrative JS. Can be used to solve a lot of problems if it works well. I should find some time to investigate this thing.
  4. The current approach PhoneGap is using for communications between JavaScript and Objective-C is very hacky and slow - even though it works. Adding a micro Comet server on Objective-C's side and use Comet for communications will work much better. It sounds crazy, but it's more doable than most people think.
  5. I need to do more screencasts like AFeature's, for those "micro" open source projects (like bson and bson-objc) that I do in weekends - just to brush up my presentation skills.
  6. The current way people do Comet and WebSockets haven't accounted for unreliability at the physical layer on mobile devices (aka. AT&T).
  7. Comet on mobile devices is also not a very good practical idea because (from our experiments), mobile browsers tend to minimize active TCP connections - s.t. even though you can sort of keep the receiving connection "persistent", the send will not. Which means, the send part of your Comet session will have high latency.

Sunday, May 22, 2011

Some predictions and wishlist for the coming year

It's a bit late to do it in May but I'm beginning to find myself constantly forgetting big picture things.

  1. Mobile applications will increasingly be done in HTML5 and wrapped inside something like PhoneGap.
  2. Co-routine I/O libraries like gevent and eventlet, and the whole approach in general irrespective of languages, will take off. Someone will implement an Actor model on top of them to make them work nicely across processes. (note: Pykka doesn't work across processes, yet)
  3. will get more buzz.
  4. CoffeeScript will get a lot more users, especially for those people on Node.js. Writing sophisticated server-side logic in plain JavaScript is crazy.
  5. NowJS will be a flop.
  6. ChromeOS will be a flop - for now. But Google has the money and patience to iterate.
  7. WebSockets and WebGL will remain experimental.
  8. The general direction for software that'll take off are things that are lean and mean - in terms of performance, code size, ease of development, etc.
  9. Everybody that matters will will say UX instead of UI - which means just a good UX will no longer confer significant competitive advantage in general.
  10. The HK government will keep pushing meaningless things like "the wine industry" where a single tech company will easily trump the whole industry in terms of revenue - but they'll keep talking the talk on tech.
  11. HK university graduates still don't know their mainland counterparts from similarly high-ranked universities are already getting a higher salary and maybe 2x to 3x their real purchasing power.
  12. The world will not end tonight, doomsday preachers are nuts.

Saturday, May 21, 2011

An alternative workaround for Mobile Safari's innerHTML problem

One major frustration for mobile HTML5 app developers is that innerHTML in Mobile Safari stops working randomly - often at the most inconvenient times. I met the problem as the PhoneGap project scaled up in complexity in the recent months and random rendering bugs appear more and more often in my app.

There's a clear problem description in this 4-year-old blog page:

The code has been in use for several months without issue and has been working fine all this time in all the browsers I’ve tried it in. For some reason in this one particular scenario though, Safari was completely ignoring the attempts to set the innerHTML of the node. Setting the innerHTML and then on the following line attempting to read it was also giving an empty response. For example:

text = "foo";
node.innerHTML = text;
alert( "html="+node.innerHTML ); // Pops up message saying "html="

I tried numerous methods to fix this problem, including setting the property before and/or after adding the DOM node to the document. I also googled it which flagged up a number of related posts but these generally referred to pages that were served as XHTML (ie. pages with an .xhtml extension and MIME type application/xhtml+xml) and were not offering any solution.

The general consensus towards working around this problem is to set a timer to retry setting the innerHTML value again. (e.g. as mentioned in this page) Such a solution is highly inconvenient and is generally inapplicable, however, because it screws up your programming model - you essentially need to turn the simple operation of setting innerHTML into a callback-like asynchronous operation.

A Probable General Solution

I found an alternative solution yesterday when I noticed that, at the moment innerHTML stops working in Mobile Safari, DOM manipulation operations, like..
element.appendChild(document.createTextNode("Baby you're a firework!"));
.. would still work. What this means is, if you're able to translate the set innerHTML operation into purely DOM manipulation operations, you'd be able to circumvent the problem entirely - in theory.

To do this, I'd need to be able to parse the HTML in JavaScript. That's actually easier than most people think - I've worked with such a parser during my CKEditor days, and it was mostly just a bunch of regular expressions. Even better, there's a standalone JavaScript library for doing HTML parsing written by John Resig.

With that in mind, I wrote a simple JavaScript function that turns an HTML string into a DOM fragment - which in mathematical terms, is simply a forest.

Then, as I'm using jQuery Mobile, I can patch it into jQuery's html function:


Wednesday, May 18, 2011

AFeature - Interactive JavaScript console for mobile HTML5 applications

I created this because I really needed something interactive to debug my PhoneGap iOS project. There is a similar project out there called ibug but it is no longer working.

You can get the code here, and below is a quick screencast.

Edit: Turns out it was unnecessary. I kept searching for Mobile Firebug before I came to the conclusion that I need to write one myself. But someone from the PhoneGap user group told me there's actually a Mobile Web Inspector out there. It's good enough for me for now, although I have to say I don't really like the Java server code in there... looks overly complicated to me.

Monday, May 9, 2011

How to solve "assembler for architecture ppc not installed" errors after installing XCode4

I was upgrading and building a few Python modules on my Mac this afternoon, and I got this error:

Martin-Kous-MacBook-Pro:~ martinkou$ sudo easy_install -U Cython
Searching for Cython
Best match: Cython 0.14.1
Running Cython-0.14.1/ -q bdist_egg --dist-dir /tmp/easy_install-5NQPRk/Cython-0.14.1/egg-dist-tmp-gOLK4r
warning: manifest_maker:, line 19: 'recursive-include' expects <dir> %lt;pattern1%gt; %lt;pattern2%gt; ...
/usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/as: assembler (/usr/bin/../libexec/gcc/darwin/ppc/as or /usr/bin/../local/libexec/gcc/darwin/ppc/as) for architecture ppc not installed
Installed assemblers are:
/usr/bin/../libexec/gcc/darwin/x86_64/as for architecture x86_64
/usr/bin/../libexec/gcc/darwin/i386/as for architecture i386
/tmp/easy_install-5NQPRk/Cython-0.14.1/Cython/Plex/Scanners.c:6694: fatal error: error writing to -: Broken pipe
compilation terminated.
lipo: can't open input file: /var/tmp//ccAtkL0J.out (No such file or directory)
error: Setup script exited with error: command 'gcc-4.2' failed with exit status 1

This error pops up for a lot of build scripts besides Python distutil's - Perl modules like ImageMagik are also failing to build on OSX after Xcode4 is installed. The reason for this is Apple has removed the PPC assembler for OSX platforms in Xcode4, yet a lot of existing build scripts for OSX are building universal binaries.

There're quite a few solutions on the Internet, but the cleanest solution I've found so far, is the second solution (as of today) in this Stack Overflow page.

So it turns out Apple has still left a PPC assembler in the iOS platform files for Xcode 4. All you need to do is to make 2 sym links at the appropriate place and it'll work.

$ sudo ln -s /Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gcc/darwin/ppc /Developer/usr/libexec/gcc/darwin
$ sudo ln -s /Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gcc/darwin/ppc /usr/libexec/gcc/darwin


互聯網站 AirBnB在 SXSW後雖然確立了宣傳手法和自我特色,但仍然是小型搞作,每次只是供應幾十間住房,談不上賺錢。而談不上賺錢,對於創業者是大問題,因為幾個創辦人在三藩市的日常開支,絕不便宜。


AirBnB三人靈機一觸,由早餐想到穀物片,由穀物片想到穀物片背後的品牌和廣告,再由穀物片品牌想到總統大選。於是美國的電視上就出現了:「 Obama O’s: Hope in every bowl!」及「 Cap’n McCain’s: Put a maverick in your morning!」

利用網上宣傳的便利,美國人對總統大選的瘋狂,和前兩次搞 AirBnB網站所認識的傳統媒體, AirBnB推出了以奧巴馬和麥凱恩為主題的早餐穀物片。每款限量推出 500盒,每盒售價 40美元。 1000盒穀物片送 200盒給記者。其餘 800盒讓 AirBnB的名字除在美國迅速走紅之外,還幫 AirBnB賺了三萬美元。

「我對你們的計劃信心不大。」 08年尾, AirBnB三人去了考 Y-Combinator。考 Y-Combinator的原因並不是因為 AirBnB成功,而是因為他們沒錢。賣穀物片的 3萬元只是還了部份信用卡欠款。在全國電視一輪風光過後, AirBnB網站依然沒人流,沒收入,很快便被人忘記。折騰了一年,結果碌爆信用卡,晚餐只好吃麥凱恩和奧巴馬。考 Y-Combinator,就是想問 Paul Graham拿兩萬元給自己吃飯。

「但我欣賞你們那種大無畏的精神。不怕死,能在最壞的情況下看出並抓緊機會,比任何計劃書更好。」 Paul Graham由 AirBnB網站的統計數字觀察到,除大型會議以外, AirBnB的主要客源來自紐約。於是, Paul Graham給 AirBnB的頭號建議是,不要老是坐在矽谷,去紐約見你們的客戶。打電話給他們,敲他們的門,和他們一起拍照、開派對,用盡所有方法,令客戶記得你。

「不要想,只管做」,紐約一行終令 AirBnB人流增長。

(刊於 2011-02-26 香港蘋果日報)