将庞大的单个ViewController组织到MVC中

时间:2019-07-09 02:51:34

标签: swift xcode model-view-controller

我需要将一个可运行的应用程序组织到MVC中进行分配。不幸的是,它在一个庞大的ViewController上包含了很多丑陋的代码,我什至不知道从哪里开始,所以任何指针都将不胜感激。这是一个简单的API搜寻器,只需将信息吐回到表视图中即可。

我应该在哪里分割这段代码的不同部分,以及如何将它们链接在一起成为MVC模型?

import UIKit

class ViewController: UIViewController {


  var startingURL = "https://anapioficeandfire.com/api"
  var jsonDictionary = [String: Any]()
  var jsonArray = [Any]()



  enum DataType {
    case url(value: String)
    case dictionary
    case array(value: [Any])
    case string(value: String)
    case number
    case boolean
    case null

    static func getDataType(for input: Any) -> DataType {
      switch input {
      case is [String: Any]:
        return .dictionary
      case is [Any]:
        return .array(value: input as! [Any])
      case is String:
        let stringValue = input as! String
        return !stringValue.contains("http")
          ? .string(value: stringValue)
          : .url(value: stringValue)
      case is NSNumber:
        return .number
      case is Bool:
        return .boolean
      case is NSNull:
        return .null
      default:
        fatalError("Crashing just because reasons")
      }
    }
  }

  @IBOutlet weak var crawlerTableView: UITableView!

  override func viewDidLoad() {
    super.viewDidLoad()
    crawlerTableView.dataSource = self
    crawlerTableView.delegate = self
    crawlerTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    guard let url = URL(string: startingURL) else { return }
    URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
      guard let data = data else { return }
      let jsonObject = try! JSONSerialization.jsonObject(with: data, options: [])
      if let jsonDictionary = jsonObject as? [String: Any] {
        self?.jsonDictionary = jsonDictionary
      } else if let jsonArray = jsonObject as? [Any] {
        self?.jsonArray = jsonArray
      }
      DispatchQueue.main.async {
        self?.crawlerTableView.reloadData()
      }
    }.resume()
  }
}

extension ViewController: UITableViewDataSource {
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if !jsonDictionary.isEmpty {
      return jsonDictionary.count
    } else if !jsonArray.isEmpty {
      return jsonArray.count
    } else {
      return 0
    }
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
    if !jsonDictionary.isEmpty {
      let keys = Array(jsonDictionary.keys)
      let values = Array(jsonDictionary.values)
      let selectedValue = values[indexPath.row]
      let dataType = DataType.getDataType(for: selectedValue)

      cell.textLabel?.text = keys[indexPath.row]

      let detailString: String
      switch dataType {
      case .array(let arrayValue):
        let numberOfItems = (selectedValue as? [Any])?.count ?? 0
        detailString = "Number of elements: \(numberOfItems)"
      case .dictionary:
        let numberOfKeys = (selectedValue as? [String: Any])?.count ?? 0
        detailString = "Number of entries: \(numberOfKeys)"
      case .null:
        detailString = "NULL"
      case .number, .boolean:
        detailString = "\(selectedValue)"
      case .string, .url:
        detailString = (selectedValue as? String) ?? ""
      }
      cell.detailTextLabel?.text = detailString.isEmpty
        ? "Empty String"
        : detailString
    } else if !jsonArray.isEmpty {
      let selectedValue = jsonArray[indexPath.row]
      let dataType = DataType.getDataType(for: selectedValue)
      switch dataType {
      case .array:
        cell.textLabel?.text = "Index: \(indexPath.row)"
      case .dictionary:
        cell.textLabel?.text = "Entry: \(indexPath.row)"
      case .string, .null, .number, .boolean, .url:
        let textString = (selectedValue as? String) ?? ""
        cell.textLabel?.text = textString.isEmpty
          ? "Empty String"
          : textString
      }
      cell.detailTextLabel?.text = (selectedValue as? String) ?? ""
    } else {
      cell.textLabel?.text = "How did you get here???!!!"
    }
    return cell
  }
}

extension ViewController: UITableViewDelegate {
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let nextViewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
    if !jsonDictionary.isEmpty {
      let values = Array(jsonDictionary.values)
      let selectedValue = values[indexPath.row]
      let dataType = DataType.getDataType(for: selectedValue)
      switch dataType {
      case .array:
        nextViewController.startingURL = ""
        nextViewController.jsonArray = (selectedValue as? [Any]) ?? []
      case .dictionary:
        nextViewController.startingURL = ""
        nextViewController.jsonDictionary = (selectedValue as? [String: Any]) ?? [:]
      case .string, .number, .null, .boolean:
        return
      case .url:
        nextViewController.startingURL = (selectedValue as? String) ?? ""
      }
    } else if !jsonArray.isEmpty {
      nextViewController.startingURL = ""
      let selectedValue = jsonArray[indexPath.row]
      let dataType = DataType.getDataType(for: selectedValue)
      switch dataType {
      case .array:
        nextViewController.jsonArray = (selectedValue as? [Any]) ?? []
      case .boolean, .null, .string, .number:
        return
      case .dictionary:
        nextViewController.jsonDictionary = (selectedValue as? [String: Any]) ?? [:]
      case .url:
        nextViewController.startingURL = (jsonArray[indexPath.row] as? String) ?? ""
      }
    } else {

    }
    navigationController?
      .pushViewController(nextViewController,
                          animated: true)
  }
}

0 个答案:

没有答案