全路径为:F:\下载\儿童网站\儿童\ImgUpload\1_13012.jpg

ios - Upload image with parameters in Swift - Stack Overflow
to customize your list.
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
J it only takes a minute:
Join the Stack Overflow community to:
Ask programming questions
Answer and help your peers
Get recognized for your expertise
I'm trying to upload an image with parameters in Swift. When I try this code, I can get the parameters but not the image
uploadFileToUrl(foti?o:UIImage){
var foto =
UIImage(data: UIImageJPEGRepresentation(foti?o, 0.2))
var request = NSMutableURLRequest(URL:NSURL(string: "URL"))
request.HTTPMethod = "POST"
var bodyData = "id_user="PARAMETERS&ETC""
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(foto))
println("miraqui \(request.debugDescription)")
var response: AutoreleasingUnsafeMutablePointer&NSURLResponse?&=nil
var HTTPError: NSError? = nil
var JSONError: NSError? = nil
var dataVal: NSData? =
NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: &HTTPError)
if ((dataVal != nil) && (HTTPError == nil)) {
var jsonResult = NSJSONSerialization.JSONObjectWithData(dataVal!, options: NSJSONReadingOptions.MutableContainers, error: &JSONError)
if (JSONError != nil) {
println("Bad JSON")
println("Synchronous\(jsonResult)")
} else if (HTTPError != nil) {
println("Request failed")
println("No Data returned")
I think that I have some problems with the path of the saved UIImage, because php tells me that the file already exist, which I think is because I send it in blank
func createRequest (#userid: String, disco: String, id_disco: String, pub: String, foto: UIImage) -& NSURLRequest {
let param = [
"name_discoteca"
"id_discoteca" : id_disco,
"ispublic" : pub] // build your dictionary however appropriate
let boundary = generateBoundaryString()
let url = NSURL(string: "http....")
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.timeoutInterval = 60
request.HTTPShouldHandleCookies = false
request.setValue("multipart/form- boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var imagesaver = ImageSaver()
var image = foto
// However you create/get a UIImage
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let destinationPath = documentsPath.stringByAppendingPathComponent("VipKing.jpg")
UIImageJPEGRepresentation(image,1.0).writeToFile(destinationPath, atomically: true)
self.saveImage(foto, withFileName: "asdasd22.jpg")
var path = self.documentsPathForFileName("asdasd22.jpg")
self.ViewImage.image = self.loadImageWithFileName("asdasd22.jpg")
let path1 = NSBundle.mainBundle().pathForResource("asdasd22", ofType: "jpg", inDirectory: path) as String!
**//path1 always crash**
println(param.debugDescription)
println(path.debugDescription)
println(boundary.debugDescription)
request.HTTPBody = createBodyWithParameters(param, filePathKey: "asdasd22.jpg", paths: [path], boundary: boundary)
println(request.debugDescription)
return request
11.7k102963
In your comment below, you inform us that you are using the $_FILES syntax to retrieve the files. That means that you want to create a multipart/form-data request. The process is basically:
Specify a boundary for your multipart/form-data request.
Specify a Content-Type of the request that specifies that it multipart/form-data and what the boundary is.
Create body of request, separating the individual components (each of the posted values as well as between each upload).
For more detail, see . Anyway, this might look like:
/// Create request
/// - parameter userid:
The userid to be passed to web service
/// - parameter password: The password to be passed to web service
/// - parameter email:
The email address to be passed to web service
/// - returns:
The NSURLRequest that was created
func createRequest (userid userid: String, password: String, email: String) -& NSURLRequest {
let param = [
"password" : password]
// build your dictionary however appropriate
let boundary = generateBoundaryString()
let url = NSURL(string: "/imageupload.php")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("multipart/form- boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let path1 = NSBundle.mainBundle().pathForResource("image1", ofType: "png") as String!
request.HTTPBody = createBodyWithParameters(param, filePathKey: "file", paths: [path1], boundary: boundary)
return request
/// Create body of the multipart/form-data request
/// - parameter parameters:
The optional dictionary containing keys and values to be passed to web service
/// - parameter filePathKey:
The optional field name to be used when uploading files. If you supply paths, you must supply filePathKey, too.
/// - parameter paths:
The optional array of file paths of the files to be uploaded
/// - parameter boundary:
The multipart/form-data boundary
/// - returns:
The NSData of the body of the request
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, paths: [String]?, boundary: String) -& NSData {
let body = NSMutableData()
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form- name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
if paths != nil {
for path in paths! {
let url = NSURL(fileURLWithPath: path)
let filename = url.lastPathComponent
let data = NSData(contentsOfURL: url)!
let mimetype = mimeTypeForPath(path)
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form- name=\"\(filePathKey!)\"; filename=\"\(filename!)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.appendData(data)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body
/// Create boundary string for multipart/form-data request
/// - returns:
The boundary string that consists of "Boundary-" followed by a UUID string.
func generateBoundaryString() -& String {
return "Boundary-\(NSUUID().UUIDString)"
/// Determine mime type on the basis of extension of a file.
/// This requires MobileCoreServices framework.
/// - parameter path:
The path of the file for which we are going to determine the mime type.
/// - returns:
Returns the mime type if successful. Returns application/octet-stream if unable to determine mime type.
func mimeTypeForPath(path: String) -& String {
let url = NSURL(fileURLWithPath: path)
let pathExtension = url.pathExtension
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension! as NSString, nil)?.takeRetainedValue() {
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
return mimetype as String
return "application/octet-stream";
This also uses a little NSMutableData extension:
extension NSMutableData {
/// Append string to NSMutableData
/// Rather than littering my code with calls to `dataUsingEncoding` to convert strings to NSData, and then add that data to the NSMutableData, this wraps it in a nice convenient little extension to NSMutableData. This converts using UTF-8.
/// - parameter string:
The string to be added to the `NSMutableData`.
func appendString(string: String) {
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
appendData(data!)
Having all of this, you now need to submit this request. I would advise against using the synchronous technique in your question. You should do this asynchronously. For example, in NSURLSession, you would do something like:
let request = createRequest(userid: userid, password: password, email: email)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
if error != nil {
// handle error here
print(error)
// if response was JSON, then parse it
if let responseDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("success == \(responseDictionary)")
// note, if you want to update the UI, make sure to dispatch that to the main queue, e.g.:
// dispatch_async(dispatch_get_main_queue()) {
// update your UI and model objects here
print(error)
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
task.resume()
My original answer is below for historical purposes:
A couple of observations:
You are setting HTTPBody to be the standard POST format (as if it was a application/x-www-form-urlencoded request, even though you never specified that). You then proceed to discard that and replace it with the binary data of the PNG representation of the image. You presumably wanted to send both.
We cannot advise you with clarification regarding precisely what the server is expecting, but frequently it's multipart/form-data, rather than application/x-www-form-urlencoded (e.g., if it's a PHP web service, it's using $_FILES variable). If you are trying to do multipart/form-data, see this, , for example of how to do that. Clearly that's Objective-C, but it illustrates the basic technique.
Note, there are other formats that other web services use, so I hesitate to just assume that this is expecting multipart/form-data request. You should confirm precisely what the server is expecting.
Needless to say, there are other issues, too (e.g. you really should specify the Content-Type of the request, you really shouldn't be issuing synchronous request (unless you're already doing this in a background thread); I'd probably advise NSURLSession; etc.).
But the main issue is how you're populating HTTPBody. It's hard for us to help you further without greater clarity regarding what the server requires, though.
166k20293393
AlamoFire now supports Multipart:
Here's a blog post with sample project that touches on using Multipart with AlamoFire.
The relevant code might look something like this (assuming you're using AlamoFire and SwiftyJSON):
func createMultipart(image: UIImage, callback: Bool -& Void){
// use SwiftyJSON to convert a dictionary to JSON
var parameterJSON = JSON([
"id_user": "test"
// JSON stringify
let parameterString = parameterJSON.rawString(encoding: NSUTF8StringEncoding, options: nil)
let jsonParameterData = parameterString!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
// convert image to binary
let imageData = UIImageJPEGRepresentation(image, 0.7)
// upload is part of AlamoFire
URLString: "http://httpbin.org/post",
multipartFormData: { multipartFormData in
// fileData: puts it in "files"
multipartFormData.appendBodyPart(fileData: jsonParameterData!, name: "goesIntoFile", fileName: "json.txt", mimeType: "application/json")
multipartFormData.appendBodyPart(fileData: imageData, name: "file", fileName: "iosFile.jpg", mimeType: "image/jpg")
// data: puts it in "form"
multipartFormData.appendBodyPart(data: jsonParameterData!, name: "goesIntoForm")
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, data, error in
let json = JSON(data!)
println("json:: \(json)")
callback(true)
case .Failure(let encodingError):
callback(false)
let fotoImage = UIImage(named: "foto")
createMultipart(fotoImage!, callback: { success in
if success { }
Thank you @Rob, your code is working fine, but in my case, I am retriving image from gallary and taking name of the image by using code:
let filename = url.lastPathComponent
But this code, displaying image extension as .JPG (in capital letter), but server not accepting extensions in captital letter, so i changed my code as:
let filename =
(path.lastPathComponent as NSString).lowercaseString
and now my code is working fine.
Thank you :)
2,51332139
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabled

我要回帖

更多关于 1=F 的文章

 

随机推荐