Мне нужно организовать рабочее приложение в 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)
}
}