Is there a simple way to upload an image, taken by the camera, to a web server? I have a script that takes images from a submitted form, but not sure how to convey that info from my iOS app.
I am using an HTTPSocket to send & receive text data, which works quite well.
Using the iOSKit, which works very well by the way, I can take the pic and load it onto a canvas so the user can see it before uploading.
I would appreciate any suggestions, as so far I am not finding details how to send the form data. (I am using httpsocket.SetRequestContent method, but can change if that is not appropriate here.)
I’m working on a similar project. It’s a Xojo iOS app where the user takes a photo and uploads it to a server along (along with location information).
Here’s how it works…
On the client side, a photo is taken and then displayed to the user as an iOSImageView. When the user chooses to upload the photo, it is converted to a memory block, and then posted via an HTTP socket.
On the server side, I originally tested the client using a simple PHP-based app. The script grabs the posted content using something like this: $data = file_get_contents(“php://input”) That data is then saved as a file on the server.
After I confirmed that the iOS app was uploading properly, I rewrote the server app as a Xojo Web app. It looks for upload requests via the HandleURL event, gets the uploaded content (via “Request.Entity”), and saves it to the server. My next step is to move the uploaded file to an Amazon S3 bucket - and that’s what I’m working on now.
I hope this helps. Let me know if you need any help or code snippets.
At a simple level, you can use iOSImage.ToData(“public.jpeg”) to convert your iOSImage to a JPEG in a MemoryBlock and then use setRequestContent to attach the MemoryBlock to your HTTPSocket. You can then just Send this as a POST to your service.
But remember to encapsulate the filename/image name if you’re passing this as part of the request, check the image size doesn’t exceed the maximum size for your service and build in some recovery such as supporting seamless retries because uploading binaries isn’t as simple as POSTing to regular services. In my app I also disable the idle timer, and re-enable it after each upload, so that the app can complete each upload without the lock screen intervening.
Also worth noting is that in my case I found the intrinsic HTTPSocket was troublesome as it doesn’t (yet) have a timeout property and so it was unable to support all of my users in a consistent way and a significant number of my users reported issues uploading images in early versions of my app. So instead of the native HTTPSocket I use Monkeybread’s NSURLConnectionMB class, which has a timeout property, and it works flawlessly.
In the app that I’m working on, the image (which is actually a photo captured from the camera) is displayed using an iOSImageView. The user clicks a button to initiate the upload, and the Action event handler looks like this:
// Create a new HTTP socket.
httpSocket = New HTTPSocketPost
// Convert the image to a memoryblock.
Dim data As MemoryBlock = PhotoPreview.Image.ToData("public.png")
// Set the socket's content and type.
httpSocket.SetRequestContent(data, "multipart/form-data")
// Send the data.
httpSocket.Send("POST", "http://10.0.1.18:8080")
On the server side, when I was doing testing with PHP, I was able to get to the posted data using this:
Dim mb as MemoryBlock = ImageView1.Image.ToData("picture.jpg")
The image loads into the iOSImageViewer, and displays fine. As soon as I click send, the app crashes when trying to load the data into the MB.
What am I missing?
BTW, it never even calls, or tries to call, the php script as it has already dumped out. I don’t know how to easily debug this, as the camera doesn’t seem to be supported in the simulator.
Dim mb as MemoryBlock = ImageView1.Image.ToData("picture.jpg")
The image loads into the iOSImageViewer, and displays fine. As soon as I click send, the app crashes when trying to load the data into the MB.
What am I missing?
BTW, it never even calls, or tries to call, the php script as it has already dumped out. I don’t know how to easily debug this, as the camera doesn’t seem to be supported in the simulator.[/quote]
I have an MBS license, so think I may take a look at doing it the way you have, rather than re-inventing the wheel. I assume I can pass the file, a file name, and a reference number (i.e. the id of the record to which the picture relates) with the post?
BTW, I am not sure how to encapsulate the file name, as you mentioned, but if there are issues with the basic http socket, it seems silly to go down that path only to change to the MBS solution.
I’m posting additional information about the image by using custom HTTP headers. For example:
// Set the request headers.
httpSocket.RequestHeader("image_id") = "12345"
httpSocket.RequestHeader("latitude") = Latitude.ToText
httpSocket.RequestHeader("longitude") = Longitude.ToText
On the server side, I’m getting those values in the Xojo version using Request.GetRequestHeader(“image_id”). If you were going to do the same in PHP, you’d get the header values using something like $_SERVER[‘HTTP_IMAGE_ID’].
My concern with the large photos was the bandwidth that it would require for the uploads, and the possibility that the users might get anxious and bail out of the app - especially when they are on a cell connection. So I ended up resizing the photos as they come in from the camera. For example:
I don’t need all of the detail that the original, full-sized photos provide, so I can get away with resizing the photo. But if you need the originals, then this won’t work for you.
Anyway, it sounds like you’re getting close. Let us know how it goes.
I shall probably do the same, just to be safe. This app won’t have many users uploading concurrently, so hopefully wouldn’t be an issue., but better safe than sorry.
This started out as a web app, as I don’t do android stuff, and am a bit of a purist on cross-platform development… but the client’s company only use iDevices, so decided to spruce up an old solution.
The web app has served them well, for years now, but has limitations.
Once again, I appreciate you assistance. I’ll let you know how it goes.