Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
273 views
in Technique[技术] by (71.8m points)

Upload image with multipart form-data iOS in Swift

i am having a problem with uploading image with multipart-form

here is my code i used from this answer

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

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

    var body = NSMutableData()

    if self.img.image != nil {
        var imageData = UIImagePNGRepresentation(self.img.image)

        if imageData != nil {
            body.appendString("--(boundary)
")
            body.appendString("Content-Disposition: form-data; name="image"; filename="image.png"
")
            body.appendString("Content-Type: image/png

")
            body.appendData(imageData!)
            body.appendString("
")
        }

    }

    body.appendString("--(boundary)--
")
    request.setValue("(body.length)", forHTTPHeaderField:"Content-Length")
    request.HTTPBody = body

then i use NSURLSession to apply the request

the server says that i didn't choose image to upload i only want to upload the image for now

do i have to use paths of images to upload any image or it's data is enough?

do i miss any thing , any help to understand this ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

My version that 100% works. Maybe it will help you.

let url = "http://server/upload"
let img = UIImage(contentsOfFile: fullPath)
let data: NSData = UIImageJPEGRepresentation(img, 1)

sendFile(url, 
    fileName:"one.jpg", 
    data:data, 
    completionHandler: completionHandler:{
        (result:Bool, isNoInternetConnection:Bool) -> Void in

            // ...     
            NSLog("Complete: (result)")
    }
)


func sendFile(
    urlPath:String,
    fileName:String,
    data:NSData,
    completionHandler: (NSURLResponse!, NSData!, NSError!) -> Void){
        
        var url: NSURL = NSURL(string: urlPath)!
        var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
        
        request1.HTTPMethod = "POST"
        
        let boundary = generateBoundary()
        let fullData = photoDataToFormData(data,boundary:boundary,fileName:fileName)
        
        request1.setValue("multipart/form-data; boundary=" + boundary,
            forHTTPHeaderField: "Content-Type")
        
        // REQUIRED!
        request1.setValue(String(fullData.length), forHTTPHeaderField: "Content-Length")
        
        request1.HTTPBody = fullData
        request1.HTTPShouldHandleCookies = false
        
        let queue:NSOperationQueue = NSOperationQueue()
        
        NSURLConnection.sendAsynchronousRequest(
            request1,
            queue: queue,
            completionHandler:completionHandler)
}

// this is a very verbose version of that function
// you can shorten it, but i left it as-is for clarity
// and as an example
func photoDataToFormData(data:NSData,boundary:String,fileName:String) -> NSData {
    var fullData = NSMutableData()
    
    // 1 - Boundary should start with --
    let lineOne = "--" + boundary + "
"
    fullData.appendData(lineOne.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)
    
    // 2
    let lineTwo = "Content-Disposition: form-data; name="image"; filename="" + fileName + ""
"
    NSLog(lineTwo)
    fullData.appendData(lineTwo.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)
    
    // 3
    let lineThree = "Content-Type: image/jpeg

"
    fullData.appendData(lineThree.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)
    
    // 4
    fullData.appendData(data)
    
    // 5
    let lineFive = "
"
    fullData.appendData(lineFive.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)
    
    // 6 - The end. Notice -- at the start and at the end
    let lineSix = "--" + boundary + "--
"
    fullData.appendData(lineSix.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)
    
    return fullData
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...