Review & Intro
In the previous tutorial, you will be able to create a Simple iOS application
and a simple rails application.
In this last tutorial, you will know how to send the image from iphone simulator to rails web application.
Principle for sending image
There are two common way to send image, one is to use the form data request, one is to use Base64 to encode the image data byte into ASCII code so that the encoded image data can be sent with JSON request.
Make connection from IOS
Assume you have put the library into the XCode project,
then import NSData+Base64.h into BIDViewController.m in order to get the ability to encode the image data.
- Create a request with URL
- Encode the Image data with Base64
- Embed the encoded image data into JSON
- set the JSON as the data of the reuqest
- Make connection with the request owns JSON data
- (IBAction)sendImage:(id)sender {
// Encode the Image with Base64
NSData *imageData = UIImagePNGRepresentation(_imageView.image);
NSString *imageDataEncodedeString = [imageData base64EncodedString];
// Send Request to Server
// Create the request with url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:3000/accounts.json"]];
// Add header value and set http for POST requeest as JSON
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
NSLog(@"Htttp Method%@ ", request.HTTPMethod);
// Create dictionary key-value pair for transformming into NSData
NSMutableDictionary *newAccount = [[NSMutableDictionary alloc]init];
[newAccount setObject:_nameTextField.text forKey:@"name"];
[newAccount setObject:imageDataEncodedeString forKey:@"icon_image_data"];
NSLog(@"%@", newAccount);
//transform the dictionary key-value pair into NSData object
NSData *newAccountJSONData = [NSJSONSerialization dataWithJSONObject:newAccount options:NSJSONReadingMutableContainers error:nil];
//let the NSData object be the data of the request
[request setHTTPBody:newAccountJSONData];
//create connection with the request and the connection will be sented immediately
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
// the connection created is successfully
if (connection) {
_receivedData = [[NSMutableData alloc] init];
}
}
Receive the data in the connection
The prevous step only made the connection to the URL, the controller have to owns a NSMutableData in order to holds the data received from the connection.
@interface BIDViewController ()
@property (strong, nonatomic) NSMutableData *receivedData;
@end
// delege meethod of NSURLConnection
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[_receivedData appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
// parsing the return JSON Sting
/* {"created_at":"2012-12-15T22:33:59Z","icon_url":"/icon/3.png","id":3,"name":"jason","updated_at":"2012-12-15T22:33:59Z"} */
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Connection" message:@"Connection Finished" delegate:self cancelButtonTitle:@"I know!" otherButtonTitles:nil];
[alert show];
}
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if ([response isKindOfClass:[NSHTTPURLResponse class]])
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) response;
NSLog(@"%d", [httpResponse statusCode]);
//If you need the response, you can use it here
}
}
Decode the image data in rails
Add this method into model- account.rb
It will decode the image data into IOObject.
def decode_icon_image_data
# if the icon_image_data is set
# decode it and handle by controller method
if self.icon_image_data.present?
data = StringIO.new(Base64.decode64(self.icon_image_data))
data.class.class_eval {attr_accessor :original_filename, :content_type}
data.original_filename = self.id.to_s+".png"
data.content_type = "image/png"
return data
end
end
In the controller we set up in the previous tutorial, we will check either the data from remote or from local.
icon_io = @account.icon_image || @account.decode_icon_image_data So we don't have to change the controller.
Test your result
- Open rail server with rails server
- Choose the image in iphone, enter the name
- Kick register button, you should be able to send the request
- View the result in http://localhost:3000/accounts
Expect result and testing shell script
This result is expected, you will see a long JSON request parameter in terminal.




I have made a shell script for testing the server side, it hard code the JSON data used to register a member called jason with blue flower icon. You can download it from
Use it as sh curl_test.sh
Happy new year :)