From 7675afd01571c7188f246ce560d4f88bc0f17fd9 Mon Sep 17 00:00:00 2001 From: Pouya Yarandi <30620887+pouyayarandi@users.noreply.github.com> Date: Sat, 11 Jun 2022 16:29:01 +0430 Subject: [PATCH] Custom body export (#17) * Add customization for body export * Set delegate for vc * Add delegate to shared instance * Add method for request body export Co-authored-by: Pouya Yarandi --- Sources/NetShears/NetShears.swift | 14 ++++++++++- .../UI/BodyDetailViewController.swift | 4 ++- .../UI/RequestDetailViewController.swift | 20 ++++++++++++--- .../UI/RequestListViewController.swift | 4 ++- Sources/NetShears/Utils/NSHelper.swift | 14 +++++------ Sources/NetShears/Utils/RequestExporter.swift | 25 +++++++++++++------ 6 files changed, 59 insertions(+), 22 deletions(-) diff --git a/Sources/NetShears/NetShears.swift b/Sources/NetShears/NetShears.swift index d6c6c14..95efda7 100644 --- a/Sources/NetShears/NetShears.swift +++ b/Sources/NetShears/NetShears.swift @@ -7,9 +7,20 @@ import UIKit +public protocol BodyExporterDelegate: AnyObject { + func netShears(exportResponseBodyFor request: NetShearsRequestModel) -> BodyExportType + func netShears(exportRequestBodyFor request: NetShearsRequestModel) -> BodyExportType +} + +public extension BodyExporterDelegate { + func netShears(exportResponseBodyFor request: NetShearsRequestModel) -> BodyExportType { .default } + func netShears(exportRequestBodyFor request: NetShearsRequestModel) -> BodyExportType { .default } +} + public final class NetShears: NSObject { public static let shared = NetShears() + public weak var bodyExportDelegate: BodyExporterDelegate? internal var loggerEnable = false internal var interceptorEnable = false internal var listenerEnable = false @@ -69,10 +80,11 @@ public final class NetShears: NSObject { return config.removeModifier(at: index) } - public func presentNetworkMonitor(){ + public func presentNetworkMonitor() { let storyboard = UIStoryboard.NetShearsStoryBoard if let initialVC = storyboard.instantiateInitialViewController(){ initialVC.modalPresentationStyle = .fullScreen + ((initialVC as? UINavigationController)?.topViewController as? RequestsViewController)?.delegate = bodyExportDelegate UIViewController.currentViewController()?.present(initialVC, animated: true, completion: nil) } } diff --git a/Sources/NetShears/UI/BodyDetailViewController.swift b/Sources/NetShears/UI/BodyDetailViewController.swift index bff2daf..429cf44 100644 --- a/Sources/NetShears/UI/BodyDetailViewController.swift +++ b/Sources/NetShears/UI/BodyDetailViewController.swift @@ -17,6 +17,8 @@ final class BodyDetailViewController: UIViewController, ShowLoaderProtocol { @IBOutlet weak var buttonNext: UIBarButtonItem! static let kPadding: CGFloat = 10.0 + + var bodyExportType: BodyExportType = .default var searchController: UISearchController? var highlightedWords: [NSTextCheckingResult] = [] @@ -47,7 +49,7 @@ final class BodyDetailViewController: UIViewController, ShowLoaderProtocol { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let hud = showLoader(view: view) - RequestExporter.body(data) { [weak self] (stringData) in + RequestExporter.body(data, bodyExportType: bodyExportType ?? .default) { [weak self] (stringData) in let formattedJSON = stringData DispatchQueue.main.async { self?.textView.text = formattedJSON diff --git a/Sources/NetShears/UI/RequestDetailViewController.swift b/Sources/NetShears/UI/RequestDetailViewController.swift index fafefea..83cb0bd 100644 --- a/Sources/NetShears/UI/RequestDetailViewController.swift +++ b/Sources/NetShears/UI/RequestDetailViewController.swift @@ -11,6 +11,7 @@ import UIKit final class RequestDetailViewController: UIViewController, ShowLoaderProtocol { @IBOutlet weak var tableView: UITableView! + weak var delegate: BodyExporterDelegate? var request: NetShearsRequestModel? var sections: [NetShearsSection] = [ @@ -73,15 +74,26 @@ final class RequestDetailViewController: UIViewController, ShowLoaderProtocol { func shareContent(_ sender: UIBarButtonItem, requestExportOption: RequestResponseExportOption = .flat){ if let request = request{ - NSHelper.shareRequests(presentingViewController: self, sender: sender, requests: [request], requestExportOption: requestExportOption) + NSHelper.shareRequests(presentingViewController: self, sender: sender, requests: [request], requestExportOption: requestExportOption, delegate: delegate) } } - func openBodyDetailVC(title: String?, body: Data?){ + private var responseExportType: BodyExportType { + guard let request = request else { return .default } + return delegate?.netShears(exportResponseBodyFor: request) ?? .default + } + + private var requestExportType: BodyExportType { + guard let request = request else { return .default } + return delegate?.netShears(exportRequestBodyFor: request) ?? .default + } + + func openBodyDetailVC(title: String?, body: Data?, exportType: BodyExportType) { let storyboard = UIStoryboard.NetShearsStoryBoard if let requestDetailVC = storyboard.instantiateViewController(withIdentifier: "BodyDetailViewController") as? BodyDetailViewController{ requestDetailVC.title = title requestDetailVC.data = body + requestDetailVC.bodyExportType = exportType self.show(requestDetailVC, sender: self) } } @@ -146,10 +158,10 @@ extension RequestDetailViewController: UITableViewDelegate{ switch section.type { case .requestBody: - openBodyDetailVC(title: "Request Body", body: request?.httpBody) + openBodyDetailVC(title: "Request Body", body: request?.httpBody, exportType: requestExportType) break case .responseBody: - openBodyDetailVC(title: "Response Body", body: request?.dataResponse) + openBodyDetailVC(title: "Response Body", body: request?.dataResponse, exportType: responseExportType) break default: break diff --git a/Sources/NetShears/UI/RequestListViewController.swift b/Sources/NetShears/UI/RequestListViewController.swift index e01fc61..2cab3f0 100644 --- a/Sources/NetShears/UI/RequestListViewController.swift +++ b/Sources/NetShears/UI/RequestListViewController.swift @@ -12,6 +12,7 @@ import UIKit class RequestsViewController: UIViewController, ShowLoaderProtocol { @IBOutlet weak var collectionView: UICollectionView! + weak var delegate: BodyExporterDelegate? private var filteredRequests: [NetShearsRequestModel] = Storage.shared.requests @@ -101,7 +102,7 @@ class RequestsViewController: UIViewController, ShowLoaderProtocol { } private func shareContent(_ sender: UIBarButtonItem, requestExportOption: RequestResponseExportOption = .flat){ - NSHelper.shareRequests(presentingViewController: self, sender: sender, requests: filteredRequests, requestExportOption: requestExportOption) + NSHelper.shareRequests(presentingViewController: self, sender: sender, requests: filteredRequests, requestExportOption: requestExportOption, delegate: delegate) } // MARK: - Navigation @@ -119,6 +120,7 @@ class RequestsViewController: UIViewController, ShowLoaderProtocol { let storyboard = UIStoryboard.NetShearsStoryBoard if let requestDetailVC = storyboard.instantiateViewController(withIdentifier: String(describing: RequestDetailViewController.self)) as? RequestDetailViewController{ requestDetailVC.request = request + requestDetailVC.delegate = delegate self.show(requestDetailVC, sender: self) } } diff --git a/Sources/NetShears/Utils/NSHelper.swift b/Sources/NetShears/Utils/NSHelper.swift index 2bb3949..012f67c 100644 --- a/Sources/NetShears/Utils/NSHelper.swift +++ b/Sources/NetShears/Utils/NSHelper.swift @@ -10,13 +10,13 @@ import UIKit final class NSHelper { - static func shareRequests(presentingViewController: UIViewController, sender: UIBarButtonItem, requests: [NetShearsRequestModel], requestExportOption: RequestResponseExportOption = .flat){ + static func shareRequests(presentingViewController: UIViewController, sender: UIBarButtonItem, requests: [NetShearsRequestModel], requestExportOption: RequestResponseExportOption = .flat, delegate: BodyExporterDelegate?){ var text = "" switch requestExportOption { case .flat: - text = getTxtText(requests: requests) + text = getTxtText(requests: requests, delegate: delegate) case .curl: - text = getCurlText(requests: requests) + text = getCurlText(requests: requests, delegate: delegate) case .postman: text = getPostmanCollection(requests: requests) ?? "{}" text = text.replacingOccurrences(of: "\\/", with: "/") @@ -42,18 +42,18 @@ final class NSHelper { presentingViewController.present(activityViewController, animated: true, completion: nil) } - private static func getTxtText(requests: [NetShearsRequestModel]) -> String { + private static func getTxtText(requests: [NetShearsRequestModel], delegate: BodyExporterDelegate?) -> String { var text: String = "" for request in requests{ - text = text + RequestExporter.txtExport(request: request) + text = text + RequestExporter.txtExport(request: request, delegate: delegate) } return text } - private static func getCurlText(requests: [NetShearsRequestModel]) -> String { + private static func getCurlText(requests: [NetShearsRequestModel], delegate: BodyExporterDelegate?) -> String { var text: String = "" for request in requests{ - text = text + RequestExporter.curlExport(request: request) + text = text + RequestExporter.curlExport(request: request, delegate: delegate) } return text } diff --git a/Sources/NetShears/Utils/RequestExporter.swift b/Sources/NetShears/Utils/RequestExporter.swift index 2d2df71..db22317 100644 --- a/Sources/NetShears/Utils/RequestExporter.swift +++ b/Sources/NetShears/Utils/RequestExporter.swift @@ -7,6 +7,11 @@ import UIKit +public enum BodyExportType { + case `default` + case custom(_ text: String) +} + final class RequestExporter: NSObject { static func overview(request: NetShearsRequestModel) -> NSMutableAttributedString{ @@ -33,14 +38,18 @@ final class RequestExporter: NSObject { return final } - static func body(_ body: Data?, splitLength: Int? = nil, completion: @escaping (String) -> Void){ + static func body(_ body: Data?, splitLength: Int? = nil, bodyExportType: BodyExportType, completion: @escaping (String) -> Void){ DispatchQueue.global().async { - completion(RequestExporter.body(body, splitLength: splitLength)) + completion(RequestExporter.body(body, splitLength: splitLength, bodyExportType: bodyExportType)) return } } - static func body(_ body: Data?, splitLength: Int? = nil) -> String{ + static func body(_ body: Data?, splitLength: Int? = nil, bodyExportType: BodyExportType) -> String { + if case .custom(let text) = bodyExportType { + return text + } + guard body != nil else { return "-" } @@ -52,7 +61,7 @@ final class RequestExporter: NSObject { return "-" } - static func txtExport(request: NetShearsRequestModel) -> String{ + static func txtExport(request: NetShearsRequestModel, delegate: BodyExporterDelegate?) -> String{ var txt: String = "" txt.append("*** Overview *** \n") @@ -60,18 +69,18 @@ final class RequestExporter: NSObject { txt.append("*** Request Header *** \n") txt.append(header(request.headers).string + "\n\n") txt.append("*** Request Body *** \n") - txt.append(body(request.httpBody) + "\n\n") + txt.append(body(request.httpBody, bodyExportType: delegate?.netShears(exportRequestBodyFor: request) ?? .default) + "\n\n") txt.append("*** Response Header *** \n") txt.append(header(request.responseHeaders).string + "\n\n") txt.append("*** Response Body *** \n") - txt.append(body(request.dataResponse) + "\n\n") + txt.append(body(request.dataResponse, bodyExportType: delegate?.netShears(exportResponseBodyFor: request) ?? .default) + "\n\n") txt.append("------------------------------------------------------------------------\n") txt.append("------------------------------------------------------------------------\n") txt.append("------------------------------------------------------------------------\n\n\n\n") return txt } - static func curlExport(request: NetShearsRequestModel) -> String{ + static func curlExport(request: NetShearsRequestModel, delegate: BodyExporterDelegate?) -> String{ var txt: String = "" txt.append("*** Overview *** \n") @@ -81,7 +90,7 @@ final class RequestExporter: NSObject { txt.append("*** Response Header *** \n") txt.append(header(request.responseHeaders).string + "\n\n") txt.append("*** Response Body *** \n") - txt.append(body(request.dataResponse) + "\n\n") + txt.append(body(request.dataResponse, bodyExportType: delegate?.netShears(exportResponseBodyFor: request) ?? .default) + "\n\n") txt.append("------------------------------------------------------------------------\n") txt.append("------------------------------------------------------------------------\n") txt.append("------------------------------------------------------------------------\n\n\n\n")