Last active
February 22, 2019 17:54
-
-
Save robertmryan/62dcb3a7c67091d7e2b9aaaea8b55634 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import MobileCoreServices | |
class ViewController: UIViewController { | |
let networkManager = NetworkManager() | |
@IBAction func didTapButton(_ sender: Any) { | |
let controller = UIImagePickerController() | |
controller.mediaTypes = [kUTTypeMovie as String] | |
controller.sourceType = .photoLibrary | |
controller.delegate = self | |
present(controller, animated: true) | |
} | |
} | |
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { | |
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { | |
networkManager.uploadFile(info[.mediaURL] as! URL) | |
picker.dismiss(animated: true) | |
} | |
} | |
class NetworkManager { | |
let uploadURL = URL(string: "...")! | |
let username = "..." | |
let password = "..." | |
@discardableResult | |
func uploadFile(_ fileURL: URL) -> URLSessionUploadTask { | |
let filename = fileURL.lastPathComponent | |
let tempFile = temporaryFile(for: filename) | |
do { | |
try FileManager.default.copyItem(at: fileURL, to: tempFile) | |
} catch { | |
print("unable to copy file", error) | |
return | |
} | |
let request = uploadRequest(for: filename) | |
let task = URLSession.shared.uploadTask(with: request, fromFile: tempFile) { data, response, error in | |
defer { try? FileManager.default.removeItem(at: tempFile) } | |
guard let data = data, | |
let httpResponse = response as? HTTPURLResponse, | |
(200 ... 299) ~= httpResponse.statusCode, | |
error == nil else { | |
print(error ?? "unknown error") | |
print(response ?? "no response") | |
return | |
} | |
if let json = try? JSONSerialization.jsonObject(with: data) { | |
print(json) | |
} else { | |
print(String(data: data, encoding: .utf8) ?? data as NSData) | |
} | |
} | |
task.resume() | |
return task | |
} | |
} | |
private extension NetworkManager { | |
func temporaryFile(for filename: String) -> URL { | |
return URL(fileURLWithPath: NSTemporaryDirectory()) | |
.appendingPathComponent(UUID().uuidString + "." + filename) | |
} | |
func uploadRequest(for filename: String) -> URLRequest { | |
var components = URLComponents(string: uploadURL.absoluteString)! | |
components.queryItems = [URLQueryItem(name: "filename", value: filename)] | |
var request = URLRequest(url: components.url!) | |
request.httpMethod = "POST" | |
request.setValue(mimeType(for: filename), forHTTPHeaderField: "Content-Type") | |
request.updateBasicAuth(for: username, password: password) // this is my own routine for setting `Authorization` header; configure your request however appropriate for your server | |
return request | |
} | |
/// Determine mime type on the basis of extension of a file. | |
/// | |
/// This requires `import MobileCoreServices`. | |
/// | |
/// - 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. | |
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" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment