2016-08-09 17 views
2

Ich versuche, ein Bild von einem iOS-Gerät auf eine Rails-API hochzuladen, die zum Speichern von Bildern auf AWS Büroklammern verwendet. Alles funktioniert gut, wenn ich Postman den API-Aufruf senden. Dies sind die Heroku Protokolle, wenn ich die Anfrage von Postbote nennen ...Das Hochladen von Bildern auf Paperclip mit einer mehrteiligen Anfrage unter Swift

Processing by Api::V1::FeedsController#create as JSON 
Parameters: {"image"=>#<ActionDispatch::Http::UploadedFile:0x007f1f7d30c5c0 @tempfile=#<Tempfile:/tmp/RackMultipart20160809-3-c6leue.jpg>, @original_filename="458989879.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"image\"; filename=\"458989879.jpg\"\r\nContent-Type: image/jpeg\r\n">, "subdomain"=>"api", "uid"=>"6"} 
Can't verify CSRF token authenticity 
Geokit is using the domain: 
Command :: file -b --mime '/tmp/5c6db5b2d12287ce12f1345f27b0ac2f20160809-3-ovx51i.jpg' 
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/5c6db5b2d12287ce12f1345f27b0ac2f20160809-3-1j7oszw.jpg[0]' 2>/dev/null 
Command :: identify -format %m '/tmp/5c6db5b2d12287ce12f1345f27b0ac2f20160809-3-1j7oszw.jpg[0]' 
Command :: convert '/tmp/5c6db5b2d12287ce12f1345f27b0ac2f20160809-3-1j7oszw.jpg[0]' -auto-orient -resize "300x300>" '/tmp/b4a012d2ad09b09e0ccb3d15a438648a20160809-3-vvgjkn' 
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/5c6db5b2d12287ce12f1345f27b0ac2f20160809-3-1j7oszw.jpg[0]' 2>/dev/null 
Command :: identify -format %m '/tmp/5c6db5b2d12287ce12f1345f27b0ac2f20160809-3-1j7oszw.jpg[0]' 
Command :: convert '/tmp/5c6db5b2d12287ce12f1345f27b0ac2f20160809-3-1j7oszw.jpg[0]' -auto-orient -resize "100x100>" '/tmp/b4a012d2ad09b09e0ccb3d15a438648a20160809-3-19eu3y9' 
(2.3ms) BEGIN 
Command :: file -b --mime '/tmp/5c6db5b2d12287ce12f1345f27b0ac2f20160809-3-k5lzw7.jpg' 
SQL (4.5ms) INSERT INTO "feeds" ("user_id", "message", "image_file_name", "image_content_type", "image_file_size", "image_updated_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["user_id", 6], ["message", "wow"], ["image_file_name", "458989879.jpg"], ["image_content_type", "image/jpeg"], ["image_file_size", 78487], ["image_updated_at", "2016-08-09 14:39:57.766228"], ["created_at", "2016-08-09 14:39:57.985558"], ["updated_at", "2016-08-09 14:39:57.985558"]] 
[paperclip] saving /feeds/images/000/000/018/original/458989879.jpg 
[AWS S3 200 0.110633 0 retries] put_object(:acl=>:public_read,:bucket_name=>"petoye",:content_length=>78487,:content_type=>"image/jpeg",:data=>Paperclip::UploadedFileAdapter: 458989879.jpg,:key=>"feeds/images/000/000/018/original/458989879.jpg") 
[paperclip] saving /feeds/images/000/000/018/thumb/458989879.jpg 
[paperclip] saving /feeds/images/000/000/018/medium/458989879.jpg 
(1.7ms) COMMIT 
[AWS S3 200 0.071674 0 retries] put_object(:acl=>:public_read,:bucket_name=>"petoye",:content_length=>8944,:content_type=>"image/jpeg",:data=>Paperclip::FileAdapter: b4a012d2ad09b09e0ccb3d15a438648a20160809-3-19eu3y9,:key=>"feeds/images/000/000/018/thumb/458989879.jpg") 
[AWS S3 200 0.037868 0 retries] put_object(:acl=>:public_read,:bucket_name=>"petoye",:content_length=>41611,:content_type=>"image/jpeg",:data=>Paperclip::FileAdapter: b4a012d2ad09b09e0ccb3d15a438648a20160809-3-vvgjkn,:key=>"feeds/images/000/000/018/medium/458989879.jpg") 
Completed 201 Created in 462ms (Views: 2.5ms | ActiveRecord: 8.6ms) 

Als ich dies von einem Simulator versuchen zu tun ...

Processing by Api::V1::FeedsController#create as JSON 
Parameters: {"test"=>"hi", "file"=>#<ActionDispatch::Http::UploadedFile:0x007f1f7ddb6390 @tempfile=#<Tempfile:/tmp/RackMultipart20160809-3-1rdm92u.png>, @original_filename="test.png", @content_type="image/png", @headers="Content-Disposition:form-data; name=\"file\"; filename=\"test.png\"\r\nContent-Type: image/png\r\n">, "subdomain"=>"api", "uid"=>"6"} 
Geokit is using the domain: 
(0.7ms) BEGIN 
Started POST "/feeds/6/create" for at 2016-08-09 14:43:45 +0000 
(0.6ms) ROLLBACK 
Completed 422 Unprocessable Entity in 6ms (Views: 2.5ms | ActiveRecord: 1.3ms) 
Can't verify CSRF token authenticity 
at=info method=POST path="/feeds/6/create" host= request_id=b4d0506f-a1ce-477e-993b-fc39e338e0fc fwd="" dyno=web.1 connect=1ms service=37566ms status=422 bytes=435 

Das ist mein Code ist, wenn ich das Bild hochladen, mit Swift

func UploadRequest() 
{ 
    let url = NSURL(string: "") 

    let request = NSMutableURLRequest(URL: url!) 
    request.HTTPMethod = "POST" 

    let boundary = generateBoundaryString() 

    //define the multipart request type 

    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") 

    if (postImage.image == nil) 
    { 
     return 
    } 

    let image_data = UIImagePNGRepresentation(postImage.image!) 


    if(image_data == nil) 
    { 
     return 
    } 


    let body = NSMutableData() 

    let fname = "test.png" 
    let mimetype = "image/png" 

    //define the data post parameter 

    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("Content-Disposition:form-data; name=\"test\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("hi\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 



    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("Content-Disposition:form-data; name=\"file\"; filename=\"\(fname)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData(image_data!) 
    body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 


    body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 



    request.HTTPBody = body 



    let session = NSURLSession.sharedSession() 


    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in 
     guard error == nil && data != nil else {               // check for fundamental networking error 
      print(error!) 
      return 
     } 

     if let httpStat = response as? NSHTTPURLResponse where httpStat.statusCode == 201 
     { 
      //pop up comment added 


     } 


     if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 201 {   // check for http errors 
      print("statusCode should be 201, but is \(httpStatus.statusCode)") 
      print(response!) 
     } 

     var responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) 
     print(responseString!) 


    } 
    task.resume() 

} 

ich bin für eine Weile jetzt auf diese stecken und haben festgestellt, nicht wirklich eine Frage, die für Büroklammer sowie rasche funktioniert, also bitte machen Sie mir etwas, das für beide funktioniert.

Antwort

1

Ich habe die folgenden Änderungen an dem Körperblock, den ich oben in meiner Frage gestellt ..

body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
body.appendData("Content-Disposition:form-data; name=\"image\"; filename=\"\(fname)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
body.appendData(image_data!) 
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 

Und dann dachte ich irgendwie heraus, was schiefgeht ..

I Ich habe versucht, ein Standardbild hochzuladen, das vom iOS-Simulator sehr groß war. Also habe ich die App auf meinem iPhone-Gerät installiert und versucht, ein relativ kleines Bild hochzuladen und der Upload war erfolgreich.

Also ging ich zu meinem Feed-Modell auf meiner Rails API, wo ich das Bild nahm. Das war der Code.

has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png" 
validates_attachment :image, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] } 
validates_with AttachmentSizeValidator, attributes: :image, less_than: 1.megabytes 
validates_with AttachmentPresenceValidator, attributes: :image 

Wie Sie in der dritten Zeile sehen ich die Bildgrößen auf weniger als 1 MB beschränkt war, so dass ich entfernt nur diese Zeile und alles funktioniert jetzt gut.

0
let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!) 

mutableURLRequest.HTTPMethod = Alamofire.Method.POST.rawValue 
let boundaryConstant = "myRandomBoundary12345"; 
     let contentType = "multipart/form-data;boundary="+boundaryConstant 
     mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type") 
     let uploadData = NSMutableData() 

     for (key, value) in files { 
      if let data = value.data{ 
       uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
       uploadData.appendData(String("Content-Disposition: form-data; name=\"" + key + "\"; filename=\""+value.fileName+"\"\r\n").dataUsingEncoding(NSUTF8StringEncoding)!) 
       if let contentType = value.contentType{ 
        uploadData.appendData(("Content-Type: " + contentType + "\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!) 
       } 
       uploadData.appendData(data) 
      } 
     } 
     if let params = parameters { 
      for (key, value) in params { 
       uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
       uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!) 
      } 
     } 
     uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
     return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData) 
+0

Ich weiß Alamofire ist besser zu verwenden, aber aus irgendeinem Grund kann ich es nicht verwenden. –

Verwandte Themen