Guest post by Tom Saxton, Idle Loop Software Design
The code is part of a Mac OS X Cocoa app, so it has some Mac-specific code intermingled with the GData code. To bring it into an iPhone project, I trimmed out the Mac user interface stuff, and defined a class and a protocol to create code that should work from any Mac or iPhone application.
The library requires several steps to upload or download a file. First, you create a service object that encodes the user agent that identifies your application, along with the username and password for the account you want to access. Then use that object to request a document list feed, which is the list of documents in the user’s account.
Retrieving the document list feed both validates the account credentials and captures information you’ll need to either upload or download files. The feed contains the URL for downloading each document. To download, you can use any http call such as NSURLConnection or the library’s GDataHTTPFetcher. The feed also has the URL for uploading new document entries.
The networking operations are asynchronous, so my encapsulating object has methods for starting an upload or download, then uses an Objective-C protocol to inform the controlling object of the progress and status at completion.
I’ve been calling these document objects files, but Google Docs isn’t a file system. It’s much more like a web publishing system: a collection of objects with associated metadata including title, creation and modification dates, and so on.
The first difference from a file system that I encountered is that you can have multiple different files with the same name. So, if you just upload a new version of a file the same way you uploaded it the first time, you’ll get a second document with that same name. To avoid that, search for the document entry with the title that you want to upload to. You can then request an update operation instead of an insert.
The second issue I discovered is that much like when you post to a blog, what you upload can get transformed to match the type of document that is holding the data. When you download the same object, you get something different than what you uploaded. For example, I uploaded a plain text document (specified by MIME type “text/plain”), but when I downloaded that same object I found the text wrapped in a bunch of HTML that makes it display well on the Google Docs web page. Our app’s files are UTF-8 XML files created by NSKeyedArchiver. Google Docs fails if you try to specify a MIME type of “text/xml” and totally mangles the document contents if you specify “text/plain”. That is not a big surprise because there’s not currently a way to specify that the text is encoded UTF-8, and the content gets stuffed into an XML file for the journey to the server.