Sunday, July 26, 2009

Upgrading to Puri! Lite 2.0


Puri! Lite has returned in full force with a host of exciting new features and better user experience. With version 2.0 of the most popular photo sticker application, users can freely edit both portrait and landscape photos with great ease. More frames and stamps have been added to the already grand collection of high-quality artwork. Emailing purikura and the new speech bubble make it even more fun and convenient making photo stickers.

Foremost, we have improved the user interface significantly with an overhaul of the back-end photo-saving engine. Now you can save photos in the app together with the stamp and frame meta-data and therefore you can resume editing even after you close and reopen the app! This is a rather advanced feature with quite a bit of technical complexity under the hood. Unfortunately, the save format of version 2.0 is not backward compatible with the previous versions. Therefore, upgrading to 2.0 would cause the photos saved within the application to cleared since they are unusable. However, the upgrade does NOT affect photos exported to Facebook and the iPhone's Camera Roll album. *** We strongly advise users to backup their in-app saves by exporting them to the iPhone album and/or Facebook before upgrading. ***

Tuesday, July 21, 2009

Puri! 2.0


Puri! 2.0 is finally out after 3 months. The journey of making this iphone app has not been easy and we, as a company, have grown and improved alongside Puri!.

We started out as 3 young adults who were looking to do something unique, something different, something enjoyable. Thinking in the direction of making people happy, we came up with the idea of Puri!.


We hope that Puri! would add new meaning to people’s photos and make photos more fun. We hope that Puri! could be used, shared and enjoyed by father, daughter, husband and wife. We hope that it would put smiles onto people’s faces.


But never have we thought that over 500,000 people will download this app and make us no.1 in the free photography category for over 2 months. This application is special because of all of you and we are truly grateful for everyone’s support and love for this application.


We worked very hard to get this new update out in hope of making the experience an even greater and memorable one. We have listened to many of your feedback and turned Puri! into an even more fun and powerful photo editor. Yet, in its core, it’s still an application that tries to make people laugh and smile.


Ultimately, Puri! is made for you and we’d love to have your thoughts, comments and feedbacks so we can keep innovating and making Puri! more fun.


Out of all the new features, the most exciting for us is the community feature. We want our Puri! users to share their photos with the whole community. We want our Puri! users to share the joy of others through viewing others' purikura. We want our Puri! users to be able to keep and collect their own purikura.


And to that regard, we’re working very hard with printing partners to allow you to order actual photo stickers and get them sent to your home.


Please stay tuned to the coming updates and join the community by going to mypuri.com (full website coming out soon). Thanks again for your support and love!

The proper way to fix linker conflict between AdWhirl and FBConnect

I was trying to integrate AdWhirl into Puri! Lite 2 yesternight but I was getting a linker error. Apparently the static library that AdWhirl is giving out already contains part of Facebook's FBConnect library and it is causing duplicated symbols with our own FBConnect library. AdWhirl's instructions page has some answers to it but it's not good enough for us, because we're using a customized FBConnect:

  1. Refactoring would work if it's done correctly. But with Objective-C's dynamic nature it's possible for grep/sed/anything relying on regular expressions to miss a few references that aren't apparent in the code. I'm sure it will work for FBConnect (which isn't too complicated a library), but I don't see it as a clean solution.
  2. Removing .m files from FBConnect until no conflict is left - this doesn't work for us because it means we're removing our own customizations.
  3. Specifically compiled .a files without Pinch Media's package (which is the package containing FBConnect libraries) - doesn't work because we want to have Pinch Media's adverts.

There's a far better way than any of the above.

AdWhirl's library is actually an .a file - a static library that can be used by the GNU linker. People who're familiar with GNU toolchain would know that an .a file is actually just an archive containing object files (.o files that are the direct products after you've compiled .c, .cpp or .m source files). Because it's just an archive, it can be opened, listed, extracted and modified.

So let's see what's inside AdWhirl's static library file:
[martinkou@martinkou AdWhirl]$ ar -t libAdWhirlDevice_1.2.0.a
__.SYMDEF SORTED
ARAdNetworkController.o
ARAdRolloController.o
ARCustomController.o
ARExternalAdNetworkController.o
ARJumpTapController.o
ARMillennialMediaController.o
ARMobclixController.o
ARQuattroController.o
ARVideoEggController.o
AdRolloCanvasController.o
AdRolloController.o
AdRolloAdContent.o
AdRolloConnectionURLDownload.o
AdRolloConnectionURLMetricsFetch.o
AdRolloImgCacheManager.o
AdRolloLocationManager.o
AdRolloAdView.o
AdRolloCanvasWebView.o
AdRolloContainerView.o
AdRolloView.o
MMAdOverlayController.o
MMAdView.o
MMAdViewPrivate.o
MMAdWebViewController.o
MMAppData.o
dgif_lib.o
gif_err.o
gif_hash.o
gifalloc.o
PLGIFImageView.o
PLGIFReader.o
ARRollerController.o
ARReachability.o
ARRollerAnalyticsUrlRequest.o
ARRollerConfigurationInfoRequest.o
ARRollerStaticInfo.o
ARRollerUrlMetricsRequest.o
ARRollerUrlRequest.o
ARCDataScanner.o
ARCDataScanner_Extensions.o
ARNSCharacterSet_Extensions.o
ARNSDictionary_JSONExtensions.o
ARNSScanner_Extensions.o
ARCJSONDeserializer.o
ARCJSONScanner.o
ARCJSONSerializer.o
ARRollerView.o
ARRollerViewInternal.o
Mobclix.o
MobclixController.o
MobclixDatabase.o
MobclixJSON.o
MobclixMessenger.o
MobclixReachability.o
MobclixAds.a
MobclixBrowser.a
MobclixFeedback.a
MobclixSocial.a
FMDatabase.o
FMDatabaseAdditions.o
FMResultSet.o
CXMLDocument.o
CXMLDocument_CreationExtensions.o
CXMLDocument_PrivateExtensions.o
CXMLElement.o
CXMLElement_CreationExtensions.o
CXMLElement_ElementTreeExtensions.o
CXMLNode.o
CXMLNode_CreationExtensions.o
CXMLNode_PrivateExtensions.o
CXMLNode_XPathExtensions.o
QWAd.o
QWAdRequestOperation.o
QWAdView.o
QWBannerAdView.o
QWCacheManager.o
QWInterstitialAdView.o
QWLog.o
QWRequestConstants.o
QWSmallBannerAdView.o
QWSubmitReportOperation.o
QWTextAdView.o
QWWebViewController.o
QWAdViewConcrete.o
QWTestMode.o
QWPrefetchOperation.o
QWURLBuilder.o
QWImageFactory.o
NSURLRequest+QWTools.o
QWRegisterAppLaunchOperation.o
AdFrameView.o
PMCDataScanner_Extensions.o
PMNSCharacterSet_Extensions.o
PMNSDictionary_JSONExtensions.o
PMNSScanner_Extensions.o
PMCJSONDeserializer.o
PMCJSONScanner.o
PMCJSONSerializer.o
PMCDataScanner.o
PMAdSizeLookup.o
PMAdViewController.o
PMStaticAdViewController.o
PMDropDownAdViewController.o
PMInterstitialAdViewController.o
PMAdView.o
PMInterstitialAdView.o
PMAd.o
PMAdServer.o
Beacon.o
BeaconDatabase.o
Reachability.o
Database.o
JSONUtils.o
CrackDetector.o
FBConnectGlobal.o
FBRequest.o
FBSession.o
FBXMLHandler.o


Notice the four object files: FBConnectGlobal.o, FBRequest.o, FBSession.o and FBXMLHandler.o at the end of the list. These four files are causing the linker conflict with our customized FBConnect library.

To remove them from AdWhirl's static library archive, use ar -d:
[martinkou@martinkou AdWhirl]$ ar -d libAdWhirlDevice_1.2.0.a \
FBConnectGlobal.o FBRequest.o FBSession.o FBXMLHandler.o

Repeat the same command for the other .a file which is for the Simulator.

After running this command the FBConnect-related object files will no longer be present in the AdWhirl static library (you can use ar -t to check), and thus you'll no longer have the linker conflicts.

The same principle can be applied to other conflicting libraries. e.g. TouchXML or FMDB in Quattro.

Friday, July 10, 2009

What does being an "American cultured" company mean?


We've recently been negotiating a few potential partnerships with Hong Kong companies as well as Silicon Valley companies. Negotiations with Silicon Valley are usually smooth - I guess it's because they're used to dealing with tech companies anyway and so it's business as usual for them. But when we negotiated with local (i.e. Hong Kong) companies I've found they'd often try to laugh at our notion:

"We're an American cultured company"
"Hey, that's just marketing gimmick, it means nothing to us."

The response is understandable given the local business culture. But whenever I hear this kind of rebuff, I always sigh to myself, "alright, there's a lot of ground we need to cover in this meeting."

Results Oriented

You can know all the venture capitalists in Silicon Valley, talk to them until your face turn blue, and yet you won't get any funding. Some antisocial hacker in a basement somewhere, who never cared about socializing apart from DEFCON or 2600's IRC channel, may get funded instead. (Note: antisocial does not mean he cannot communicate himself - (s)he may be a great writer and public speaker) What's the difference? Results. What results means here can be anything - it may be your cash flow; it may be your customer base size; it may be your superior technology; it may be your business model is really innovative. But the point is, you've GOT to have something, something different and powerful in your hands. The usual VC pitches may sound like nonsense to traditional businessmen. But when tech companies are funded by the larger VCs like Kleiner Perkins, these is most often a good reason.

Here at Think Bulbs it doesn't matter that you're a good friend of mine, or Alvin, or Michael - if you're unable to deliver results, you'll be fired. Whenever we have our weekly company meeting the focus is always on the tasks and results - what's been done, what's to be done, is the task feasible, schedule, what's our competitor doing, is the new app a threat to us, how to negate their competitive advantage (if any). The focus is so laser sharp it feels like you're doing maths.

And the market response speaks for our effort - within the few months since Puri! was debuted, everyone was too busy (I'm also working at FCKeditor, all other people are students or have a full time job) to do any serious marketing operation (no promo video!) but we still managed to grab more than 500,000 users worldwide - this is not a fake number. Our iPhone app stayed on the #1 of Photography in a good number of countries for 2 months - we haven't updated Puri! v1.1 for a long time and the customers just keep coming in. Even to this day I can still give you a laundry list of countries where we're still firmly planted within the top 10, and then we're still the #1 in some countries like Mexico. And then for 2 weeks or more we've been within the top 5 of all free apps in a number of countries/localities like Hong Kong and Taiwan. Still don't believe it? Ask Google, search for "Puri! Lite", look at all the blog entries from people taking photos with Puri! and Puri! Lite and praising us. That, my friend, is results.

If you intend to propose a deal to us we can give you Apple's download statistics reports to prove it. And if you doubt our statistics are fabricated, feel free to verify it with Apple.

Quality, as in Doing it the Right Way

If you're not aware of it, software contractors and developers are often paid very cheaply in Hong Kong, even cheaper in mainland China. The tradeoff for the cheap prices, is quality. Good people don't want to work on cheap things, and even if you've somehow got someone good with no independent thought (there are, unfortunately, quite a number of them) - it isn't worth the time to do things correctly for cheap projects. The result? Things that "work" but fall apart at the slightest glance.

And then you have a very large number of people who totally don't know how to do things (let alone doing things correctly), but are passing off as programmers. But that's another story.

At Think Bulbs, however, we strive to do things the right way. If a bug is found (happens a lot), we take time to find out the actual reason (e.g. is it a design flaw? a logic bug? or simply a typo?) and fix it. If the bug has to be fixed by a structural change, then so be it. Unless it's extremely urgent, we don't use hacks to fix bugs. On the graphics front, you'll find that our frames and stamps are actually of pretty high quality, and the strokes you draw in Puri! 1.1 are anti-aliased - no jagged edges! If you compare our app to other photo sticker apps in App Store you'll find that many other apps have really ugly frames and icons - their designs often just look wrong to begin with, and even worse, even their own preset graphics contain jagged edges! Horrible.

Such quality differences are very easily noticeable by your users. And, contrary to what many sales and marketing people may think, users in the App Store are actually quite smart because of the free flow of information (e.g. comments, and the "what users also buy" field). So if you have a poor quality product, put it up in App Store, it'll simply be free advertisement for the higher quality app - your potential customers will simply click on one of those "what users also buy" entries and notice the other product has better ratings. Puri! Lite stayed on the top spot for so long, because of quality. And as I've said in one of the negotiations this week - it doesn't matter that your app goes to the top 10, what's important is making it STAY there.

Passion

Doing things the right way, is actually a boring task. Imagine you have an application that almost works, but you've made a design flaw in the beginning so that 1% of it isn't working - would you choose to fix it with a hack or change the whole design and fix it from the source? Most people would choose to fix it with a hack and release it right away, but with hidden costs when he goes further into the application's development, and probably causing more bugs to appear.

To write a software "the right way", you actually have to spend a lot of time NOT writing code. This is true for the design phase - you have to spend a lot of time imagining how your software is going to work and how it may break. It is also true for implementation and debugging - when something wrong happens, you have to spend a lot of time to investigate why the bug is happening, instead of using hacks to cover it up.

Somebody who went into software development just for the money (the fast money doesn't exist anymore - probably a good thing), will almost certainly not bother with these troubles. The result? Software that breaks at the slightest glance. At Think Bulbs, our development team actually care about our software. We don't see it as just a way to make a tidy profit, we take our creations as something we love. "Cookies need love like everything does" - so does software. And this is why we can have quality without me shouting for it until my throat sores - we just take it as the natural thing to have.

And that's also why I'm writing this blog entry early in the morning, despite the fact I'm feeling sick right now.

Monday, July 6, 2009

Apple's Lousiness




We'd like to thank our user Katrina for pointing out a flaw in Apple's iTunes management system. If you don't already know, we've already submitted Puri! 2.0 to Apple for review. While preparing for the application description for this exciting new version, we discovered that the app. management system, iTunes Connect, fails to distinguish between certain attributes of different versions of the same application. We were led to believe that the "What's New" section for version 2.0 will be hidden before the application itself has been approved. We were, unfortunately, wrong. Indeed, only the application and its icon can be changed for a new version without affecting the description for the existing version. Consequently, some users have been led to mistake v1.1 with v2.0. We have resolved the issue, and hope that the inconvenience has been short.

GOOD NEWS: Puri! 2.0 will be out within the week! All those who have v1.1 can upgrade to v2.0 for free!! THE UPGRADE WILL BE AWESOME!!!!

Don't forget to visit our community: http://mypuri.com
See you there!

Archive