Search code examples
objective-ccouchcocoa

Get Attachment from documentProperties in couchCocoa


I have a document properties downloaded from a view, so I have the actual JSON from the doc, including the ID and Rev ID. I don't have the actual CouchDocument, though.

The document has an attachment, and I know the name of it. I'm trying to download the attachment into a CouchAttachment object, but I can't find a way of doing it without having to redownload the document, which is slow. Here's what I'm doing:

-(CouchAttachment *)getAttachmentFor:(NSObject *)doc named:(NSString *)fileName {

  if ([[doc valueForKey:@"_attachments"] valueForKey:fileName]==nil)
    return nil;

  CouchDocument * document = [[[App shared] database] documentWithID:[doc valueForKey:@"_id"]];
  CouchRevision * revision = [document revisionWithID:[doc valueForKey:@"_rev"]];
  return [revision attachmentNamed:fileName];
}

Is there any way to get the Attachment directly, wihout having to first get the doc and revision?


Solution

  • The CouchCocoa framework does not seem to provide a way to create a CouchAttachment object directly. However, you can get the attachment directly with a GET operation, provided you know the URL of the attachment.

    Let's say you have some document in some database with an attachment named someAttachment.txt. The URL format for that attachment would be:

    http://couchdb/someDatabase/someDocumentID/someAttachment.txt?rev=<your revision id>
    

    You have your revision ID and document ID from your doc dictionary. If you can pass your server URL and/or your database URL, you can do a GET operation to get the attachment like so.

    RESTResource *aRestResource=[[RESTResource alloc] initWithURL:[NSURL URLWithString:@"http://couchdb/someDatabase/someDocumentID/someAttachment.txt?rev=<your revision id>"]];
        [aRestResource autorelease];
        RESTOperation *aRestOperation=[aRestResource GET];
        [aRestOperation onCompletion:^{
            NSLog(@"Content Type:%@",aRestOperation.responseBody.contentType);
            //The response for the GET will contain the attachment's data. You can
            NSData *contentData=[[NSData alloc] initWithData:aRestOperation.responseBody.content];
            NSString *contentString=[[NSString alloc] initWithData:contentData encoding:NSUTF8StringEncoding];
            NSLog(@"Content:%@",contentString);   //Should contain the text in someAttachment.txt
            [contentData release];
            [contentString release];
        }];
        [aRestOperation wait];
    

    Source: http://wiki.apache.org/couchdb/HTTP_Document_API#Attachments

    Alternatively you can create a CouchAttachment object using RESTResource 's initWithURL: method but that does not construct CouchAttachment specific properties like the document and database etc.