Skip to content

Instantly share code, notes, and snippets.

@robertmryan
Last active February 22, 2019 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertmryan/62dcb3a7c67091d7e2b9aaaea8b55634 to your computer and use it in GitHub Desktop.
Save robertmryan/62dcb3a7c67091d7e2b9aaaea8b55634 to your computer and use it in GitHub Desktop.
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