CommandResponseViewController.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //
  2. // CommandResponseViewController.swift
  3. // LoopKit
  4. //
  5. // Created by Nate Racklyeft on 8/26/16.
  6. // Copyright © 2016 Nathan Racklyeft. All rights reserved.
  7. //
  8. import UIKit
  9. import os.log
  10. public class CommandResponseViewController: UIViewController {
  11. public typealias Command = (_ completionHandler: @escaping (_ responseText: String) -> Void) -> String
  12. public init(command: @escaping Command) {
  13. self.command = command
  14. super.init(nibName: nil, bundle: nil)
  15. }
  16. required public init?(coder aDecoder: NSCoder) {
  17. fatalError("init(coder:) has not been implemented")
  18. }
  19. public var fileName: String?
  20. private let uuid = UUID()
  21. private let command: Command
  22. fileprivate lazy var textView = UITextView()
  23. public override func loadView() {
  24. self.view = textView
  25. }
  26. public override func viewDidLoad() {
  27. super.viewDidLoad()
  28. textView.contentInsetAdjustmentBehavior = .always
  29. let font = UIFont(name: "Menlo-Regular", size: 14)
  30. if let font = font {
  31. let metrics = UIFontMetrics(forTextStyle: .body)
  32. textView.font = metrics.scaledFont(for: font)
  33. } else {
  34. textView.font = font
  35. }
  36. textView.text = command { [weak self] (responseText) -> Void in
  37. var newText = self?.textView.text ?? ""
  38. newText += "\n\n"
  39. newText += responseText
  40. self?.textView.text = newText
  41. }
  42. textView.isEditable = false
  43. navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareText(_:)))
  44. }
  45. @objc func shareText(_: Any?) {
  46. let title = fileName ?? "\(self.title ?? uuid.uuidString).txt"
  47. guard let item = SharedResponse(text: textView.text, title: title) else {
  48. return
  49. }
  50. let activityVC = UIActivityViewController(activityItems: [item], applicationActivities: nil)
  51. present(activityVC, animated: true, completion: nil)
  52. }
  53. }
  54. private class SharedResponse: NSObject, UIActivityItemSource {
  55. let title: String
  56. let fileURL: URL
  57. init?(text: String, title: String) {
  58. self.title = title
  59. var url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
  60. url.appendPathComponent(title, isDirectory: false)
  61. do {
  62. try text.write(to: url, atomically: true, encoding: .utf8)
  63. } catch let error {
  64. os_log("Failed to write to file %{public}@: %{public}@", log: .default, type: .error, title, String(describing: error))
  65. return nil
  66. }
  67. fileURL = url
  68. super.init()
  69. }
  70. public func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
  71. return fileURL
  72. }
  73. public func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
  74. return fileURL
  75. }
  76. public func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String {
  77. return title
  78. }
  79. public func activityViewController(_ activityViewController: UIActivityViewController, dataTypeIdentifierForActivityType activityType: UIActivity.ActivityType?) -> String {
  80. return "public.utf8-plain-text"
  81. }
  82. }