I spent all this morning looking for a clear example on how to upload a picture taken with an iPhone to the blobstore, but without succeed.
Currently I have my iPhone app developed, which can send pics to the server in PHP, with this code in the server:
// Function to upload a photo in a file and save data in the DB
function upload($photoData, $descr, $phone) {
// Folder to upload data
$path = $_SERVER['DOCUMENT_ROOT']."/program/data/";
// Check if there was no error during the file upload
if ($photoData['error'] == 0) {
$result = query("INSERT INTO pics(descr, phone) VALUES('%s','%s')", $descr, $phone);
if (!$result['error']) {
// Inserted in the database, go on with file storage
// Obtain database link (in lib.php)
global $link;
// Get the last automatically generated ID
$idPhoto = mysqli_insert_id($link);
// Move the temporarily stored file to a convenient location
if (move_uploaded_file($photoData['tmp_name'], $path.$idPhoto.".jpg")) {
// File moved, all good, generate thumbnail
thumb($path.$idPhoto.".jpg", 180);
print json_encode(array('successful' => 1));
} else {
errorJson('Upload on server problem');
}
} else {
errorJson('Save database problem: '.$result['error']);
}
} else {
errorJson('Upload malfunction.');
}
}
The part in Objective-C that makes this works is (I'm using AFNetworking and the object API sharedInstance is an AFJSONRequestOperation class):
// Upload the image and the description to the web service
[[API sharedInstance] commandWithParams:[NSMutableDictionary dictionaryWithObjectsAndKeys:
@"upload", @"command",
UIImageJPEGRepresentation(originalPhoto, 70), @"file",
description, @"descr",
phoneNumber, @"phone",
nil]
onCompletion:^(NSDictionary *json) {
// Finished and response from server
if (![json objectForKey:@"error"]) {
// Success
[[[UIAlertView alloc]initWithTitle:@"Info"
message:@"Thanks"
delegate:nil
cancelButtonTitle:@"Dismiss"
otherButtonTitles: nil] show];
// Send a notification so the main view can reload the data
[[NSNotificationCenter defaultCenter] postNotificationName:@"updateStream" object:nil];
} else {
// Error
NSString* errorMsg = [json objectForKey:@"error"];
[UIAlertView error:errorMsg];
}
}];
This works fine and the images are saved on the server. But I want to make the same with datastore, which you can't save files. So I made a webpage to practice on save images, and I can upload images without any problem in the blobstore from an standard web form. This is the code I'm using to save it in GAE (forget about my own helper classes or functions like PicturePageHandler or render_page):
# Get and post for the create page
class Create(PicturePageHandler, blobstore_handlers.BlobstoreUploadHandler):
def get(self):
if self.user_logged_in():
# The session for upload a file must be new every reload page
uploadUrl = blobstore.create_upload_url('/addPic')
self.render_page("addPicture.htm", form_action=uploadUrl)
def post(self):
if self.user_logged_in():
# Create a dictionary with the values, we will need in case of error
templateValues = self.template_from_request()
# Test if all data form is valid
testErrors = check_fields(self)
if testErrors[0]:
# No errors, save the object
try:
# Get the file and upload it
uploadFiles = self.get_uploads('picture')
# Get the key returned from blobstore, for the first element
blobInfo = uploadFiles[0]
# Add the key and the permanent url to the template
templateValues['blobKey'] = blobInfo.key()
templateValues['servingUrl'] = images.get_serving_url(blobInfo.key(), size=None)
# Save all
pic = Picture.save(self.user.key, **templateValues)
if pic is None:
logging.error('Picture save error.')
self.redirect("/myPics")
except:
self.render_page("customMessage.htm", custom_msg=_("Problems while uploading the picture."))
else:
# Errors, render the page again, with the values, and showing the errors
templateValues = custom.prepare_errors(templateValues, testErrors[1])
# The session for upload a file must be new every reload page
templateValues['form_action'] = blobstore.create_upload_url('/addPic')
self.render_page("addPicture.htm", **templateValues)
My questions are:
It's not exactly what you're after, but this might help: