import UIKit import CoreData import WebKit import CoreServices extension Data { /// Append string to Data /// /// Rather than littering my code with calls to `data(using: .utf8)` to convert `String` values to `Data`, this wraps it in a nice convenient little extension to Data. This defaults to converting using UTF-8. /// /// - parameter string: The string to be added to the `Data`. mutating func append(_ string: String, using encoding: String.Encoding = .utf8) { if let data = string.data(using: encoding) { append(data) } } } class ReverseImageViewController: UIViewController { var post: Post? @IBOutlet weak var webView: WKWebView! let documentsPath : URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteURL private func mimeType(for path: String) -> String { let url = URL(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" } private func createBody(with parameters: [String: String]?, filePathKey: String, paths: [String], boundary: String) throws -> Data { var body = Data() if parameters != nil { for (key, value) in parameters! { body.append("--\(boundary)\r\n") body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n") body.append("\(value)\r\n") } } for path in paths { let url = URL(fileURLWithPath: path) let filename = url.lastPathComponent let data = try Data(contentsOf: url) let mimetype = mimeType(for: path) body.append("--\(boundary)\r\n") body.append("Content-Disposition: form-data; name=\"\(filePathKey)\"; filename=\"\(filename)\"\r\n") body.append("Content-Type: \(mimetype)\r\n\r\n") body.append(data) body.append("\r\n") } body.append("--\(boundary)--\r\n") return body } private func generateBoundaryString() -> String { return "Boundary-\(UUID().uuidString)" } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) var components = URLComponents(string: "https://iqdb.org") components?.queryItems = [URLQueryItem(name: "url", value: "true")] if let result = components?.url { let boundary = generateBoundaryString() var request = URLRequest(url: result) request.httpMethod = "POST" request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") let imagePath = documentsPath.appendingPathComponent(post!.value(forKey: "name") as! String).path do { request.httpBody = try createBody(with: nil, filePathKey: "file", paths: [imagePath], boundary: boundary) } catch let error as NSError { print(error) } webView!.load(request) } } @IBAction func cancelAction(_ sender: Any) { dismiss(animated: true, completion: nil) } } extension ReverseImageViewController { static func loadFromStoryboard(post: Post) -> ReverseImageViewController? { let storyboard = UIStoryboard(name: "Main", bundle: .main) let viewController = storyboard.instantiateViewController(withIdentifier: "ReverseImageViewController") as? ReverseImageViewController viewController!.post = post return viewController } }