// // DetailViewController.swift // JSONCreator // // Created by Scott Pfeil on 8/2/19. // Copyright © 2019 Verizon Wireless. All rights reserved. // import UIKit import MVMCoreUI class DetailViewController: UIViewController { //-------------------------------------------------- // MARK: - Outlets //-------------------------------------------------- let textView = UITextView(frame: .zero) let tableView = UITableView(frame: .zero, style: .plain) //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- var objectifiedJSON: [Any] = [] //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- override func viewDidLoad() { super.viewDidLoad() guard textView.superview == nil else { return } title = "Raw JSON" setupNavigationMenu() setupTextView() // setupTable() } private func setupTable() { tableView.delegate = self tableView.dataSource = self tableView.register(ObjectCell.self, forCellReuseIdentifier: String(describing: ObjectCell.self)) tableView.register(ArrayCell.self, forCellReuseIdentifier: String(describing: ArrayCell.self)) view.addSubview(tableView) tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true view.trailingAnchor.constraint(equalTo: tableView.trailingAnchor).isActive = true view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: tableView.bottomAnchor).isActive = true } private func setupTextView() { textView.textDropDelegate = self textView.delegate = self textView.smartDashesType = .no textView.smartQuotesType = .no textView.smartInsertDeleteType = .no view.addSubview(textView) textView.font = UIFont.systemFont(ofSize: UIDevice.current.userInterfaceIdiom == .pad ? 20 : 14) textView.translatesAutoresizingMaskIntoConstraints = false textView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true view.trailingAnchor.constraint(equalTo: textView.trailingAnchor).isActive = true view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: textView.bottomAnchor).isActive = true } private func setupNavigationMenu() { let shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareButtonPressed)) let buildButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(play)) let clearButton = UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(clearTextView)) let objectViewButton = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: #selector(objectView)) let refreshButton = UIBarButtonItem(barButtonSystemItem: .refresh, target: self, action: #selector(refreshJSON)) navigationItem.setLeftBarButtonItems([clearButton, objectViewButton], animated: true) navigationItem.setRightBarButtonItems([buildButton, shareButton, refreshButton], animated: true) } //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- func showError(_ error: NSError) { let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil)) present(alert, animated: true, completion: nil) } //-------------------------------------------------- // MARK: - Actions //-------------------------------------------------- @objc func shareButtonPressed() { if let text = textView.text { let activityController = UIActivityViewController(activityItems: [text], applicationActivities: nil) activityController.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem present(activityController, animated: true, completion: nil) } } @objc func clearTextView() { textView.text = "" } @objc func play() { // TODO: If toggle is on, save JSON to userdefaults. If off, clear do { if let data = textView.text.data(using: .utf8), let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [AnyHashable: Any] { let page = jsonObject.optionalDictionaryForKey(KeyPage) let pageType = page?.optionalStringForKey(KeyPageType) let template = page?.optionalStringForKey("template") var errorObject = MVMCoreErrorObject(title: nil, message: "No Template Found", code: ErrorCode.initViewController.rawValue, domain: ErrorDomainNative, location: nil) if let viewController = MVMCoreUIViewControllerMappingObject.shared()?.createMFViewController(ofTemplate: template, pageType: pageType), let loadObject = MVMCoreLoadObject(pageJSON: page, modulesJSON: nil, requestParameters: nil, dataForPage: nil, delegateObject: nil), viewController.shouldFinishProcessingLoad(loadObject, error: &errorObject!) { let navigation = UINavigationController(rootViewController: viewController) viewController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(close)) MVMCoreNavigationHandler.shared()?.present(navigation, animated: true) } else if let errorObject = errorObject { let error = NSError(domain: ErrorDomainNative, code: ErrorCode.initViewController.rawValue, userInfo: [NSLocalizedDescriptionKey: errorObject.messageToDisplay!]) showError(error) } } } catch { showError(error as NSError) } } @objc func close() { MVMCoreNavigationHandler.shared()?.dismissTopViewController(animated: true) } @objc func objectView() { } @objc func refreshJSON() { } } // MARK:- TextView Delegate extension DetailViewController: UITextViewDelegate { func textViewShouldEndEditing(_ textView: UITextView) -> Bool { guard textView.text.count > 0 else { return true } do { if let data = textView.text.data(using: .utf8) { let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) _ = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) } return true } catch { let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil)) present(alert, animated: true, completion: nil) return false } } func textViewDidEndEditing(_ textView: UITextView) { guard textView.text.count > 0 else { return } do { if let data = textView.text.data(using: .utf8) { let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) let prettyData = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) let prettyString = String.init(data: prettyData, encoding: .utf8) textView.text = prettyString } } catch { let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil)) present(alert, animated: true, completion: nil) } } } extension DetailViewController: UITextDropDelegate { func textDroppableView(_ textDroppableView: UIView & UITextDroppable, willPerformDrop drop: UITextDropRequest) { // Nothing for now.... } } extension DetailViewController: UITableViewDelegate, UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 0 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return objectifiedJSON.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return UITableViewCell() } }