.oooooo.     ooooo   ooooo     ooooooooooooo 
   d8P'  `Y8b    `888'   `888'     8'   888   `8 
  888             888     888           888      
  888             888     888           888      
  888     ooooo   888     888           888      
  `88.    .88'    888     888     o     888      
   `Y8bood8P'    o888o   o888ooood8    o888o     
___ ____ ____ _  _ _  _ ____ _    ____ ____ _ ____ 
 |  |___ |    |__| |\ | |  | |    |  | | __ | |___ 
 |  |___ |___ |  | | \| |__| |___ |__| |__] | |___ 
                                                    
        
First Public API Language Bindings Available Now!

7 days ago, we launched our Public API and the accompanying Developer Portal. We’ve received a lot of great feedback, updated the Portal a bit to better give you the information you need, and talked to a lot of developers with some really neat ideas for ways to use the API. Now’s a great time to get started on your own application!

Today I’m here to share some of the hard work that people have been doing, both here at Gilt and in the developer community at large, to make the API more accessible to developers of specific languages. We now have the first API language bindings available for Javascript, Ruby, Objective-C, Scala, and Python!

There’s more to come; I’ll make sure to update here when we have support for more languages or other libraries that might tickle your fancy. Until then, this should be enough to get you started, right?

Javascript

Developed by Chris Young-Zawada here at Gilt, these Javascript language bindings are available as a jQuery-based implementation, so all you have to do is drop in a recent version of jQuery and this .js file and you’re off to the races!

Ruby

gem install kin is all you need to get started with using the Gilt API in Ruby. Developer Vivek Bhagwat put together this rubygem to let Ruby developers worldwide have access to Gilt’s great flash sales in their applications. Thanks, Vivek!

Objective-C

iOS development is kind of a big deal right now, and what better way to dip your toes in the water or extend the reach of your mobile app empire than to use this Gilt API iOS client library to integrate Gilt sales data into an app for iPhone, iPod Touch and/or iPad? (That’s a rhetorical question. This is the ultimate way to do those things.) The SDK was put together by a crack team of Gilt mobile developers: Louis Vera and Adam Kaplan.

Scala

Recently among my friends and, it seems, in the developer community at large, what started as a whisper (“Scala is pretty sweet”) has turned into a roar (“DEPLOY ALL THE SCALA”). If you’re one of the converts, I’m happy to tell you that developers Moses Nakamura and Vivek Bhagwat have prepared a fully-tested, simple to use library called Aurum that give you access to the Gilt API. Moses and Vivek win the prize for being the first client library developed outside of Gilt— it was up and ready for use fewer than 48 hours after the launch of the API!

Python

Not content to rest after that, Moses put together a simple Python wrapper for the Gilt API as well. It’s currently the slimmest of the client libraries highlighted here today, clocking in at just over 100 lines of code, but supports digging through all of the sales and product information that you need to explore our curated sales and do all kinds of fun stuff with them. Good luck, Pythonistas!

The Xcode Organizer doesn’t show me all my crash logs. Help!

When you’re developing an iPhone or iPad application, running the app on the device is essential to understanding whether your code is working correctly. Although the iOS Simulator is very useful for testing functionality and user interface interactions, it doesn’t provide a very good simulation of the memory constraints your app will face on actual devices. As a result, applications that run fine in the simulator may be unexpectedly terminated by the operating system when run on devices.

Often, but not always, crashes that happen only on the device are due to memory warnings that are not being handled correctly by your application. Unfortunately, if your application terminates unexpectedly on the device, you’re not always given a clear indication of the cause.

One tool for diagnosing such problems is the Xcode Organizer. The left-hand sidebar of the Organizer window contains a list of the various devices that have been hooked up to your computer over time. While a development-enabled device is connected to your computer, the Organizer window will show a green dot next to the device name, and the if you select a connected device in the “Devices” list, you will see a number of tabs at the top of the main part of the window.

The “Device Logs” tab should show any crash logs recoded on the device for the applications you’re developing. On my installation of Xcode, however, crash logs don’t always appear there, making it difficult to determine with any surety the cause of a given crash. (I’m not sure why certain logs are omitted from the Organizer; I just know that in my experience, they don’t always show up. I’m currently running Xcode 3.2.6.)

Fortunately, there is a work-around. If you sync a device through iTunes, it turns out that new crash logs are copied from the device to a location within your home directory. You can find the crash logs for your device(s) within:

~/Library/Logs/CrashReporter/MobileDevice

Inside that directory, you’ll see a directory for each device that (1) has been synced through iTunes, and (2) had crash logs to copy at the time it was synced. (The name of the directory will be taken from the name of the device.)

If a given application crashed due to an exception such as EXC_BAD_ACCESS, you should see a log file containing the name of the application’s executable followed by a timestamp indicating the time of the crash. The contents of the log file will give you more information about the nature of the problem.

When the operating system terminates applications due to low memory conditions, it will create a log file starting with the name “LowMemory-” followed by a timestamp. The file will list any application(s) terminated and give clues about the memory usage of each.

Even when running an application on the device within the debugger, console output isn’t always clear about the reason that an app was terminated. In those cases, the Xcode Organizer seems like the right place to look, but you might not find all the expected logs there. Syncing your device with iTunes and digging into the log files copied to your local filesystem is sometimes the only way to get the clues you need to diagnose certain types of unexpected terminations.

Evan Coyne Maloney
Senior Software Engineer, Mobile Team
Gilt Groupe

Tips for optimizing iPhone/iPad applications

We’ve made a number of optimizations to our iPhone/iPad codebase over the past couple of months, the effects of which can be seen in the attached video:

(Because our application is so dependent on the network, the new code won’t appear to outperform the old code 100% of the time. This is due to the vagaries of the connection between the devices and the server.)

As we prepare to submit this latest code to Apple, we decided to make some of our optimization techniques public in the hopes that it may benefit developers outside of our company:

  • In a number of places in our code, we were spawning new threads to perform short-lived operations. We’ve rewritten a number of these as NSOperations, allowing us to use NSOperationQueue instances, which are implemented under the hood by the OS as thread pools. So we’re spawning fewer new threads and reusing existing threads more; as a result, we’ve avoided some overhead of launching new threads. Also, since the OS is able to manage threading behavior for us via the NSOperationQueue, the OS is able to make smart decisions at runtime about thread resource usage that we were previously hard-coding at development time. Our assumptions could never be correct for all cases, since each device may have a different number of other processes running at any time. The OS itself is in the best position to make such decisions.
  • Using the @synchronized construct for thread safety in iOS is very expensive. (Part of the reason for this is that @synchronized sets up inherent exception handlers.) So, one major optimization was to replace @synchronized blocks with using the NSLock/NSRecursiveLock classes for thread safety. Doing this reduced thread waits that occur during lock contention, improving app performance overall.
  • Another way we avoid unnecessary locking is by using the thread-local storage provided by the threadDictionary: method of NSThread. Thread-unsafe resources that are expensive to construct—but that don’t take up a lot of memory—are good candidates for this. So, instead of constructing many short-lived objects on an as-needed basis, we can construct one per thread and keep it in thread-local storage. This ensures that the resources are used in a thread-safe manner, while avoiding the expense of repeated instantiations. (This technique is less useful for short-lived threads that are spawned often, because in those cases you won’t be avoiding the instantiation costs. Note, too, that Apple recommends against using thread-local storage for threads managed by NSOperationQueues.)
  • We discovered that instantiating and using the NSDateFormatter class is particularly expensive. (And, because the NSDateFormatter class is not thread-safe, we can’t share instances across threads.) We use this class to parse text dates that arrive from the server. So, to avoid the instantiation expense, we’re caching NSDateFormatters in thread-local storage. Also, in our particular case, because so many of the date strings we’re parsing turn out to be identical (a result of many sales starting at the same time), we’re avoiding some of the date parsing altogether by maintaining a cache with date string keys that point to the NSDate instances that resulted from parsing that date string. Most of our dates now don’t need to be parsed at all; we just need to look up the NSDate associated with a given date string. Doing this shaved 5%-10% off the processing done at app startup.
  • Our old caching system used a SQLite database; we’re now using the filesystem for caching, which avoids all the marshalling/unmarshalling required by the database accesses. This is particularly beneficial for our image cache. Now that cached images are stored in the filesystem, we can load them directly with [UIImage imageWithContentsOfFile:]. Previously, our image data was first loaded into an NSData instance that was then passed to [UIImage imageWithData:]. Not only does this new technique perform better, but by using this method to reference images, the OS has the option of purging image data from memory and reconstituting it directly from the file on an as-needed basis. (Whether or not a given version of iOS does this is another story, but at least this technique gives the OS that option.) That’s not possible if we were still using [UIImage imageWithData:]; the OS can’t purge the image data in that case since there would be no way to transparently reconstitute it if the image data were needed again. This gives the OS the ability to better manage memory on our behalf.
  • Since a big factor in iOS app performance is the memory footprint of the application, we’re also making better decisions about what images to store in our memory cache. Large images in iOS are particularly expensive, since the operating system stores image data uncompressed in memory. The large Gilt sale images are over 6MB uncompressed, and we’re now avoiding caching those in memory altogether. (We now only cache images in memory if their uncompressed size is less than 1MB.) This reduces the amount of memory warnings our app has to handle, which means we don’t have to flush our memory caches as often. As a result, all of our various memory caches have more cache hits and fewer misses; our memory caches are now more efficient.

If there’s any interest in my going into further detail on any of these items, let me know. In the meantime, I hope you find this helpful!

Evan Coyne Maloney
Senior Software Engineer, Mobile Team
Gilt Groupe