如何使用Swift将图像上传到iOS服务器?

时间:2014-10-13 08:24:25

标签: ios swift

它无法工作,如何将图像从iOS Swift应用程序发送到我的PHP服务器?

@IBAction func upload(sender: UIButton) {

    var imageData = UIImageJPEGRepresentation(img.image, 90)
   // println(imageData)
    let url = NSURL(string:"http://www.i35.club.tw/old_tree/test/uplo.php")
    //let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
    //var request = NSMutableURLRequest(URL: url, cachePolicy: cachePolicy, timeoutInterval: 10)
    var request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"

    // set Content-Type in HTTP header
    let boundaryConstant = "----------V2ymHFg03esomerandomstuffhbqgZCaKO6jy";
    let contentType = "multipart/form-data; boundary=" + boundaryConstant
    NSURLProtocol.setProperty(contentType, forKey: "Content-Type", inRequest: request)
    request.HTTPBody = imageData
    // set data
    //var dataString = "adkjlkajfdadf"
    //let requestBodyData = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
    //request.HTTPBody = requestBodyData


    //

    request.addValue(contentType, forHTTPHeaderField: "Content-Type")
    request.addValue("multipart/form-data", forHTTPHeaderField: "Accept")
    //
    // set content length

    //NSURLProtocol.setProperty(requestBodyData.length, forKey: "Content-Length", inRequest: request)

    var response: NSURLResponse? = nil
    var error: NSError? = nil
    let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)

    let results = NSString(data:reply!, encoding:NSUTF8StringEncoding)
    println("API Response: \(results)")
}

//take photo
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {


    var selectedImage : UIImage = image
     img.image = selectedImage
    UIImageWriteToSavedPhotosAlbum(selectedImage, nil, nil, nil)
    self.dismissViewControllerAnimated(true, completion: nil)

}

11 个答案:

答案 0 :(得分:19)

我已经根据用户的选择拍摄了照片,并为swift 2和iOS9编写了代码

    func imageUploadRequest(imageView imageView: UIImageView, uploadUrl: NSURL, param: [String:String]?) {

        //let myUrl = NSURL(string: "http://192.168.1.103/upload.photo/index.php");

        let request = NSMutableURLRequest(URL:uploadUrl);
        request.HTTPMethod = "POST"

        let boundary = generateBoundaryString()

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

        let imageData = UIImageJPEGRepresentation(imageView.image!, 1)

        if(imageData==nil)  { return; }

        request.HTTPBody = createBodyWithParameters(param, filePathKey: "file", imageDataKey: imageData!, boundary: boundary)

        //myActivityIndicator.startAnimating();

        let task =  NSURLSession.sharedSession().dataTaskWithRequest(request,
            completionHandler: {
                (data, response, error) -> Void in
                if let data = data {

                    // You can print out response object
                    print("******* response = \(response)")

                    print(data.length)
                    // you can use data here

                    // Print out reponse body
                    let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
                    print("****** response data = \(responseString!)")

                    let json =  try!NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as? NSDictionary

                    print("json value \(json)")

                    //var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err)

                    dispatch_async(dispatch_get_main_queue(),{
                        //self.myActivityIndicator.stopAnimating()
                        //self.imageView.image = nil;
                    });

                } else if let error = error {
                    print(error.description)
                }
        })
        task.resume()


    }


    func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
        let body = NSMutableData();

        if parameters != nil {
            for (key, value) in parameters! {
                body.appendString("--\(boundary)\r\n")
                body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
                body.appendString("\(value)\r\n")
            }
        }

        let filename = "user-profile.jpg"

        let mimetype = "image/jpg"

        body.appendString("--\(boundary)\r\n")
        body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
        body.appendString("Content-Type: \(mimetype)\r\n\r\n")
        body.appendData(imageDataKey)
        body.appendString("\r\n")

        body.appendString("--\(boundary)--\r\n")

        return body
    }

    func generateBoundaryString() -> String {
        return "Boundary-\(NSUUID().UUIDString)"
    }

}// extension for impage uploading

extension NSMutableData {

    func appendString(string: String) {
        let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
        appendData(data!)
    }
}

---------以下是php端的代码

<?php

$firstName = $_POST["firstName"];
$lastName = $_POST["lastName"];
$userId = $_POST["userId"];

$target_dir = "media";

if(!file_exists($target_dir))
{
mkdir($target_dir, 0777, true);
}

$target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);

if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir)) 
{
echo json_encode([
"Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
"Status" => "OK",
"userId" => $_REQUEST["userId"]
]);

} else {

echo json_encode([
"Message" => "Sorry, there was an error uploading your file.",
"Status" => "Error",
"userId" => $_REQUEST["userId"]
]);

}

答案 1 :(得分:9)

要使用参数上传图像,请使用此代码

 // Your method to upload image with parameters to server.     

func uploadImageOne(){
    var imageData = UIImagePNGRepresentation(imageView.image)

    if imageData != nil{
        var request = NSMutableURLRequest(URL: NSURL(string:"Enter Your URL")!)
        var session = NSURLSession.sharedSession()

        request.HTTPMethod = "POST"

        var boundary = NSString(format: "---------------------------14737809831466499882746641449")
        var contentType = NSString(format: "multipart/form-data; boundary=%@",boundary)
      //  println("Content Type \(contentType)")
        request.addValue(contentType, forHTTPHeaderField: "Content-Type")

        var body = NSMutableData.alloc()

        // Title
         body.appendData(NSString(format: "\r\n--%@\r\n",boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(NSString(format:"Content-Disposition: form-data; name=\"title\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("Hello World".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)

        // Image
        body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"img.jpg\"\\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(imageData)
        body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)



        request.HTTPBody = body


        var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)

        var returnString = NSString(data: returnData!, encoding: NSUTF8StringEncoding)

        println("returnString \(returnString)")

    }


}

答案 2 :(得分:3)

Swift 3

的更新代码
func uploadImage() {
    let url = URL(string: "YOUR SERVER URL");
    let request = NSMutableURLRequest(url: url!);
    request.httpMethod = "POST"
    let boundary = "Boundary-\(NSUUID().uuidString)"
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    var retreivedImage: UIImage? = nil
    //Get image
    do {
        let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
        let readData = try Data(contentsOf: URL(string: "file://\(documentsPath)/myImage")!)
        retreivedImage = UIImage(data: readData)
        addProfilePicView.setImage(retreivedImage, for: .normal)
    }
    catch {
        print("Error while opening image")
        return
    }

    let imageData = UIImageJPEGRepresentation(retreivedImage!, 1)
    if (imageData == nil) {
        print("UIImageJPEGRepresentation return nil")
        return
    }

    let body = NSMutableData()
    body.append(NSString(format: "\r\n--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
    body.append(NSString(format: "Content-Disposition: form-data; name=\"api_token\"\r\n\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
    body.append(NSString(format: (UserDefaults.standard.string(forKey: "api_token")! as NSString)).data(using: String.Encoding.utf8.rawValue)!)
    body.append(NSString(format: "\r\n--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
    body.append(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"testfromios.jpg\"\r\n").data(using: String.Encoding.utf8.rawValue)!)
    body.append(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
    body.append(imageData!)
    body.append(NSString(format: "\r\n--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)

    request.httpBody = body as Data

    let task =  URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
        (data, response, error) -> Void in
        if let data = data {
           // do what you want in success case   
        } else if let error = error {
            print(error.localizedDescription)
        }
    })

    task.resume()
}

您可以从@VinodJoshi回答PHP代码。

答案 3 :(得分:2)

根据Sergey Kargopolov(http://swiftdeveloperblog.com/image-upload-example/)和他的视频(https://youtu.be/HqxeyS961Uk)的博客文章,以下是我的代码,该代码在Swift 5中非常有效。 它将图片上传到php脚本(进一步向下)中指定的目录中,并将根据给定的imgKey命名图片。在我的示例中,它将myImageUploadRequest的imageToUpload上传到目录“ wp-content / Images”。参数字典不是必需的。这很可能会写得更有效,但也许这是某人的开始:)

func myImageUploadRequest(imageToUpload: UIImage, imgKey: String) {

    let myUrl = NSURL(string: "https://yourdomain/uploadPicture.php");
    let request = NSMutableURLRequest(url:myUrl! as URL);
    request.httpMethod = "POST";

    let param = [
        "firstName"  : "name",
        "lastName"    : "name",
        "userId"    : "42"
    ]

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

    let imageData = imageToUpload.jpegData(compressionQuality: 1)
    if imageData == nil  {
        return
    }

    request.httpBody = createBodyWithParameters(parameters: param, filePathKey: "file", imageDataKey: imageData! as NSData, boundary: boundary, imgKey: imgKey) as Data

    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in

            if error != nil {
                print("error=\(error!)")
                return
            }

            //print response
            //print("response = \(response!)")

            // print reponse body
            let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            print("response data = \(responseString!)")

        }

        task.resume()
    }




func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String, imgKey: String) -> NSData {
        let body = NSMutableData();

        if parameters != nil {
            for (key, value) in parameters! {
                body.appendString(string: "--\(boundary)\r\n")
                body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
                body.appendString(string: "\(value)\r\n")
            }
        }

        let filename = "\(imgKey).jpg"
        let mimetype = "image/jpg"

        body.appendString(string: "--\(boundary)\r\n")
        body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
        body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
        body.append(imageDataKey as Data)
        body.appendString(string: "\r\n")
        body.appendString(string: "--\(boundary)--\r\n")

        return body
    }

    func generateBoundaryString() -> String {
        return "Boundary-\(NSUUID().uuidString)"
    }

}

extension NSMutableData {
    func appendString(string: String) {
        let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
        append(data!)
    }
}

服务器端php(PHP / 7.3.18)代码:

<?php

$firstName = $_POST["firstName"];
$lastName = $_POST["lastName"];
$userId = $_POST["userId"];

$target_dir = "wp-content/Images";

if (!file_exists($target_dir)) {
    mkdir($target_dir, 0777, true);
}

$target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);

if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir)) {

    echo json_encode([
    "Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
    "Status" => "OK",
    "userId" => $_REQUEST["userId"]
    ]);

} 
else {

    echo json_encode([
    "Message" => "Sorry, there was an error uploading your file.",
    "Status" => "Error",
    "userId" => $_REQUEST["userId"]
    ]);

}

?>

控制台输出示例:

response data = {
"Message":"The file 9B862D73-9F0B-4DD3-8FBB-452AEF2FE1CF.jpg has been uploaded.",
"Status":"OK",
"userId":"17"}

答案 4 :(得分:1)

我已经为Block方法创建了一个易于使用的函数,这是类函数,因此您可以在项目中的任何位置使用,例如make

MVCServer.swift  

NSObject类和

import Alamofire 

然后在此类中编写此函数

 func postImageRequestWithURL(withUrl strURL: String,withParam postParam: Dictionary<String, Any>,withImages imageArray:NSMutableArray,completion:@escaping (_ isSuccess: Bool, _ response:NSDictionary) -> Void)
{

    Alamofire.upload(multipartFormData: { (MultipartFormData) in

        // Here is your Image Array
        for (imageDic) in imageArray
        {
            let imageDic = imageDic as! NSDictionary

            for (key,valus) in imageDic
            {
                MultipartFormData.append(valus as! Data, withName:key as! String,fileName: "file.jpg", mimeType: "image/jpg")
            }
        }

        // Here is your Post paramaters
        for (key, value) in postParam
        {
            MultipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
        }

    }, usingThreshold: UInt64.init(), to: strURL, method: .post) { (result) in

        switch result {
        case .success(let upload, _, _):

            upload.uploadProgress(closure: { (progress) in
                print("Upload Progress: \(progress.fractionCompleted)")
            })

            upload.responseJSON { response in

                if response.response?.statusCode == 200
                {
                    let json = response.result.value as? NSDictionary

                    completion(true,json!);
                }
                else
                {
                    completion(false,[:]);
                }
            }

        case .failure(let encodingError):
            print(encodingError)

            completion(false,[:]);
        }

    }
}

现在调用此函数

var ImageArray : NSMutableArray!

// Here is your post parameter 
var parameters: [String:Any] = ["user_master_id" : “56”,
                                        "first_name": “Jignesh”,
                                        "last_name" : “Mayani”,
                                        "email": “TestEmail@gmail.com”]
// Here is your image is in DATA formate don’t send as UIImage formate       
let ImageDic = ["profile_image" : imageData!]

// Here you can pass multiple image in array i am passing just one 
ImageArray = NSMutableArray(array: [ImageDic as NSDictionary])

MVCServer().postImageRequestWithURL(withUrl: "write Your URL here", withParam: parameters, withImages: ImageArray) { (isSuccess, response) in
      // Your Will Get Response here   
    }

答案 5 :(得分:0)

试试这个

@IBAction func upload(sender: UIButton) {

    var imageData = UIImageJPEGRepresentation(img.image, 90)
    var url = NSURL(string: "http://www.i35.club.tw/old_tree/test/uplo.php")
            var request = NSMutableURLRequest(URL: url)
            request.HTTPMethod = "POST"
            request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(imageData))

            var response: NSURLResponse? = nil
    var error: NSError? = nil
    let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)

    let results = NSString(data:reply!, encoding:NSUTF8StringEncoding)
    println("API Response: \(results)")
    }       

参考此link

答案 6 :(得分:0)

我建议您查看:https://github.com/sraj/Swift-SRWebClient

适合我的示例功能:

func uploadImage(image:UIImage) {
  let imageData:NSData = UIImageJPEGRepresentation(image, 100)
  SRWebClient.POST("http://www.example.com/upload/")
    .data(imageData, fieldName:"photo", data: ["foo":"bar","baz":"qux"])
    .send({(response:AnyObject!, status:Int) -> Void in
        // process success response
    },failure:{(error:NSError!) -> Void in
        // process failure response
    })
}

您会注意到上面的代码是Swift-SRWebClient Github页面上稍微调整过的代码片段版本。我已将[{1}}替换为NSData.dataWithData,因为前者已被弃用。

另外,不要忘记将UIImageJPEGRepresentation拖到项目文件夹中,否则无效:)

答案 7 :(得分:0)

这很棒,我一直尝试使用REST传输图像一段时间,并且可以将其格式化,并且不断出现超时错误。使用createBodyWithParameters我能够使它工作。

这是代码的Swift 3版本:

func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: UIImage, boundary: String) -> Data {
  var body = Data();

  if parameters != nil {
     for (key, value) in parameters! {
        body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
        body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: String.Encoding.utf8)!)
        body.append("\(value)\r\n".data(using: String.Encoding.utf8)!)
     }
  }

  let filename = "user-profile.jpg"

  let mimetype = "image/jpg"

  body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
  body.append("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n".data(using: String.Encoding.utf8)!)
  body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
  body.append(UIImageJPEGRepresentation(imageDataKey, 1)!)
  //body.appendData(imageDataKey)
  body.append("\r\n".data(using: String.Encoding.utf8)!)

  body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)

  return body
}

答案 8 :(得分:0)

func imageUpload(imageData:String){       
 var request:NSMutableURLRequest!
        let param:String = ""
        request = NSMutableURLRequest(url: URL(string: "www.pickmyoffers.com")!)// use your upload php file link and parameter "example.com/upload.php?image=\(imageData)"

        request.httpMethod = "POST"

        request.httpBody = param.data(using: String.Encoding.utf8)
        let session = URLSession.shared
        let task = session.dataTask(with: request as URLRequest) {data,response,error in
            if error != nil {
                print("error=\(error)")
                return
            }
            let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            print(responseString!)
        }
        task.resume()
}

答案 9 :(得分:-1)

只需看一下简单的解释即可:

  

Form data and multipart uploads with URLRequest

此外,要保持代码最新,您可以在NSMutableData上替换Data。这样您的最终代码将如下所示:

func createHttpBody(parameters: [String: String]? = nil, _ boundary: String, data: Data, mimeType: String, filename: String) -> Data {
    var body = Data()

    let boundaryPrefix = "--\(boundary)\r\n"

    if let parameters = parameters {

        for (key, value) in parameters {
            body.append(boundaryPrefix)
            body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
            body.append("\(value)\r\n")
        }
    }

    body.append(boundaryPrefix)
    body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n")
    body.append("Content-Type: \(mimeType)\r\n\r\n")
    body.append(data)
    body.append("\r\n")
    body.append("--".appending(boundary.appending("--")))

    return body
}

并更新了Data的扩展名以使用append方法:

extension Data {

    mutating func append(_ string: String) {

        if let data = string.data(using: .utf8) {
            append(data)
        }
    }
}

您还可以选中此video tutorial并为该教程选中source code

答案 10 :(得分:-2)

在Swift 4.1和Xcode 9.4.1中

在此博客中查看我的代码,以获取在Swift中将图像上传到服务器

https://markingios.blogspot.com/2018/09/upload-image-to-server-in-swift.html

调用此函数,例如:uploadImage()

<div class="col-3">
  <label class="slider-switch">
    <input type="checkbox" checked (click)="switchClicked($event)">
    <span class="slider-slider round"></span>
  </label>
</div>