checked No minimum volume required
checked Global printing & delivery
checked Effortless integration
checked Peecho is a free service


From iPhone to Printcloud

Written by our app guru Stephanvan Eijkelenburg, here is a tutorial on how to connect your iPhoneapp to Printcloud.

External libraries

Our iPhone code uses the following libraries.

    • All seeing I (ASI)– an HTTP request library. Upload requests over HTTP can be quite hardto assemble on the iPhone. This library helps.




Creating an order

The initial order creation is done by a simple post request to the orderurl: only data needed for this request is:

    • offeringId: the identification of the offering (that’syour catalogue item) that will be ordered.


    • merchantApiKey: the merchant’s API key.


Here is the code:

ASIFormDataRequest *req = [ASIFormDataRequest requestWithURL:   [NSURL URLWithString:orderUrl]];[req setPostValue:(NSString *)offeringId forKey:@"offeringId"];[req setPostValue:(NSString *)merchantApiKey forKey:@"merchantApiKey"];[req setDelegate:self];[req startSynchronous];

The server gives back an XML response with information about the orderthat you just created. You need this information to be able to uploadfiles.The next piece of code extracts this information using the Google XMLlibrary.

GDataXMLDocument *doc = [[GDataXMLDocument alloc]  initWithData:[req responseData]  options:0  error:nil];putURL    = [[[doc nodesForXPath:@"//order/signedPutUrl" error:nil] objectAtIndex:0] stringValue];putPath   = [[[doc nodesForXPath:@"//order/signedPutPath" error:nil] objectAtIndex:0] stringValue];policy    = [[[doc nodesForXPath:@"//order/base64EncodedPolicy" error:nil] objectAtIndex:0] stringValue];signature = [[[doc nodesForXPath:@"//order/signature" error:nil] objectAtIndex:0] stringValue];orderId   = [[[doc nodesForXPath:@"//order/externalOrderId" error:nil] objectAtIndex:0] stringValue];


Upload the files

The files are uploaded directly to Amazon AWS S3 using the ASI library.This post request is a bit more complex. The following function helpsyou to create these requests. It uses the following information

    • bucketUrl is the url to the s3 bucket, in this case


    • filename and contenttype deliver basic infoabout the data.


    • data is the file to upload, as an NSDataobject


    • key is the path to the destination file


    • kAccessKey is the Amazon access key: [ask us for a key]


The code for this is:

- (ASIFormDataRequest *)newRequestWithFilename:(NSString *)filename   contentType:(NSString *)contentType  data:(NSData *)data   key:(NSString *)key {  ASIFormDataRequest *req = [[ASIFormDataRequest alloc]  initWithURL:[NSURL URLWithString:(NSString *)bucketUrl]];[req setPostValue:key forKey:@"key"];[req setPostValue:(NSString *)kAccessKey forKey:@"AWSAccessKeyId"];[req setPostValue:contentType forKey:@"Content-Type"];[req setPostValue:@"private" forKey:@"acl"];[req setPostValue:policy forKey:@"policy"];[req setPostValue:signature forKey:@"signature"];[req setPostValue:filename forKey:@"Filename"];[req setPostValue:@"201" forKey:@"success_action_status"];[req setData:data withFileName:filename andContentType:contentType forKey:@"file"];[req setDelegate:self];  return req;}

Here is an example of how to use the function to upload the photo. The photoKeyis created by appending ${filename} to the putPath. Theputpath was returned by the server in the previous step). S3 willreplace ${filename} with the actual filename, in this case‘photo.jpg’.

NSString *photoKey = [NSString stringWithFormat:@"%@${filename}", putPath];ASIFormDataRequest *req1 = [self newRequestWithFilename:@"photo.jpg" contentType:@"image/jpeg"    data:photoDatakey:photoKey];

The same goes for the data.xml file.

NSString *xmlKey = [NSString stringWithFormat:@"%@${filename}", putPath];ASIFormDataRequest *req2 = [self newRequestWithFilename:@"data.xml" contentType:@"text/xml"    data:xmlData key:xmlKey];

It’s also possible to make asynchronous requests, this prevents the appfrom freezing during the request. The next piece of code creates a queuefor the upload of the two files. It also assigns to handlers for theevents where the queue finished uploading, of where an upload failed.[queue go] starts the upload progress without freezing theuser-interface.

queue = [ASINetworkQueue new];[queue setShowAccurateProgress:YES];[queue setQueueDidFinishSelector:@selector(queueFinished:)];[queue setRequestDidFailSelector:@selector(requestFailed:)];[queue addOperation:req1];[queue addOperation:req2];[req1 release];[req2 release];[queue go];



The payment is loaded in a UIWebView. The webview loads the payment url( with the order id andlocale as query parameters.

NSString *payURL = @"";NSString *url = [NSString stringWithFormat:payURL, cardId, [[NSLocale currentLocale] localeIdentifier]];NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];[webview loadRequest:req];


Latest blogs

Meet Lachlan, our new Growth Hacker

Read blog

New: Personalize the order confirmation emails your customers receive

Read blog

Create a personal present with Chatella

Read blog