2012年3月19日月曜日

iphoneで撮った写真をherokuにアップロードする(iosアプリ)

herokuで無料のimage uploaderを作るの続き。

mongolabを使って、写真のアップローダを作れるようにしましたが、せっかくなのでiphoneから写真を直接あげられるようにしておきます。
写真をアップロードはhttpを使ってサーバにpostします。

postするサンプルを作っている人がいたので、これをベースにして使うことに。
https://github.com/tochi/HTTPFileUploadSample

HTTPFileUploadSampleViewController.hを以下のように修正
  1. @interface HTTPFileUploadSampleViewController : UIViewController <httpfileuploaddelegate, uitextfielddelegate="">  
  2. {  
  3.     IBOutlet UITextField *codeTextField;  
  4.     IBOutlet UIImageView *_imageView;  
  5. }  
  6.   
  7. - (IBAction)postButtonClicked:(id)sender;  
  8. - (IBAction)showCameraSheet:(id)sender;  
  9. @property (retain, nonatomic) IBOutlet UITextField *codeTextField;  
  10. </httpfileuploaddelegate,>  


HTTPFileUploadSampleViewController.mを以下のように修正
httpFileUpload postWithUriは自分のherokuのURLに修正してください。

  1. #import "HTTPFileUploadSampleViewController.h"  
  2.   
  3. @implementation HTTPFileUploadSampleViewController  
  4. @synthesize codeTextField = _codeTextField;  
  5.   
  6. - (void)dealloc  
  7. {  
  8.     [_imageView release];  
  9.     [_codeTextField release];  
  10.   [super dealloc];  
  11. }  
  12.   
  13. - (void)didReceiveMemoryWarning  
  14. {  
  15.   [super didReceiveMemoryWarning];  
  16. }  
  17.   
  18. #pragma mark - View lifecycle  
  19. - (void)viewDidLoad  
  20. {  
  21.   [super viewDidLoad];  
  22.     _codeTextField.returnKeyType = UIReturnKeyDone;  
  23.     _codeTextField.delegate = self;  
  24. }  
  25.   
  26. - (BOOL)textFieldShouldReturn:(UITextField *)textField {  
  27.     [_codeTextField resignFirstResponder];  
  28.     return YES;  
  29. }  
  30.   
  31. - (void)viewDidUnload  
  32. {  
  33.     [_imageView release];  
  34.     _imageView = nil;  
  35.     [codeTextField release];  
  36.     codeTextField = nil;  
  37.     [self setCodeTextField:nil];  
  38.   [super viewDidUnload];  
  39. }  
  40.   
  41. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  42. {  
  43.   return (interfaceOrientation == UIInterfaceOrientationPortrait);  
  44. }  
  45.   
  46. - (IBAction)postButtonClicked:(id)sender  
  47. {  
  48.   // Get image data.  
  49.   //UIImage *image1 = [UIImage imageNamed:@"Icon.png"];  
  50.     
  51.   // File upload.  
  52.   HTTPFileUpload *httpFileUpload = [[HTTPFileUpload alloc] init];  
  53.   httpFileUpload.delegate = self;  
  54.   [httpFileUpload setPostString:self.codeTextField.text withPostName:@"name"];  
  55.   [httpFileUpload setPostImage:_imageView.image withPostName:@"photo" fileName:@"Icon.png"];  
  56.   [httpFileUpload postWithUri:@"http://XXXX.herokuapp.com/users/photo.json"];  
  57.   [httpFileUpload release], httpFileUpload = nil;  
  58. }  
  59.   
  60. - (IBAction)showCameraSheet:(id)sender {  
  61.     // アクションシートを作る  
  62.     UIActionSheet*  sheet;  
  63.     sheet = [[UIActionSheet alloc]   
  64.              initWithTitle:@"Select Soruce Type"   
  65.              delegate:self   
  66.              cancelButtonTitle:@"Cancel"   
  67.              destructiveButtonTitle:nil   
  68.              otherButtonTitles:@"Photo Library", @"Camera", @"Saved Photos", nil];  
  69.     [sheet autorelease];  
  70.       
  71.     // アクションシートを表示する  
  72.     [sheet showInView:self.view];  
  73. }  
  74.   
  75. - (void)actionSheet:(UIActionSheet*)actionSheet   
  76. clickedButtonAtIndex:(NSInteger)buttonIndex  
  77. {  
  78.     // ボタンインデックスをチェックする  
  79.     if (buttonIndex >= 3) {  
  80.         return;  
  81.     }  
  82.       
  83.     // ソースタイプを決定する  
  84.     UIImagePickerControllerSourceType   sourceType = 0;  
  85.     switch (buttonIndex) {  
  86.         case 0: {  
  87.             sourceType = UIImagePickerControllerSourceTypePhotoLibrary;  
  88.             break;  
  89.         }  
  90.         case 1: {  
  91.             sourceType = UIImagePickerControllerSourceTypeCamera;  
  92.             break;  
  93.         }  
  94.         case 2: {  
  95.             sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;  
  96.             break;  
  97.         }  
  98.     }  
  99.       
  100.     // 使用可能かどうかチェックする  
  101.     if (![UIImagePickerController isSourceTypeAvailable:sourceType]) {    
  102.         return;  
  103.     }  
  104.       
  105.     // イメージピッカーを作る  
  106.     UIImagePickerController*    imagePicker;  
  107.     imagePicker = [[UIImagePickerController alloc] init];  
  108.     [imagePicker autorelease];  
  109.     imagePicker.sourceType = sourceType;  
  110.     imagePicker.allowsImageEditing = YES;  
  111.     imagePicker.delegate = self;  
  112.       
  113.     // イメージピッカーを表示する  
  114.     [self presentModalViewController:imagePicker animated:YES];  
  115. }  
  116.   
  117. - (void)imagePickerController:(UIImagePickerController*)picker   
  118.         didFinishPickingImage:(UIImage*)image   
  119.                   editingInfo:(NSDictionary*)editingInfo  
  120. {  
  121.     // イメージピッカーを隠す  
  122.     [self dismissModalViewControllerAnimated:YES];  
  123.     // オリジナル画像を取得する  
  124.     UIImage*    originalImage;  
  125.     originalImage = [editingInfo objectForKey:UIImagePickerControllerOriginalImage];  
  126.       
  127.     // グラフィックスコンテキストを作る  
  128.     CGSize  size = { 300, 400 };  
  129.     UIGraphicsBeginImageContext(size);  
  130.       
  131.     // 画像を縮小して描画する  
  132.     CGRect  rect;  
  133.     rect.origin = CGPointZero;  
  134.     rect.size = size;  
  135.     [originalImage drawInRect:rect];  
  136.       
  137.     // 描画した画像を取得する  
  138.     UIImage*    shrinkedImage;  
  139.     shrinkedImage = UIGraphicsGetImageFromCurrentImageContext();  
  140.     UIGraphicsEndImageContext();  
  141.       
  142.     // 画像を表示する  
  143.     _imageView.image = shrinkedImage;  
  144. }  
  145.   
  146. - (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker  
  147. {  
  148.     // イメージピッカーを隠す  
  149.     [self dismissModalViewControllerAnimated:YES];  
  150. }  
  151.   
  152. - (void)httpFileUpload:(NSURLConnection *)connection  
  153.       didFailWithError:(NSError *)error  
  154. {  
  155.   NSLog(@"%@", error);  
  156. }  
  157.   
  158. - (void)httpFileUploadDidFinishLoading:(NSURLConnection *)connection  
  159.                                 result:(NSString *)result  
  160. {  
  161.   NSLog(@"%@", result);  
  162.     UIAlertView *alert = [[UIAlertView alloc]  
  163.                           initWithTitle:@""   
  164.                           message:@"投稿完了しました。"   
  165.                           delegate:nil   
  166.                           cancelButtonTitle:@"OK"   
  167.                           otherButtonTitles:nil, nil];  
  168.     [alert show];  
  169.     [alert release];  
  170. }  
  171. @end  


次にここを参考にxibを作成。アクションシートを追加してください。(コードは上のものにすでに入ってます。)
http://news.mynavi.jp/column/iphone/001/index.html
同じような感じで、textfieldを追加してください。(codeTextField)

次にrails側。
こちらをベースに修正します。
https://github.com/face-do/heroku-image-uploader
UsersController.rbを以下の用に修正。
  1. def photo  
  2.   @user = User.new(:name => params[:name], :photo => params[:photo] )  
  3.   
  4.   respond_to do |format|  
  5.     if @user.save  
  6.       format.html { redirect_to @user, notice: 'User was successfully created.' }  
  7.       format.json { render json: @user, status: :created, location: @user }  
  8.     else  
  9.       format.html { render action: "new" }  
  10.       format.json { render json: @user.errors, status: :unprocessable_entity }  
  11.     end  
  12.   end  
  13. end  

config/routes.rbに以下を追記
post "users/photo" => 'users#photo'

app/controllers/application_controller.rbを以下のように修正。
  1. protect_from_forgery  :except => :photo  


で、herokuにあげて、iosアプリをiphoneに転送すれば、できます。
一応今回のファイルをgithubにあげておきました。
rails アプリのほう
iphoneクライアントの方

0 件のコメント:

コメントを投稿