{"id":3496,"date":"2021-07-16T14:25:27","date_gmt":"2021-07-16T06:25:27","guid":{"rendered":"http:\/\/123.57.164.21\/?p=3496"},"modified":"2021-07-16T14:25:27","modified_gmt":"2021-07-16T06:25:27","slug":"swift-%e4%bd%bf%e7%94%a8%e5%8e%9f%e7%94%9f%e6%96%b9%e5%bc%8f%e5%90%8c%e6%97%b6%e4%b8%8a%e4%bc%a0%e5%a4%9a%e4%b8%aa%e6%96%87%e4%bb%b6%e5%92%8c%e5%8f%82%e6%95%b0%ef%bc%88form%e8%a1%a8%e5%8d%95","status":"publish","type":"post","link":"https:\/\/92it.top\/?p=3496","title":{"rendered":"Swift &#8211; \u4f7f\u7528\u539f\u751f\u65b9\u5f0f\u540c\u65f6\u4e0a\u4f20\u591a\u4e2a\u6587\u4ef6\u548c\u53c2\u6570\uff08form\u8868\u5355\u63d0\u4ea4\u3001post\u65b9\u5f0f\uff09"},"content":{"rendered":"\n<p>\u672c\u6587\u63a5\u7740\u6f14\u793a\u5728\u4e0d\u501f\u52a9\u7b2c\u4e09\u65b9\u5e93\u7684\u60c5\u51b5\u4e0b\uff0c\u5982\u4f55\u4f7f\u7528\u539f\u751f\u4ee3\u7801\uff08<strong>URLSession<\/strong>\uff09\u6765\u5b9e\u73b0\uff1a\u4e00\u6b21\u6027\u4e0a\u4f20\u591a\u4e2a\u6587\u4ef6\u548c\u591a\u4e2a\u53c2\u6570\u5230\u670d\u52a1\u5668\u3002<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">1\uff0c\u6548\u679c\u56fe<\/h5>\n\n\n\n<p>\uff081\uff09\u70b9\u51fb\u201c<strong>\u5f00\u59cb\u63d0\u4ea4<\/strong>\u201d\u6309\u94ae\u540e\uff0c\u5c06\u4e24\u4e2a\u6587\u4ef6\u3001\u4e24\u4e2a\u53c2\u6570\u540c\u65f6\u53d1\u9001\u5230\u670d\u52a1\u5668\u3002<br>\uff082\uff09\u670d\u52a1\u5668\u63a5\u6536\u5904\u7406\u5b8c\u6bd5\u540e\uff0c\u8fd4\u56de\u76f8\u5e94\u4fe1\u606f\uff0c\u5ba2\u6237\u7aef\u8fd9\u8fb9\u63a5\u6536\u5e76\u6253\u5370\u51fa\u6765\u3002<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/07\/image-69-1024x290.png\" alt=\"\" class=\"wp-image-3497\" width=\"610\" height=\"172\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-69-1024x290.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-69-300x85.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-69-768x218.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-69-830x235.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-69-230x65.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-69-350x99.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-69-480x136.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-69.png 1278w\" sizes=\"(max-width: 610px) 100vw, 610px\" \/><\/figure><\/div>\n\n\n\n<h5 class=\"wp-block-heading\"><br><\/h5>\n\n\n\n<h5 class=\"wp-block-heading\">2\uff0c\u6837\u4f8b\u4ee3\u7801<\/h5>\n\n\n\n<p>\uff081\uff09\u5ba2\u6237\u7aef\u4ee3\u7801\uff08<strong>ViewController.swift<\/strong>\uff09<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import UIKit\nimport MobileCoreServices\n \nclass ViewController: UIViewController {\n     \n    @IBAction func startUpload(_ sender: Any) {\n         \n        \/\/\u5206\u9694\u7ebf\n        let boundary = \"Boundary-\\(UUID().uuidString)\"\n         \n        \/\/\u4f20\u9012\u7684\u53c2\u6570\n        let parameters = [\n            \"value1\": \"hangge.com\",\n            \"value2\": \"1234\"\n        ]\n         \n        \/\/\u4f20\u9012\u7684\u6587\u4ef6\n        let files = [\n            (\n                name: \"file1\",\n                path:Bundle.main.path(forResource: \"1\", ofType: \"jpg\")!\n            ),\n            (\n                name: \"file2\",\n                path:Bundle.main.path(forResource: \"2\", ofType: \"png\")!\n            )\n        ]\n         \n        \/\/\u4e0a\u4f20\u5730\u5740\n        let url = URL(string: \"http:\/\/www.hangge.com\/upload.php\")!\n        var request = URLRequest(url: url)\n        \/\/\u8bf7\u6c42\u7c7b\u578b\u4e3aPOST\n        request.httpMethod = \"POST\"\n        request.setValue(\"multipart\/form-data; boundary=\\(boundary)\",\n            forHTTPHeaderField: \"Content-Type\")\n         \n        \/\/\u521b\u5efa\u8868\u5355body\n        request.httpBody = try! createBody(with: parameters, files: files, boundary: boundary)\n         \n        \/\/\u521b\u5efa\u4e00\u4e2a\u8868\u5355\u4e0a\u4f20\u4efb\u52a1\n        let session = URLSession.shared\n        let uploadTask = session.dataTask(with: request, completionHandler: {\n            (data, response, error) -> Void in\n            \/\/\u4e0a\u4f20\u5b8c\u6bd5\u540e\n            if error != nil{\n                print(error!)\n            }else{\n                let str = String(data: data!, encoding: String.Encoding.utf8)\n                print(\"--- \u4e0a\u4f20\u5b8c\u6bd5 ---\\(str!)\")\n            }\n        })\n         \n        \/\/\u4f7f\u7528resume\u65b9\u6cd5\u542f\u52a8\u4efb\u52a1\n        uploadTask.resume()\n    }\n     \n    \/\/\u521b\u5efa\u8868\u5355body\n    private func createBody(with parameters: [String: String]?,\n                            files: [(name:String, path:String)],\n                            boundary: String) throws -> Data {\n        var body = Data()\n         \n        \/\/\u6dfb\u52a0\u666e\u901a\u53c2\u6570\u6570\u636e\n        if parameters != nil {\n            for (key, value) in parameters! {\n                \/\/ \u6570\u636e\u4e4b\u524d\u8981\u7528 --\u5206\u9694\u7ebf \u6765\u9694\u5f00 \uff0c\u5426\u5219\u540e\u53f0\u4f1a\u89e3\u6790\u5931\u8d25\n                body.append(\"--\\(boundary)\\r\\n\")\n                body.append(\"Content-Disposition: form-data; name=\\\"\\(key)\\\"\\r\\n\\r\\n\")\n                body.append(\"\\(value)\\r\\n\")\n            }\n        }\n         \n        \/\/\u6dfb\u52a0\u6587\u4ef6\u6570\u636e\n        for file in files {\n            let url = URL(fileURLWithPath: file.path)\n            let filename = url.lastPathComponent\n            let data = try Data(contentsOf: url)\n            let mimetype = mimeType(pathExtension: url.pathExtension)\n             \n            \/\/ \u6570\u636e\u4e4b\u524d\u8981\u7528 --\u5206\u9694\u7ebf \u6765\u9694\u5f00 \uff0c\u5426\u5219\u540e\u53f0\u4f1a\u89e3\u6790\u5931\u8d25\n            body.append(\"--\\(boundary)\\r\\n\")\n            body.append(\"Content-Disposition: form-data; \"\n                + \"name=\\\"\\(file.name)\\\"; filename=\\\"\\(filename)\\\"\\r\\n\")\n            body.append(\"Content-Type: \\(mimetype)\\r\\n\\r\\n\") \/\/\u6587\u4ef6\u7c7b\u578b\n            body.append(data) \/\/\u6587\u4ef6\u4e3b\u4f53\n            body.append(\"\\r\\n\") \/\/\u4f7f\u7528\\r\\n\u6765\u8868\u793a\u8fd9\u4e2a\u8fd9\u4e2a\u503c\u7684\u7ed3\u675f\u7b26\n        }\n         \n        \/\/ --\u5206\u9694\u7ebf-- \u4e3a\u6574\u4e2a\u8868\u5355\u7684\u7ed3\u675f\u7b26\n        body.append(\"--\\(boundary)--\\r\\n\")\n        return body\n    }\n     \n    \/\/\u6839\u636e\u540e\u7f00\u83b7\u53d6\u5bf9\u5e94\u7684Mime-Type\n    func mimeType(pathExtension: String) -> String {\n        if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,\n                                                           pathExtension as NSString,\n                                                           nil)?.takeRetainedValue() {\n            if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?\n                .takeRetainedValue() {\n                return mimetype as String\n            }\n        }\n        \/\/\u6587\u4ef6\u8d44\u6e90\u7c7b\u578b\u5982\u679c\u4e0d\u77e5\u9053\uff0c\u4f20\u4e07\u80fd\u7c7b\u578bapplication\/octet-stream\uff0c\u670d\u52a1\u5668\u4f1a\u81ea\u52a8\u89e3\u6790\u6587\u4ef6\u7c7b\n        return \"application\/octet-stream\"\n    }\n}\n \n\/\/\u6269\u5c55Data\nextension Data {\n    \/\/\u589e\u52a0\u76f4\u63a5\u6dfb\u52a0String\u6570\u636e\u7684\u65b9\u6cd5\n    mutating func append(_ string: String, using encoding: String.Encoding = .utf8) {\n        if let data = string.data(using: encoding) {\n            append(data)\n        }\n    }\n}<\/pre>\n\n\n\n<p>\uff082\uff09\u670d\u52a1\u7aef\u4ee3\u7801\uff08<strong>upload.php<\/strong>\uff09<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?\n$value1 = $_POST[\"value1\"];\n$value2 = $_POST[\"value2\"];\n  \nmove_uploaded_file($_FILES[\"file1\"][\"tmp_name\"],\n    $_SERVER[\"DOCUMENT_ROOT\"].\"\/uploadFiles\/\" . $_FILES[\"file1\"][\"name\"]);\n \nmove_uploaded_file($_FILES[\"file2\"][\"tmp_name\"],\n    $_SERVER[\"DOCUMENT_ROOT\"].\"\/uploadFiles\/\" . $_FILES[\"file2\"][\"name\"]);\n \necho \"\\r\\n\u4e24\u4e2a\u53c2\u6570\u4e3a\uff1a\".$value1.\"\uff0c\".$value2;\necho \"\\r\\n\u4e24\u4e2a\u6587\u4ef6\u4e3a\uff1a\". $_FILES[\"file1\"][\"name\"].\"\uff0c\".$_FILES[\"file2\"][\"name\"];\n?><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">\u9644\uff1a\u4e0a\u4f20\u65f6\u9644\u5e26\u4e0a\u4f20\u8fdb\u5ea6<\/h5>\n\n\n\n<p>\uff081\uff09\u5982\u679c\u60f3\u5728\u4e0a\u4f20\u7684\u8fc7\u7a0b\u4e2d\u5b9e\u65f6\u83b7\u53d6\u5f53\u524d\u8fdb\u5ea6\uff0c\u5c31\u4e0d\u80fd\u4f7f\u7528\u5168\u5c40\u7684\u00a0<strong>URLSession.shared\u00a0<\/strong>\u548c\u00a0<strong>dataTask\u00a0<\/strong>\u65b9\u6cd5\uff0c\u800c\u9700\u4f7f\u7528\u81ea\u5b9a\u4e49\u7684\u00a0<strong>URLSession\u00a0<\/strong>\u5bf9\u8c61\u548c\u5e76\u5b9e\u73b0\u76f8\u5173\u7684\u4ee3\u7406\u65b9\u6cd5\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import UIKit\nimport MobileCoreServices\n \nclass ViewController: UIViewController {\n     \n    @IBAction func startUpload(_ sender: Any) {\n         \n        \/\/\u5206\u9694\u7ebf\n        let boundary = \"Boundary-\\(UUID().uuidString)\"\n         \n        \/\/\u4f20\u9012\u7684\u53c2\u6570\n        let parameters = [\n            \"value1\": \"hangge.com\",\n            \"value2\": \"1234\"\n        ]\n         \n        \/\/\u4f20\u9012\u7684\u6587\u4ef6\n        let files = [\n            (\n                name: \"file1\",\n                path:Bundle.main.path(forResource: \"1\", ofType: \"jpg\")!\n            ),\n            (\n                name: \"file2\",\n                path:Bundle.main.path(forResource: \"2\", ofType: \"png\")!\n            )\n        ]\n         \n        \/\/\u4e0a\u4f20\u5730\u5740\n        let url = URL(string: \"http:\/\/www.hangge.com\/upload.php\")!\n        var request = URLRequest(url: url)\n        \/\/\u8bf7\u6c42\u7c7b\u578b\u4e3aPOST\n        request.httpMethod = \"POST\"\n        request.setValue(\"multipart\/form-data; boundary=\\(boundary)\",\n            forHTTPHeaderField: \"Content-Type\")\n         \n        \/\/\u521b\u5efa\u8868\u5355body\n        request.httpBody = try! createBody(with: parameters, files: files, boundary: boundary)\n         \n        \/\/\u521b\u5efa\u4e00\u4e2a\u8868\u5355\u4e0a\u4f20\u4efb\u52a1\n        let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)\n        let uploadTask = session.dataTask(with: request, completionHandler: {\n            (data, response, error) -> Void in\n            \/\/\u4e0a\u4f20\u5b8c\u6bd5\u540e\n            if error != nil{\n                print(error!)\n            }else{\n                let str = String(data: data!, encoding: String.Encoding.utf8)\n                print(\"--- \u4e0a\u4f20\u5b8c\u6bd5 ---\\(str!)\")\n            }\n        })\n         \n        \/\/\u4f7f\u7528resume\u65b9\u6cd5\u542f\u52a8\u4efb\u52a1\n        uploadTask.resume()\n    }\n     \n    \/\/\u521b\u5efa\u8868\u5355body\n    private func createBody(with parameters: [String: String]?,\n                            files: [(name:String, path:String)],\n                            boundary: String) throws -> Data {\n        var body = Data()\n         \n        \/\/\u6dfb\u52a0\u666e\u901a\u53c2\u6570\u6570\u636e\n        if parameters != nil {\n            for (key, value) in parameters! {\n                \/\/ \u6570\u636e\u4e4b\u524d\u8981\u7528 --\u5206\u9694\u7ebf \u6765\u9694\u5f00 \uff0c\u5426\u5219\u540e\u53f0\u4f1a\u89e3\u6790\u5931\u8d25\n                body.append(\"--\\(boundary)\\r\\n\")\n                body.append(\"Content-Disposition: form-data; name=\\\"\\(key)\\\"\\r\\n\\r\\n\")\n                body.append(\"\\(value)\\r\\n\")\n            }\n        }\n         \n        \/\/\u6dfb\u52a0\u6587\u4ef6\u6570\u636e\n        for file in files {\n            let url = URL(fileURLWithPath: file.path)\n            let filename = url.lastPathComponent\n            let data = try Data(contentsOf: url)\n            let mimetype = mimeType(pathExtension: url.pathExtension)\n             \n            \/\/ \u6570\u636e\u4e4b\u524d\u8981\u7528 --\u5206\u9694\u7ebf \u6765\u9694\u5f00 \uff0c\u5426\u5219\u540e\u53f0\u4f1a\u89e3\u6790\u5931\u8d25\n            body.append(\"--\\(boundary)\\r\\n\")\n            body.append(\"Content-Disposition: form-data; \"\n                + \"name=\\\"\\(file.name)\\\"; filename=\\\"\\(filename)\\\"\\r\\n\")\n            body.append(\"Content-Type: \\(mimetype)\\r\\n\\r\\n\") \/\/\u6587\u4ef6\u7c7b\u578b\n            body.append(data) \/\/\u6587\u4ef6\u4e3b\u4f53\n            body.append(\"\\r\\n\") \/\/\u4f7f\u7528\\r\\n\u6765\u8868\u793a\u8fd9\u4e2a\u8fd9\u4e2a\u503c\u7684\u7ed3\u675f\u7b26\n        }\n         \n        \/\/ --\u5206\u9694\u7ebf-- \u4e3a\u6574\u4e2a\u8868\u5355\u7684\u7ed3\u675f\u7b26\n        body.append(\"--\\(boundary)--\\r\\n\")\n        return body\n    }\n     \n    \/\/\u6839\u636e\u540e\u7f00\u83b7\u53d6\u5bf9\u5e94\u7684Mime-Type\n    func mimeType(pathExtension: String) -> String {\n        if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,\n                                                           pathExtension as NSString,\n                                                           nil)?.takeRetainedValue() {\n            if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?\n                .takeRetainedValue() {\n                return mimetype as String\n            }\n        }\n        \/\/\u6587\u4ef6\u8d44\u6e90\u7c7b\u578b\u5982\u679c\u4e0d\u77e5\u9053\uff0c\u4f20\u4e07\u80fd\u7c7b\u578bapplication\/octet-stream\uff0c\u670d\u52a1\u5668\u4f1a\u81ea\u52a8\u89e3\u6790\u6587\u4ef6\u7c7b\n        return \"application\/octet-stream\"\n    }\n}\n \nextension ViewController: URLSessionDelegate, URLSessionTaskDelegate {\n    \/\/\u4e0a\u4f20\u4ee3\u7406\u65b9\u6cd5\uff0c\u76d1\u542c\u4e0a\u4f20\u8fdb\u5ea6\n    func urlSession(_ session: URLSession, task: URLSessionTask,\n                    didSendBodyData bytesSent: Int64, totalBytesSent: Int64,\n                    totalBytesExpectedToSend: Int64) {\n        \/\/\u83b7\u53d6\u8fdb\u5ea6\n        let written = (Float)(totalBytesSent)\n        let total = (Float)(totalBytesExpectedToSend)\n        let pro = written\/total\n        print(\"\u5f53\u524d\u8fdb\u5ea6\uff1a\\(pro)\")\n    }\n}\n \n\/\/\u6269\u5c55Data\nextension Data {\n    \/\/\u589e\u52a0\u76f4\u63a5\u6dfb\u52a0String\u6570\u636e\u7684\u65b9\u6cd5\n    mutating func append(_ string: String, using encoding: String.Encoding = .utf8) {\n        if let data = string.data(using: encoding) {\n            append(data)\n        }\n    }\n}<\/pre>\n\n\n\n<p>\uff082\uff09\u8fd0\u884c\u7ed3\u679c\u5982\u4e0b\uff0c\u53ef\u4ee5\u770b\u5230\u63a7\u5236\u53f0\u4e0d\u65ad\u8f93\u51fa\u5df2\u4e0a\u4f20\u7684\u8fdb\u5ea6\uff08<strong>1<\/strong>\u00a0\u5219\u8868\u793a\u4e0a\u4f20\u5b8c\u6bd5\uff09<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/07\/image-70.png\" alt=\"\" class=\"wp-image-3498\" width=\"404\" height=\"307\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-70.png 602w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-70-300x228.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-70-230x175.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-70-350x266.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/07\/image-70-480x365.png 480w\" sizes=\"(max-width: 404px) 100vw, 404px\" \/><\/figure><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u6587\u63a5\u7740\u6f14\u793a\u5728\u4e0d\u501f\u52a9\u7b2c\u4e09\u65b9\u5e93\u7684\u60c5\u51b5\u4e0b\uff0c\u5982\u4f55\u4f7f\u7528\u539f\u751f\u4ee3\u7801\uff08URLSession\uff09\u6765\u5b9e\u73b0\uff1a\u4e00\u6b21\u6027\u4e0a\u4f20\u591a\u4e2a\u6587\u4ef6\u548c\u591a\u4e2a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,8],"tags":[],"_links":{"self":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/3496"}],"collection":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3496"}],"version-history":[{"count":2,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/3496\/revisions"}],"predecessor-version":[{"id":3500,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/3496\/revisions\/3500"}],"wp:attachment":[{"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}