diff --git a/JSONCreator_iOS/JSONCreator.xcodeproj/project.pbxproj b/JSONCreator_iOS/JSONCreator.xcodeproj/project.pbxproj index 1672500..3d51d03 100644 --- a/JSONCreator_iOS/JSONCreator.xcodeproj/project.pbxproj +++ b/JSONCreator_iOS/JSONCreator.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 58CEAE662C3DE4FB00660E31 /* MoleculeReplacementViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CEAE652C3DE4FB00660E31 /* MoleculeReplacementViewController.swift */; }; D29C557825BF1F340082E7D6 /* JSONCreatorActionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29C557725BF1F340082E7D6 /* JSONCreatorActionHandler.swift */; }; D2B1E3F322F4A68F0065F95C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2B1E3F222F4A68F0065F95C /* AppDelegate.swift */; }; D2B1E3F522F4A68F0065F95C /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2B1E3F422F4A68F0065F95C /* MasterViewController.swift */; }; @@ -69,6 +70,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 58CEAE652C3DE4FB00660E31 /* MoleculeReplacementViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeReplacementViewController.swift; sourceTree = ""; }; D29C557725BF1F340082E7D6 /* JSONCreatorActionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONCreatorActionHandler.swift; sourceTree = ""; }; D2B1E3EF22F4A68F0065F95C /* JSONCreator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JSONCreator.app; sourceTree = BUILT_PRODUCTS_DIR; }; D2B1E3F222F4A68F0065F95C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -148,6 +150,7 @@ D2B1E3F222F4A68F0065F95C /* AppDelegate.swift */, D2B1E3F422F4A68F0065F95C /* MasterViewController.swift */, D2B1E3F622F4A68F0065F95C /* DetailViewController.swift */, + 58CEAE652C3DE4FB00660E31 /* MoleculeReplacementViewController.swift */, D2B1E3F822F4A68F0065F95C /* Main.storyboard */, D2B1E3FB22F4A6930065F95C /* Assets.xcassets */, D2B1E3FD22F4A6930065F95C /* LaunchScreen.storyboard */, @@ -302,6 +305,7 @@ buildActionMask = 2147483647; files = ( D2B1E3F722F4A68F0065F95C /* DetailViewController.swift in Sources */, + 58CEAE662C3DE4FB00660E31 /* MoleculeReplacementViewController.swift in Sources */, D2B1E3F522F4A68F0065F95C /* MasterViewController.swift in Sources */, D2B1E3F322F4A68F0065F95C /* AppDelegate.swift in Sources */, D29C557825BF1F340082E7D6 /* JSONCreatorActionHandler.swift in Sources */, diff --git a/JSONCreator_iOS/JSONCreator/DetailViewController.swift b/JSONCreator_iOS/JSONCreator/DetailViewController.swift index 32dcc84..1066566 100644 --- a/JSONCreator_iOS/JSONCreator/DetailViewController.swift +++ b/JSONCreator_iOS/JSONCreator/DetailViewController.swift @@ -39,6 +39,11 @@ class DetailViewController: UIViewController { textView.autocapitalizationType = .none textView.autocorrectionType = .no + if let data = UserDefaults.standard.data(forKey: "prior"), + let prior = String(data: data, encoding: .utf8) { + textView.text = prior + } + let clearButton = UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(clearButtonPressed)) let shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareButtonPressed)) let buildButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(play)) @@ -54,7 +59,8 @@ class DetailViewController: UIViewController { } @objc func clearButtonPressed() { - textView.text = "" + textView.text = "" + UserDefaults.standard.removeObject(forKey: "prior") } @objc func shareButtonPressed() { @@ -85,6 +91,8 @@ class DetailViewController: UIViewController { let loadObject = MVMCoreLoadObject(pageJSON: page, modulesJSON: moduleMap, requestParameters: nil, dataForPage: nil, delegateObject: nil), viewController.shouldFinishProcessingLoad(loadObject, error: &errorObject) { + UserDefaults.standard.set(data, forKey: "prior") + Task(priority: .userInitiated) { @MainActor in let gr = UILongPressGestureRecognizer(target: self, action: #selector(DetailViewController.close)) viewController.view.addGestureRecognizer(gr) @@ -95,15 +103,16 @@ class DetailViewController: UIViewController { _ = split.view // Force loadView let done = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.close)) + let update = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(self.update)) let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil) split.navigationController?.isToolbarHidden = false - viewController.setToolbarItems([spacer, done], animated: false) + viewController.setToolbarItems([update, spacer, done], animated: false) split.navigationController?.setToolbarItems([spacer, done], animated: false) NavigationHandler.shared().viewControllerToPresentOn = split UIApplication.shared.delegate?.window??.rootViewController = split - await MVMCoreLoadRequestOperation.processJSON(fromServer: jsonObject, loadObject: loadObject) + //await MVMCoreLoadRequestOperation.processJSON(fromServer: jsonObject, loadObject: loadObject) await NavigationHandler.shared().push(viewController: viewController, animated: false) } @@ -117,6 +126,20 @@ class DetailViewController: UIViewController { } } + @objc func update() { + Task { @MainActor in + let moleculeReplacementVC = MoleculeReplacementViewController() + moleculeReplacementVC.replaceCallback = { serverResponse, loadObject in + Task { + await NavigationHandler.shared().popTopViewController() + try? await Task.sleep(nanoseconds: 4000000) + await MVMCoreLoadRequestOperation.processJSON(fromServer: serverResponse, loadObject: loadObject) + } + } + await NavigationHandler.shared().push(viewController: moleculeReplacementVC) + } + } + @objc func close() { guard let splitViewController = (UIApplication.shared.delegate as? AppDelegate)?.splitViewController else { return } NavigationHandler.shared().viewControllerToPresentOn = splitViewController @@ -132,7 +155,7 @@ extension DetailViewController: UITextViewDelegate { do { if let data = textView.text.data(using: .utf8) { let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) - _ = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) + _ = try JSONSerialization.data(withJSONObject: jsonObject, options: [.prettyPrinted, .sortedKeys]) } return true } catch { @@ -150,7 +173,7 @@ extension DetailViewController: UITextViewDelegate { 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 prettyData = try JSONSerialization.data(withJSONObject: jsonObject, options: [.prettyPrinted, .sortedKeys]) let prettyString = String.init(data: prettyData, encoding: .utf8) textView.text = prettyString } diff --git a/JSONCreator_iOS/JSONCreator/MoleculeReplacementViewController.swift b/JSONCreator_iOS/JSONCreator/MoleculeReplacementViewController.swift new file mode 100644 index 0000000..cb86600 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/MoleculeReplacementViewController.swift @@ -0,0 +1,137 @@ +// +// MoleculeReplacementViewController.swift +// JSONCreator +// +// Created by Kyle Hedden on 7/9/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + +import UIKit +import MVMCoreUI + +class MoleculeReplacementViewController: UIViewController { + let textView = UITextView(frame: .zero) + + var replaceCallback: (([AnyHashable : Any], MVMCoreLoadObject)->Void)? + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + guard textView.superview == nil else { + return + } + + modalPresentationStyle = .fullScreen + view.addSubview(textView) + if UIDevice.current.userInterfaceIdiom == .pad { + textView.font = UIFont.systemFont(ofSize: 40) + } else { + textView.font = UIFont.systemFont(ofSize: 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 + textView.delegate = self + textView.smartDashesType = .no + textView.smartQuotesType = .no + textView.smartInsertDeleteType = .no + textView.autocapitalizationType = .none + textView.autocorrectionType = .no + + if let data = UserDefaults.standard.data(forKey: "priorReplace"), + let prior = String(data: data, encoding: .utf8) { + textView.text = prior + } else { + textView.text = """ + { + "ResponseInfo" : { + "code" : "00000", + "type" : "Success" + }, + "ModuleMap": { + + } + } + """ + } + + let clearButton = UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(clearButtonPressed)) + let buildButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(play)) + navigationItem.setRightBarButtonItems([clearButton, buildButton], animated: true) + navigationItem.title = "Trigger Update" + } + + 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) + } + + @objc func clearButtonPressed() { + textView.text = "" + UserDefaults.standard.removeObject(forKey: "priorReplace") + } + + @objc func play() { + do { + if let data = textView.text.data(using: .utf8), + let rawServerResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [AnyHashable: Any], + let modulesJSON = rawServerResponse["ModuleMap"] as? [AnyHashable: Any] { + + UserDefaults.standard.set(data, forKey: "priorReplace") + + let loadObject = MVMCoreLoadObject(pageJSON: nil, modulesJSON: modulesJSON, requestParameters: nil, dataForPage: nil, delegateObject: nil)! + + replaceCallback?(rawServerResponse, loadObject) + } + } catch { + showError(error as NSError) + } + } + + @objc func close() { + Task { @MainActor in + await NavigationHandler.shared().popTopViewController() + } + } +} + +extension MoleculeReplacementViewController: 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, .sortedKeys]) + } + 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, .sortedKeys]) + 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) + } + } +}