Skip to content

Commit ca44004

Browse files
author
mmt9497
committed
Add source code
1 parent 33191c0 commit ca44004

File tree

6 files changed

+235
-0
lines changed

6 files changed

+235
-0
lines changed

Package.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// swift-tools-version: 5.7
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "JSONViewer",
8+
platforms: [.iOS(.v16), .macOS(.v13)],
9+
products: [
10+
// Products define the executables and libraries a package produces, and make them visible to other packages.
11+
.library(
12+
name: "JSONViewer",
13+
targets: ["JSONViewer"]),
14+
],
15+
targets: [
16+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
17+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
18+
.target(
19+
name: "JSONViewer",
20+
dependencies: [])
21+
],
22+
swiftLanguageVersions: [.v5]
23+
)

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# JSONViewer
2+
3+
4+
5+
Use JSONViewer to view JSON as expandable and collapsable nodes.
6+
7+
**Usage**
8+
9+
- To Convert JSON String to JSON Node
10+
11+
12+
13+
` var rootNode: JSONNode = "{"book":[{ "id":"111","language":"C", "edition":"First","author":"Dennis Ritchie" }]}".jsonNode`
14+
15+
- To Show JSON Node in JSONViewer
16+
`JSONViewer(rootNode: rootNode)`
17+

Sources/JSONViewer/JSONNode.swift

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by Krishan Kumar Varshney on 01/07/23.
6+
//
7+
8+
import Foundation
9+
10+
enum JSONNodeType {
11+
case object
12+
case array
13+
case other
14+
}
15+
16+
var str = "".jsonNode
17+
18+
struct JSONNode: Identifiable, Hashable, Sequence {
19+
20+
static func == (lhs: JSONNode, rhs: JSONNode) -> Bool {
21+
return lhs.id == rhs.id
22+
}
23+
24+
func hash(into hasher: inout Hasher) {
25+
hasher.combine(id)
26+
}
27+
28+
init(key: String, value: String, children: [JSONNode]) {
29+
self.key = key
30+
self.value = value
31+
self.children = children
32+
}
33+
34+
let id = UUID()
35+
var key: String
36+
let value: String
37+
var children: [JSONNode]
38+
var type: JSONNodeType = .other
39+
40+
var isExpandable: Bool {
41+
return !children.isEmpty
42+
}
43+
44+
typealias Iterator = Array<JSONNode>.Iterator
45+
46+
func makeIterator() -> Iterator {
47+
return children.makeIterator()
48+
}
49+
}
50+
51+

Sources/JSONViewer/JSONNodeView.swift

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//
2+
// SwiftUIView.swift
3+
//
4+
//
5+
// Created by Krishan Kumar Varshney on 01/07/23.
6+
//
7+
8+
import SwiftUI
9+
10+
struct JSONNodeView: View {
11+
var node: JSONNode
12+
var level: Int
13+
@State var expanded: [String: Bool]
14+
var body: some View {
15+
VStack {
16+
if node.isExpandable {
17+
VStack(alignment: .trailing) {
18+
HStack {
19+
Spacer()
20+
.frame(width: 32 * CGFloat(level))
21+
Button {
22+
if let value = self.expanded[node.key] {
23+
self.expanded[node.key] = !value
24+
} else {
25+
self.expanded[node.key] = true
26+
}
27+
} label: {
28+
HStack {
29+
if self.expanded[node.key] ?? false {
30+
Image(systemName: "minus.circle.fill")
31+
.imageScale(.large)
32+
.frame(width: 16, height: 16)
33+
} else {
34+
Image(systemName: "plus.circle.fill")
35+
.imageScale(.large)
36+
.frame(width: 16, height: 16)
37+
}
38+
39+
if node.type == .object {
40+
Image(systemName: "curlybraces")
41+
.frame(width: 16, height: 16)
42+
} else if node.type == .array {
43+
Text("[ ]")
44+
.frame(width: 16, height: 16)
45+
}
46+
Text(node.key)
47+
}
48+
}
49+
Spacer()
50+
}
51+
.frame(maxWidth: .infinity, maxHeight: .infinity)
52+
53+
.buttonStyle(PlainButtonStyle())
54+
if self.expanded[node.key] ?? false {
55+
VStack(alignment: .trailing) {
56+
ForEach(node.children) { childNode in
57+
HStack() {
58+
JSONNodeView(node: childNode, level: level + 1, expanded: [String : Bool]())
59+
}
60+
}
61+
}
62+
}
63+
}
64+
} else {
65+
HStack {
66+
Spacer()
67+
.frame(width: 32 * CGFloat(level))
68+
Circle()
69+
.fill(.white)
70+
.frame(width: 8, height: 8)
71+
Text("\(node.key): \(node.value)")
72+
.font(.headline)
73+
Spacer()
74+
}
75+
}
76+
}
77+
}
78+
}

Sources/JSONViewer/JSONViewer.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import SwiftUI
2+
3+
public struct JSONViewer: View {
4+
var rootNode: JSONNode
5+
6+
public var body: some View {
7+
HStack {
8+
VStack {
9+
ScrollView {
10+
JSONNodeView(node: rootNode, level: 0, expanded: ["Root": true])
11+
}
12+
.scrollIndicators(.hidden)
13+
Spacer()
14+
}
15+
Spacer()
16+
}
17+
}
18+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by Krishan Kumar Varshney on 01/07/23.
6+
//
7+
8+
import Foundation
9+
10+
extension String {
11+
var jsonNode: JSONNode? {
12+
if let jsonData = self.data(using: .utf8) {
13+
do {
14+
let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
15+
if let jsonDict = jsonObject as? [String: Any] {
16+
return self.createNode(key: "Root", value: jsonDict)
17+
} else {
18+
return nil
19+
}
20+
} catch {
21+
return nil
22+
}
23+
}
24+
return nil
25+
}
26+
27+
private func createNode(key: String, value: Any) -> JSONNode {
28+
var children: [JSONNode] = []
29+
var type: JSONNodeType = .other
30+
if let dict = value as? [String: Any] {
31+
type = .object
32+
for (key, value) in dict {
33+
children.append(createNode(key: key, value: value))
34+
}
35+
} else if let array = value as? [Any] {
36+
type = .array
37+
for (index, item) in array.enumerated() {
38+
children.append(createNode(key: "\(index)", value: item))
39+
}
40+
} else {
41+
children = []
42+
}
43+
let jsonNodeValue = "\(value)"
44+
var node = JSONNode(key: key, value: jsonNodeValue, children: children)
45+
node.type = type
46+
return node
47+
}
48+
}

0 commit comments

Comments
 (0)