Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

uploading an image using multipart/form-data in Swift

I am new in programming, I have intermediate skill in Swift and PHP. I am trying to build an iOS app using PHP as backend server.

I have very basic experience in web development. to upload an image by using html and PHP, as far as I remember i just used enctype= multipart/form-data as the atribute in the 'form' of HTML.

but when making the same user interface in iOS app, it seems very complicated. when making a function to upload an image to my server, i try to follow a tutorial in here https://www.youtube.com/watch?v=8GH0yMPvQFU.

He said that, it will be easier to understand the code in swift if I have basic understanding in web development. i feel bad that i can only copy and paste that code, and I don't really grasp the concept so i really want to understand. here is the code to upload an image in swift, especially these line of codes.

  func myImageUploadRequest()
        {

            let myUrl = NSURL(string: "http://www.swiftdeveloperblog.com/http-post-example-script/");
            //let myUrl = NSURL(string: "http://www.boredwear.com/utils/postImage.php");

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

            let param = [
                "firstName"  : "Sergey",
                "lastName"    : "Kargopolov",
                "userId"    : "9"
            ]

            let boundary = generateBoundaryString()

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


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

            if(imageData==nil)  { return; }

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


            myActivityIndicator.startAnimating();

            let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
                data, response, error in

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

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

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

                do {
                    let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary

                    print(json)

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

                }catch
                {
                    print(error)
                }

            }

            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
        }

it seems like constructing request body with parameter and modify the header but.... I don't know, it seems different with the basic I have.

I have tried to read about HTTP protocol, and multipart/form-data. but i still don't get it. like I said before, I usually just used enctype= multipart/form-data as the atribute in the 'form' of HTML.

but those codes contains Content-Disposition: form-data, boundary, MIME type

if i want to fully understand those line of codes, what kind of topic that i have to learn first ? I have tried to find in google, but I don't get the step by step topic about it.

Thanks in advance :)