问题描述
现在在我的Rails应用我使用Carrierwave将文件上传到Amazon S3。我使用一个文件选择器和一个表单来选择并提交文件,这个效果很好。
Right now in my rails app I'm using Carrierwave to upload files to Amazon S3. I'm using a file selector and a form to select and submit the file, this works well.
不过,我现在试图从一个iPhone应用程序使职位和我接收文件的内容。我想使用这些数据创建一个文件,然后将其上传使用Carrierwave,这样我可以得到正确的路径返回。
However, I'm now trying to make posts from an iPhone app and am receiving the contents of the file. I'd like to create a file using this data and then upload it using Carrierwave so that I can get the correct path back.
可以提交模型包括:
path
file_name
id
user_id
其中path是Amazon S3的网址。我想要做这样的事情可以构建文件:
where path is the Amazon S3 url. I'd like to do something like this to build the files:
data = params[:data]
~file creation magic using data~
~carrierwave upload magic using file~
@user_id = params[:id]
@file_name = params[:name]
@path = path_provided_by_carrierwave_magic
File.build(@user_id, @file_name, @path)
更喜欢有人点我在正确的方向。谢谢!
Would really love someone to point me in the right direction. Thanks!
推荐答案
好吧,我有一个有效的解决方案。我会更好地解释我做了什么,让其他人可以从我的经验中学习。这里有云:
Alright, I have a working solution. I'm going to best explain what I did so that others can learn from my experience. Here goes:
假设你有一个iPhone应用程序需要的图片:
Assuming you have an iPhone app that takes a picture:
//handle the image that has just been selected
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//get the image
UIImage* image = [info valueForKey:@"UIImagePickerControllerOriginalImage"];
//scale and rotate so you're not sending a sideways image -> method provided by http://blog.logichigh.com/2008/06/05/uiimage-fix/
image = [self scaleAndRotateImage:image];
//obtain the jpeg data (.1 is quicker to send, i found it better for testing)
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(image, .1)];
//get the data into a string
NSString* imageString = [NSString stringWithFormat:@"%@", imageData];
//remove whitespace from the string
imageString = [imageString stringByReplacingOccurrencesOfString:@" " withString:@""];
//remove < and > from string
imageString = [imageString substringWithRange:NSMakeRange(1, [imageString length]-2)];
self.view.hidden = YES;
//dismissed the camera
[picker dismissModalViewControllerAnimated:YES];
//posts the image
[self performSelectorInBackground:@selector(postImage:) withObject:imageString];
}
- (void)postImage:(NSString*)imageData
{
//image string formatted in json
NSString* imageString = [NSString stringWithFormat:@"{\"image\": \"%@\", \"authenticity_token\": \"\", \"utf8\": \"✓\"}", imageData];
//encoded json string
NSData* data = [imageString dataUsingEncoding:NSUTF8StringEncoding];
//post the image
[API postImage:data];
}[/code]
Then for the post:
[code]+(NSArray*)postImage:(NSData*) data
{
//url that you're going to send the image to
NSString* url = @"www.yoururl.com/images";
//pretty self explanatory request building
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setTimeoutInterval:10000];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod: @"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPBody:data];
NSError *requestError;
NSURLResponse *urlResponse = nil;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
return [API generateArrayWithData:result];
}
在铁轨边我成立了一个专门的方法来处理移动图像,这会帮助你通过Carrierwave张贴图片到您的Amazon S3帐户:
On the rails side I set up a method specifically for handling mobile images, this should help you post the image to your Amazon S3 account through Carrierwave:
def post
respond_to do |format|
format.json {
#create a new image so that you can call it's class method (a bit hacky, i know)
@image = Image.new
#get the json image data
pixels = params[:image]
#convert it from hex to binary
pixels = @image.hex_to_string(pixels)
#create it as a file
data = StringIO.new(pixels)
#set file types
data.class.class_eval { attr_accessor :original_filename, :content_type }
data.original_filename = "test1.jpeg"
data.content_type = "image/jpeg"
#set the image id, had some weird behavior when i didn't
@image.id = Image.count + 1
#upload the data to Amazon S3
@image.upload(data)
#save the image
if @image.save!
render :nothing => true
end
}
end
end
这对我的作品的发布,我觉得应该是pretty的扩展。对于类方法:
This works for me for posting and I feel should be pretty extendable. For the class methods:
#stores the file
def upload(file)
self.path.store!(file)
end
#converts the data from hex to a string -> found code here http://4thmouse.com/index.php/2008/02/18/converting-hex-to-binary-in-4-languages/
def hex_to_string(hex)
temp = hex.gsub("\s", "");
ret = []
(0...temp.size()/2).each{|index| ret[index] = [temp[index*2, 2]].pack("H2")}
file = String.new
ret.each { |x| file << x}
file
end
不是说这code是完美的,甚至没有一个跳槽。但是,它确实为我工作。我接受建议,如果有人认为它可以改进。希望这有助于!
Not saying this code is perfect, not even by a longshot. However, it does work for me. I'm open to suggestions if anyone thinks it could be improved. Hope this helps!
这篇关于Carrierwave中编程上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!