Alamofire kullanarak parametreli dosya yükleme


95

Kullanarak bir dosya yüklemeye çalışıyorum Alamofire. Dosya ( NSUrl) kullanılırken yükleme iyi çalışıyor , ancak NSDataseçeneğin nasıl kullanılacağını çözemiyorum.

Test olarak sahip olduğum şey bu:

 var url:NSURL = NSURL.URLWithString("http://localhost:8080/bike.jpeg")

 var err: NSError?
 var imageData :NSData = NSData.dataWithContentsOfURL(url,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)

 Alamofire.upload(.POST, "http://localhost:8080/rest/service/upload/test.png", imageData)
        .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
            println(totalBytesWritten)
        }
        .responseJSON { (request, response, JSON, error) in
            println(request)
            println(response)
           println(JSON)
 }

415 durum kodu alıyorum?

Ayrıca, yüklemede ek parametreleri nasıl gönderebilirim?

Teşekkürler

DÜZENLE

Doğru İçerik Türünü ayarlamıyordum:

var manager = Manager.sharedInstance
manager.session.configuration.HTTPAdditionalHeaders = ["Content-Type": "application/octet-stream"]


let imageData: NSMutableData = NSMutableData.dataWithData(UIImageJPEGRepresentation(imageTest.image, 30));

Alamofire.upload(.POST, "http://localhost:8080/rest/service/upload?attachmentName=file.jpg",  imageData)
        .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
            println(totalBytesWritten)
        }
        .responseString { (request, response, JSON, error) in
            println(request)
            println(response)
            println(JSON)
}

Hala yüklemeyle birlikte ek parametrelerin nasıl gönderileceğini çözemiyorum.


"MultipartFormData.appendBodyPart (data: image1Data, name:" file ", fileName:" myImage.png ", mimeType:" image / png ")" kullanın, aksi takdirde "0 karakteri etrafında geçersiz değer" hatası al
Avijit Nagare

Yanıtlar:


81

Burada, hedef yükleme url'sini, parametrelerini ve imageData'yı gerektiren ve Alamofire.upload'un parametrelerle bir görüntü yüklemek için gerektirdiği URLRequestConvertible ve NSData'yı döndüren basit bir işlev verilmiştir.

// this function creates the required URLRequestConvertible and NSData we need to use Alamofire.upload
func urlRequestWithComponents(urlString:String, parameters:Dictionary<String, String>, imageData:NSData) -> (URLRequestConvertible, NSData) {

    // create url request to send
    var 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")



    // create upload data to send
    let uploadData = NSMutableData()

    // add image
    uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    uploadData.appendData("Content-Disposition: form-data; name=\"file\"; filename=\"file.png\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    uploadData.appendData(imageData)

    // add parameters
    for (key, value) in parameters {
        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 URLRequestConvertible and NSData
    return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData)
}    

İşte nasıl kullanılacağına dair bir örnek (bkz. İSTEK OLUŞTURMA VE GÖNDERME):

// init paramters Dictionary
var parameters = [
    "task": "task",
    "variable1": "var"
]

// add addtionial parameters
parameters["userId"] = "27"
parameters["body"] = "This is the body text."

// example image data
let image = UIImage(named: "177143.jpg")
let imageData = UIImagePNGRepresentation(image)



// CREATE AND SEND REQUEST ----------

let urlRequest = urlRequestWithComponents("http://example.com/uploadText/", parameters: parameters, imageData: imageData)

Alamofire.upload(urlRequest.0, urlRequest.1)
    .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
        println("\(totalBytesWritten) / \(totalBytesExpectedToWrite)")
    }
    .responseJSON { (request, response, JSON, error) in
        println("REQUEST \(request)")
        println("RESPONSE \(response)")
        println("JSON \(JSON)")
        println("ERROR \(error)")
}    

Ve hedef url için php dosyasına ihtiyacınız varsa (aynı dizinde bir 'yüklemeler' klasörü ile):

// get picture variables
$file       = $_FILES['file']['tmp_name'];
$fileName   = $_FILES['file']['name'];
$fileType   = $_FILES['file']['type'];

// check extension
$allowedExts = array("jpg", "jpeg", "png");
$rootName = reset(explode(".", $fileName));
$extension = end(explode(".", $fileName));

// create new file name
$time = time();
$newName = $rootName.$time.'.'.$extension;

// temporarily save file
$moved = move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/".$newName );
if ($moved) $path = "uploads/".$newName;

$body = $_POST['body'];
$userId = $_POST['userId'];


$time = time();
if ($moved) {
    $fullUrl = "http://antiblank.com/testPhotoUpload/".$path;
    $arrayToSend = array('status'=>'success','time'=>$time,'body'=>$body,'userId'=>$userId, "imageURL"=>$fullUrl);
} else {
    $arrayToSend = array('status'=>'FAILED','time'=>$time,'body'=>$body,'userId'=>$userId);
}

header('Content-Type:application/json');
echo json_encode($arrayToSend);

Merhaba, ben zaten bu yöntemi kullanıyorum ve iyi çalışıyor ancak sunucu tarafında istek içerik türünü değiştiriyorlar JSON. Bu yöntemin çalışmamasından sonra verileri json olarak yüklemek istiyorum ... lütfen bana yardım eder misin
mychar

1
hemen hemen doğru, uploadData.appendData ("Content-Disposition: form-data; name = \" file \ "; filename = \" file.png \ "\ r \ n" .dataUsingEncoding (NSUTF8StringEncoding)!) bu satırda name = \ "dosya \", aslında dosya sunucu tarafından ele alınacak anahtar adıdır ... ataç gibi.
Albert.Qing

Madenler daha önce çalışıyordu ve şimdi NSCocoaErrorDomain kodu 3840 alıyorum, kimse bu sorunu çözdü mü?
Godfather

@antiblank bu kodu paylaştığınız için teşekkür ederiz. Kullanıcıların web servis çağrıma bir resim yükleyip yüklememe seçeneğine sahip olduklarından, resim parametresi için NSData veya null kabul edebilecek şekilde bu işlevi nasıl değiştireceğinizi tavsiye edebilir misiniz? Tanımda NSData yerine anyObject kullanabilir miyim
user2363025

3
bunu başlıklar dahil nasıl yapabiliriz?
Poonam

73

Swift 3 & 4 ve Alamofire 4 üzerinden parametreler ve özel başlıklarla Fotoğraf / Dosya yükleyin

// import Alamofire
func uploadWithAlamofire() {
  let image = UIImage(named: "bodrum")!

  // define parameters
  let parameters = [
    "hometown": "yalikavak",
    "living": "istanbul"
  ]

  Alamofire.upload(multipartFormData: { multipartFormData in
    if let imageData = UIImageJPEGRepresentation(image, 1) {
      multipartFormData.append(imageData, withName: "file", fileName: "file.png", mimeType: "image/png")
    }

    for (key, value) in parameters {
      multipartFormData.append((value?.data(using: .utf8))!, withName: key)
    }}, to: "upload_url", method: .post, headers: ["Authorization": "auth_token"],
        encodingCompletion: { encodingResult in
          switch encodingResult {
          case .success(let upload, _, _):
            upload.response { [weak self] response in
              guard let strongSelf = self else {
                return
              }
              debugPrint(response)
            }
          case .failure(let encodingError):
            print("error:\(encodingError)")
          }
  })
}

Swift 2 ve Alamofire 3 aracılığıyla

  // import Alamofire
  func uploadWithAlamofire() {
    let image = UIImage(named: "myImage")!

    // define parameters
    let parameters = [
      "hometown": "yalikavak",
      "living": "istanbul"
    ]

    // Begin upload
    Alamofire.upload(.POST, "upload_url",
      // define your headers here
      headers: ["Authorization": "auth_token"],
      multipartFormData: { multipartFormData in

        // import image to request
        if let imageData = UIImageJPEGRepresentation(image, 1) {
          multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "myImage.png", mimeType: "image/png")
        }

        // import parameters
        for (key, value) in parameters {
          multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
        }
      }, // you can customise Threshold if you wish. This is the alamofire's default value
      encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold,
      encodingCompletion: { encodingResult in
        switch encodingResult {
        case .Success(let upload, _, _):
          upload.responseJSON { response in
            debugPrint(response)
          }
        case .Failure(let encodingError):
          print(encodingError)
        }
    })
  }

Güncel hızlı sürüm: https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#uploading-data-to-a-server


Eğer imageData = UIImageJPEGRepresentation (image, 1) {multipartFormData.append (imageData, withName: "file", fileName: "file.png", mimeType: "image / png")} ise parametreleri (anahtar değeri)} + {multipartFormData.append ((değer .Data (kullanarak: .utf8)) !, withName anahtarı?)}
Ravi Ojha

1
Bu takdirde çalışmaz parametersolduğu [String:Any]çünkü value.data(using: .utf8))!için geçerli değil Any Type. Bunu nasıl çözeceğiniz konusunda bir öneriniz var mı?
Chlebta

57

İşte anti -lanks cevabına dayalı Alamofire 3.0 kullanan bir Çözüm:

 let parameters = [
            "par1": "value",
            "par2": "value2"]    

 let URL = "YOUR_URL.php"

 let image = UIImage(named: "image.png")

 Alamofire.upload(.POST, URL, multipartFormData: {
                multipartFormData in

                if let _image = image {
                    if let imageData = UIImageJPEGRepresentation(_image, 0.5) {
                        multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "file.png", mimeType: "image/png")
                    }
                }

                for (key, value) in parameters {
                    multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
                }

            }, encodingCompletion: {
                encodingResult in

                switch encodingResult {
                case .Success(let upload, _, _):
                     upload.responseObject { (response: Response<UploadData, NSError>) -> Void in

                     switch response.result {
                     case .Success:
                         completionHandler?(success: true)
                     case .Failure(let error):
                         completionHandler?(success: false)
                     }

                 }
                case .Failure(let encodingError):
                    print(encodingError)
                }
        })

Bu yüklemeyi iptal etmeye ne dersiniz? Diğer yanıtlarda, yüklemeyi bir var'a atamayı söyleyen insanlar görüyorum, ancak bunu yaptığımda tür () olarak çıkarılıyor, dolayısıyla yöntemlerin çağrılmasına izin vermiyor mu? Teşekkürler.
Sean Lintern

@ SeanLintern88: Request-Object üzerinde cancel () 'i çağırabilirsiniz. Şunun gibi bir şey: upload.cancel (). İstek-Nesnesini bir değişkene atayabilir ve iptal edebilirsiniz ()
EdFunke

1
case .Success(let upload, _, _) uploadbulunamadı. Bir şey mi kaçırıyorum?
fatihyildizhan

@fatihyildizhan encodingResultbir MultipartFormDataEncodingResultnumaralandırmadır. .Success Case(Aşağıdaki parametrelere sahiptir request: Request, streamingFromDisk: Bool, streamFileURL: NSURL?) Böylece uploadbir talep olduğunu. Ekledin import Alamofiremi
EdFunke

Bununla nasıl ilerlemeyi sürdürüyorsunuz?
hris.

10

EdFunke'nin Swift 2.2 Alamofire 3.3.1 için yanıtını geliştirmek

Alamofire.upload(.POST, urlString, multipartFormData: {
            multipartFormData in
            if let _image = self.profilePic.image {
                if let imageData = UIImagePNGRepresentation(_image) {
                    multipartFormData.appendBodyPart(data: imageData, name: "user_image", fileName: "file.png", mimeType: "image/png")
                }
            }
            for (key, value) in userInfo {
                multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
            }
            }, encodingCompletion: { encodingResult in
                switch encodingResult {
                case .Success(let upload, _, _):
                    upload.responseJSON { response in
                        debugPrint(response)
                    }
                case .Failure(let encodingError):
                    print(encodingError)
                }
            }
        )

4

Çok parçalı yüklemenin Alamofire'ın bir sonraki (1.3.0) sürümüne dahil edilmesi planlanmaktadır. Bu arada, bu iş parçacığındaki bilgileri kullanarak, dosya yüklemeyi basitleştiren ve isteğe ek parametreler (normal "girdiler") ekleyerek bir veya daha fazla dosya içeren bir sınıf yaptım. Dosyaların belirli bir türde olduğunu veya Yönlendiriciler kullandığını varsaymadan.

FileUploader.swift:

import Foundation
import Alamofire

private struct FileUploadInfo {
  var name:String
  var mimeType:String
  var fileName:String
  var url:NSURL?
  var data:NSData?

  init( name: String, withFileURL url: NSURL, withMimeType mimeType: String? = nil ) {
    self.name = name
    self.url = url
    self.fileName = name
    self.mimeType = "application/octet-stream"
    if mimeType != nil {
      self.mimeType = mimeType!
    }
    if let _name = url.lastPathComponent {
      fileName = _name
    }
    if mimeType == nil, let _extension = url.pathExtension {
      switch _extension.lowercaseString {

      case "jpeg", "jpg":
        self.mimeType = "image/jpeg"

      case "png":
        self.mimeType = "image/png"

      default:
        self.mimeType = "application/octet-stream"
      }
    }
  }

  init( name: String, withData data: NSData, withMimeType mimeType: String ) {
    self.name = name
    self.data = data
    self.fileName = name
    self.mimeType = mimeType
  }
}

class FileUploader {

  private var parameters = [String:String]()
  private var files = [FileUploadInfo]()
  private var headers = [String:String]()

  func setValue( value: String, forParameter parameter: String ) {
    parameters[parameter] = value
  }

  func setValue( value: String, forHeader header: String ) {
    headers[header] = value
  }

  func addParametersFrom( #map: [String:String] ) {
    for (key,value) in map {
      parameters[key] = value
    }
  }

  func addHeadersFrom( #map: [String:String] ) {
    for (key,value) in map {
      headers[key] = value
    }
  }

  func addFileURL( url: NSURL, withName name: String, withMimeType mimeType:String? = nil ) {
    files.append( FileUploadInfo( name: name, withFileURL: url, withMimeType: mimeType ) )
  }

  func addFileData( data: NSData, withName name: String, withMimeType mimeType:String = "application/octet-stream" ) {
    files.append( FileUploadInfo( name: name, withData: data, withMimeType: mimeType ) )
  }

  func uploadFile( request sourceRequest: NSURLRequest ) -> Request? {
    var request = sourceRequest.mutableCopy() as! NSMutableURLRequest
    let boundary = "FileUploader-boundary-\(arc4random())-\(arc4random())"
    request.setValue( "multipart/form-data;boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
    let data = NSMutableData()

    for (name, value) in headers {
      request.setValue(value, forHTTPHeaderField: name)
    }

    // Amazon S3 (probably others) wont take parameters after files, so we put them first        
    for (key, value) in parameters {
      data.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
      data.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!)
    }

    for fileUploadInfo in files {
      data.appendData( "\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)! )
      data.appendData( "Content-Disposition: form-data; name=\"\(fileUploadInfo.name)\"; filename=\"\(fileUploadInfo.fileName)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
      data.appendData( "Content-Type: \(fileUploadInfo.mimeType)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
      if fileUploadInfo.data != nil {
        data.appendData( fileUploadInfo.data! )
      }
      else if fileUploadInfo.url != nil, let fileData = NSData(contentsOfURL: fileUploadInfo.url!) {
        data.appendData( fileData )
      }
      else { // ToDo: report error
        return nil
      }
    }

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

    return Alamofire.upload( request, data )
  }

}

Şu şekilde kullanılacaktır:

// This example uploads a file called example.png found in the app resources

let fileURL = NSBundle.mainBundle().URLForResource("example", withExtension: "png")
let fileUploader = FileUploader()
// we can add multiple files
// this would be equivalent to: <input type="file" name="myFile"/>
fileUploader.addFileURL(fileURL!, withName: "myFile")
// we can add NSData objects directly
let data = UIImage(named: "sample")
fileUploader.addFileData( UIImageJPEGRepresentation(data,0.8), withName: "mySecondFile", withMimeType: "image/jpeg" )
// we can also add multiple aditional parameters
// this would be equivalent to: <input type="hidden" name="folderName" value="sample"/>
fileUploader.setValue( "sample", forParameter: "folderName" )
// put your server URL here
var request = NSMutableURLRequest( URL: NSURL(string: "http://myserver.com/uploadFile" )! )
request.HTTPMethod = "POST"
fileUploader.uploadFile(request: request)

Bir göz atın veya bu özetten indirin: https://gist.github.com/ncerezo/b1991f8dfac01cb162c0


Merhaba, örnek durumunuzda, yükleme işleminin başarısını veya iOS tarafında başarısızlığı kontrol etmenin herhangi bir yolu var mı? Cevabın için teşekkür ederim.
Zigii Wong

Evet tabi ki. Bahsettiğim gibi, uploadFile (istek) yöntemi, Alamofire.request yöntemi gibi bir Request nesnesi döndürür, böylece ilerlemeyi ve / veya yanıt kapanışlarını basitçe zincirleyebilirsiniz. Örneğin: fileUploader.uploadFile (istek: istek) .response {(istek, yanıt, veri, hata) içinde ....}
ncerezo

3

@ Antiblank'ın cevabındaki kod benim için çalışmıyordu. Birkaç değişiklik yaptım ve şu anda çalışıyor:

func urlRequestWithComponents(urlString:String, parameters:NSDictionary) -> (URLRequestConvertible, NSData) {

    // create url request to send
    var mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!)
    mutableURLRequest.HTTPMethod = Alamofire.Method.POST.rawValue
    //let boundaryConstant = "myRandomBoundary12345"
    let boundaryConstant = "NET-POST-boundary-\(arc4random())-\(arc4random())"
    let contentType = "multipart/form-data;boundary="+boundaryConstant
    mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")


    // create upload data to send
    let uploadData = NSMutableData()

    // add parameters
    for (key, value) in parameters {

        uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

        if value is NetData {
            // add image
            var postData = value as NetData


            //uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(postData.filename)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

            // append content disposition
            var filenameClause = " filename=\"\(postData.filename)\""
            let contentDispositionString = "Content-Disposition: form-data; name=\"\(key)\";\(filenameClause)\r\n"
            let contentDispositionData = contentDispositionString.dataUsingEncoding(NSUTF8StringEncoding)
            uploadData.appendData(contentDispositionData!)


            // append content type
            //uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) // mark this. 
            let contentTypeString = "Content-Type: \(postData.mimeType.getString())\r\n\r\n"
            let contentTypeData = contentTypeString.dataUsingEncoding(NSUTF8StringEncoding)
            uploadData.appendData(contentTypeData!)
            uploadData.appendData(postData.data)

        }else{
            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 URLRequestConvertible and NSData
    return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData)
}

KULLANIM:

let docDir:AnyObject = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let imagePath = docDir + "/myPic.jpg"

var imageData = NSData(contentsOfFile: imagePath, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: nil)
var parameters = [
            "pic"           :NetData(nsData: imageData!, filename: "customName.jpg"),
            "otherParm"     :"Value"
        ]


    let urlRequest = self.urlRequestWithComponents("http://www.example.com/upload.php", parameters: parameters)

Https://github.com/nghialv/Net/blob/master/Net/NetData.swift adresinden alınan NetData

upload.php Kodu:

<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

$uploaddir = 'uploads/';
// PS: custom filed name : pic
$uploadfile = $uploaddir . basename($_FILES['pic']['name']);

if (move_uploaded_file($_FILES['pic']['tmp_name'], $uploadfile)) {
   $array = array ("code" => "1", "message" => "successfully");  
} else {
   $array = array ("code" => "0", "message" => "Possible file upload attack!".$_FILES['pic']['name']); 
}

echo json_encode ( $array );  

?>

Ne tür bir değişiklik yaptığınızı söylerseniz iyi olur. @ Antiblank'ın cevabında bir düzenleme olabilecek basit bir iyileştirme miydi?
Luís Cruz

3
Merhaba milz, evet @antiblank cevabından sadece birkaç değişiklik, kod bana çok yardımcı oluyor. Teşekkürler
Vincent Yan

2

@Antiblank ve @VincentYan cevaplarına dayalı daha kısa versiyon.

Sınıf

class Photo {
    class func upload(image: UIImage, filename: String) -> Request {
        let route = Router.CreatePhoto()
        var request = route.URLRequest.mutableCopy() as NSMutableURLRequest
        let boundary = "NET-POST-boundary-\(arc4random())-\(arc4random())"
        request.setValue("multipart/form-data;boundary="+boundary,
                         forHTTPHeaderField: "Content-Type")

        let parameters = NSMutableData()
        for s in ["\r\n--\(boundary)\r\n",
                  "Content-Disposition: form-data; name=\"photos[photo]\";" +
                    " filename=\"\(filename)\"\r\n",
                  "Content-Type: image/png\r\n\r\n"] {
            parameters.appendData(s.dataUsingEncoding(NSUTF8StringEncoding)!)
        }
        parameters.appendData(UIImageJPEGRepresentation(image, 1))
        parameters.appendData("\r\n--\(boundary)--\r\n"
                               .dataUsingEncoding(NSUTF8StringEncoding)!)
        return Alamofire.upload(request, parameters)
    }
}

Kullanım

let rep = (asset as ALAsset).defaultRepresentation()
let ref = rep.fullResolutionImage().takeUnretainedValue()
Photo.upload(UIImage(CGImage: ref)!, filename: rep.filename())
    .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
        println(totalBytesWritten)
    }
    .responseJSON { (request, response, JSON, error) in
        println(JSON)
    }

@TomoMatsumotto Kodunuzu kullanmaya çalıştığımda "Çözümlenmemiş 'Yönlendirici' tanımlayıcı kullanımı" hatası alıyorum, Yönlendirici'nin burada kullandığınız bir numara olduğunu düşünüyorum. Lütfen cevabı günceller misiniz? Thankz
Ankahathara

@Ankahathara Ya bir Yönlendirici listesi oluşturun ya da Yönlendirici kullanmak yerine NSURLRequest'i manuel olarak oluşturun. github.com/Alamofire/Alamofire
Tom

2

Çok parçalı istekleri manuel olarak nasıl oluşturacağınızı öneren başka yanıtlar olsa da, yalnızca AFNetworking'e bağlı kalmak isteyebilirsiniz. Objective-C'de yazılmış olmasına rağmen, yine de Swift projelerinizde kullanabilirsiniz ( Aynı Projede Swift ve Objective-C'ye bakın ). Her neyse, AFNetworking kullanarak çok parçalı bir istek göndermek için Swift kodu aşağıdaki gibidir:

let data = UIImagePNGRepresentation(image)

let manager = AFHTTPSessionManager()

manager.POST(uploadURLString, parameters: nil, constructingBodyWithBlock: { formData in
    formData.appendPartWithFileData(data, name: "image", fileName: "test.png", mimeType: "image/png")
}, success: { operation, responseObject in
    println(responseObject)
}) { operation, error in
    println(error)
}

Xcode sinir bozucu bu id<AFMultipartFormData>parametreyi tanımakta sorun yaşar formData, bu nedenle appendPartWithFileDatayöntemin veya parametrelerinin tipik düzenleyici kod tamamlamasından hoşlanmazsınız , ancak onu derleyip çalıştırdığınızda iyi çalışır.


Bu iyi bir nokta, ancak Alamofire 3'te "manuel" parçanın biraz daha küçük olduğunu düşünüyorum. Yukarıdaki cevaba bakın (aşağıda): stackoverflow.com/a/34961720/8047 ... Teşekkürler
Dan Rosenstark

1

İsteğinizdeki içerik türü eksik olduğu için 415 alıyorsunuz . Aşağıda Swift 2 ve AlamoFire'a resim yüklemek için toplam bir kaynak var

import UIKit
import Alamofire

class ViewController: UIViewController {

@IBOutlet var imageView: UIImageView!
@IBOutlet var btnUpload: UIButton!
override func viewDidLoad() {
    super.viewDidLoad()
}

func successDataHandler(responseData:String){

    print ("IMAGE UPLOAD SUCCESSFUL    !!!")

}

func failureDataHandler(errorData:String){

    print ("  !!!   IMAGE UPLOAD FAILURE   !!! ")

}

@IBAction func actionUpload(sender: AnyObject) {

    let URL = "http://m8coreapibeta.azurewebsites.net/api/cards/SaveImages"

    let postDataProlife:[String:AnyObject] = ["CardId":(dataCardDetail?.userId)!,"ImageType":1,"ImageData":imageView.image!]

    uplaodImageData(URL, postData: postDataProlife, successHandler: successDataHandler, failureHandler: failureDataHandler)
}

func uplaodImageData(RequestURL: String,postData:[String:AnyObject]?,successHandler: (String) -> (),failureHandler: (String) -> ()) -> () {

    let headerData:[String : String] = ["Content-Type":"application/json"]

    Alamofire.request(.POST,RequestURL, parameters: postData, encoding: .URLEncodedInURL, headers: headerData).responseString{ response in
        switch response.result {
        case .Success:
            print(response.response?.statusCode)
            successHandler(response.result.value!)
        case .Failure(let error):
            failureHandler("\(error)")
        }
    }
}
}

0

Aşağıda hızlı ve Php Kodu var

Swift kodu -> Apple Swift sürüm 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1) Hedef: x86_64-apple-macosx10.9

   class  func upload(jsonObject: AnyObject , files : Array<Any>? = nil  , completionHandler :  CompletionBlock? = nil ,failureHandler : FailureBlock? = nil )
{

    Alamofire.upload(multipartFormData:
        { (multipartFormData) in

            if let  filesO = files
            {
                for i in (filesO.enumerated())
                {
                    let image = UIImage(named: "\(i.element)")

                    let data = UIImageJPEGRepresentation(image!, 1)!

                    multipartFormData.append(data, withName: "imgFiles[]" , fileName: "\( NSUUID().uuidString).jpeg" , mimeType: "image/jpeg")
                  // imgFiles[] give array in Php Side
                  // imgFiles   will give string in PHP String


                }

            }


            for  (key, value)  in jsonObject as! [String : String]
            {

                 multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)

            }}          
    },
                     to:baseURL)

Parametreleri ve Dosyayı Almak için PHP Kodu

Burada Parametreler $ _Request'te İşlenir

Ve Dosyalar $ _File içinde işlenir

$ _File verisindeki format (Dizi, Sözlük veya Dize) hızlı taraftaki Talebe bağlıdır, İşte Kodda bu satırı görün

multipartFormData.append (data, withName: "imgFiles []", fileName: "(NSUUID (). uuidString) .jpeg", mimeType: "image / jpeg")

Php tarafında withName: "imgFiles []" isim, format, Type dizisi verir

Örneğin

"ad": ["06748B86-478E-421B-8470-6262755AC149.jpeg", "E70269E9-FB54-4BFD-B807-7E418C81540D.jpeg"], "tür": ["resim / jpeg", "resim / jpeg" ], "tmp_name": ["/ tmp / phpz3UAPq", "/ tmp / phpCAPExG"], "hata": [0,0], "boyut": [2779495,2067259]}

PHP Kodu

 if (isset($_FILES['imgFiles']) and strlen($orderId) > 0) {

        foreach ($_FILES['imgFiles']['tmp_name'] as $key => $tmp_name) {

            $file_name = $key . $_FILES['imgFiles']['name'][$key];
            $file_size = $_FILES['imgFiles']['size'][$key];
            $file_tmp = $_FILES['imgFiles']['tmp_name'][$key];
            $file_type = $_FILES['imgFiles']['type'][$key];
 if (is_dir("$desired_dir/" . $file_name) == false) {
                //move_uploaded_file($file_tmp, "user_data/" . $file_name);
                move_uploaded_file($file_tmp, $desired_dir . "/" .
           $file_name);
            } else {         //rename the file if another one exist
                $new_dir = $desired_dir . "/" . $file_name . time();
                rename($file_tmp, $new_dir);
            }

-2

Antiblank'ın cevabını aldım ve hepsini tamamlama işleyicisiyle 1 fonksiyona sardım. Birisi için yararlı olabileceğini düşündüm. PHP dosyasından (JSON değil) bir dize yanıtı aldığım için, biraz 'daha sert' ve sonra antiblank cevabı.

İşte nasıl adlandırdığınız:

let imageData = UIImagePNGRepresentation(myImageView.image)

uploadImage("http://www.example.com/image_upload.php", imageData: imageData, subdir: "images", filename: "imageID.png")
    { (req, res, str, err) -> Void in
        // do whatever you want to to for error handling and handeling success
    }

İşte fonksiyonun kendisi:

func uploadImage(urlToPHPFile: String, imageData: NSData, subdir: String, filename: String, completionHandler:(request:NSURLRequest, response:NSURLResponse?, responseString:String?, error: NSError?) -> ()) {

    func urlRequestWithComponents(urlString:String, parameters:Dictionary<String, String>, imageData:NSData) -> (URLRequestConvertible, NSData) {
        // create url request to send
        var mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!)
        mutableURLRequest.HTTPMethod = Method.POST.rawValue
        let boundaryConstant = "myRandomBoundary12345";
        let contentType = "multipart/form-data;boundary="+boundaryConstant
        mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")

        // create upload data to send
        let uploadData = NSMutableData()

        // add image
        uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        uploadData.appendData("Content-Disposition: form-data; name=\"file\"; filename=\"file.png\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        uploadData.appendData(imageData)

        // add parameters
        for (key, value) in parameters {
            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 URLRequestConvertible and NSData
        return (ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData)
    }

    let parameters = [
        "subdir" : subdir,
        "filename": filename
    ]
    let urlRequest = urlRequestWithComponents(urlToPHPFile, parameters, imageData)

    AlamoFire.upload(urlRequest.0, urlRequest.1)
        .responseString(completionHandler: { [weak self] (req, res, str, err) -> Void in
            if let strongSelf = self {
                completionHandler(request: req, response: res, responseString: str, error: err)

            }
        }
    )
}

Ve işte php dosyası.

$subdir = $_POST['subdir'];
$filename = $_POST["filename"];

$targetPath = $subdir.'/'.$filename;

$moved = move_uploaded_file($_FILES["file"]["tmp_name"], $targetPath );
if ($moved) {
    echo "OK";
}
else {
    echo "Error: file not uploaded";
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.