2012年3月19日月曜日

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

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

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

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

HTTPFileUploadSampleViewController.hを以下のように修正

@interface HTTPFileUploadSampleViewController : UIViewController
{
IBOutlet UITextField *codeTextField;
IBOutlet UIImageView *_imageView;
}

- (IBAction)postButtonClicked:(id)sender;
- (IBAction)showCameraSheet:(id)sender;
@property (retain, nonatomic) IBOutlet UITextField *codeTextField;


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


#import "HTTPFileUploadSampleViewController.h"

@implementation HTTPFileUploadSampleViewController
@synthesize codeTextField = _codeTextField;

- (void)dealloc
{
[_imageView release];
[_codeTextField release];
[super dealloc];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
_codeTextField.returnKeyType = UIReturnKeyDone;
_codeTextField.delegate = self;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[_codeTextField resignFirstResponder];
return YES;
}

- (void)viewDidUnload
{
[_imageView release];
_imageView = nil;
[codeTextField release];
codeTextField = nil;
[self setCodeTextField:nil];
[super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (IBAction)postButtonClicked:(id)sender
{
// Get image data.
//UIImage *image1 = [UIImage imageNamed:@"Icon.png"];

// File upload.
HTTPFileUpload *httpFileUpload = [[HTTPFileUpload alloc] init];
httpFileUpload.delegate = self;
[httpFileUpload setPostString:self.codeTextField.text withPostName:@"name"];
[httpFileUpload setPostImage:_imageView.image withPostName:@"photo" fileName:@"Icon.png"];
[httpFileUpload postWithUri:@"http://XXXX.herokuapp.com/users/photo.json"];
[httpFileUpload release], httpFileUpload = nil;
}

- (IBAction)showCameraSheet:(id)sender {
// アクションシートを作る
UIActionSheet* sheet;
sheet = [[UIActionSheet alloc]
initWithTitle:@"Select Soruce Type"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Photo Library", @"Camera", @"Saved Photos", nil];
[sheet autorelease];

// アクションシートを表示する
[sheet showInView:self.view];
}

- (void)actionSheet:(UIActionSheet*)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex
{
// ボタンインデックスをチェックする
if (buttonIndex >= 3) {
return;
}

// ソースタイプを決定する
UIImagePickerControllerSourceType sourceType = 0;
switch (buttonIndex) {
case 0: {
sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
break;
}
case 1: {
sourceType = UIImagePickerControllerSourceTypeCamera;
break;
}
case 2: {
sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
break;
}
}

// 使用可能かどうかチェックする
if (![UIImagePickerController isSourceTypeAvailable:sourceType]) {
return;
}

// イメージピッカーを作る
UIImagePickerController* imagePicker;
imagePicker = [[UIImagePickerController alloc] init];
[imagePicker autorelease];
imagePicker.sourceType = sourceType;
imagePicker.allowsImageEditing = YES;
imagePicker.delegate = self;

// イメージピッカーを表示する
[self presentModalViewController:imagePicker animated:YES];
}

- (void)imagePickerController:(UIImagePickerController*)picker
didFinishPickingImage:(UIImage*)image
editingInfo:(NSDictionary*)editingInfo
{
// イメージピッカーを隠す
[self dismissModalViewControllerAnimated:YES];
// オリジナル画像を取得する
UIImage* originalImage;
originalImage = [editingInfo objectForKey:UIImagePickerControllerOriginalImage];

// グラフィックスコンテキストを作る
CGSize size = { 300, 400 };
UIGraphicsBeginImageContext(size);

// 画像を縮小して描画する
CGRect rect;
rect.origin = CGPointZero;
rect.size = size;
[originalImage drawInRect:rect];

// 描画した画像を取得する
UIImage* shrinkedImage;
shrinkedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// 画像を表示する
_imageView.image = shrinkedImage;
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker
{
// イメージピッカーを隠す
[self dismissModalViewControllerAnimated:YES];
}

- (void)httpFileUpload:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
NSLog(@"%@", error);
}

- (void)httpFileUploadDidFinishLoading:(NSURLConnection *)connection
result:(NSString *)result
{
NSLog(@"%@", result);
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@""
message:@"投稿完了しました。"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
@end


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

次にrails側。
こちらをベースに修正します。
https://github.com/face-do/heroku-image-uploader
UsersController.rbを以下の用に修正。

def photo
@user = User.new(:name => params[:name], :photo => params[:photo] )

respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render json: @user, status: :created, location: @user }
else
format.html { render action: "new" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end

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

app/controllers/application_controller.rbを以下のように修正。

protect_from_forgery :except => :photo


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

0 件のコメント:

コメントを投稿