Skip to content

Commit ddc792f

Browse files
author
Nikita Mikheev
committed
implement Root and System modules
0 parents  commit ddc792f

31 files changed

+1224
-0
lines changed

.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>SchemeUserState</key>
6+
<dict>
7+
<key>SuperBrowser.xcscheme_^#shared#^_</key>
8+
<dict>
9+
<key>orderHint</key>
10+
<integer>1</integer>
11+
</dict>
12+
</dict>
13+
</dict>
14+
</plist>

Package.resolved

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"object": {
3+
"pins": [
4+
{
5+
"package": "WindowInstanceManager",
6+
"repositoryURL": "https://github.com/default/WindowInstanceManager",
7+
"state": {
8+
"branch": null,
9+
"revision": "97be4952f15e55ac9a50fe7156555968c41009f5",
10+
"version": "0.1.1"
11+
}
12+
}
13+
]
14+
},
15+
"version": 1
16+
}

Package.swift

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// swift-tools-version:5.5
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: "SuperBrowser",
8+
platforms: [
9+
.iOS(.v13)
10+
],
11+
products: [
12+
.library(
13+
name: "SuperBrowser",
14+
targets: ["SuperBrowser"]
15+
)
16+
],
17+
dependencies: [
18+
.package(
19+
url: "https://github.com/default/WindowInstanceManager",
20+
.upToNextMajor(from: "0.1.0")
21+
)
22+
],
23+
targets: [
24+
.target(
25+
name: "SuperBrowser",
26+
dependencies: [
27+
.byName(name: "WindowInstanceManager")
28+
],
29+
resources: [
30+
.process("Resources/Media.xcassets")
31+
]
32+
)
33+
]
34+
)

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SuperBrowser
2+
3+
`SuperBrowser` is a tool, used to provide visual representation tools for better logging, testing and debugging.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// ListSection.swift
3+
// Created by Nikita Mikheev on 27.02.2022.
4+
//
5+
6+
import Foundation
7+
8+
public struct ListSection {
9+
let title: String
10+
let items: [ListItem]
11+
12+
// MARK: Initializers
13+
public init(
14+
title: String,
15+
items: [ListItem]
16+
) {
17+
self.title = title
18+
self.items = items
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
//
2+
// ListableItem.swift
3+
// Created by Nikita Mikheev on 27.02.2022.
4+
//
5+
6+
import Foundation
7+
import UIKit
8+
9+
public struct ListItem {
10+
public let title: String
11+
public let value: ListValueRepresentable
12+
13+
public init(
14+
title: String,
15+
value: ListValueRepresentable
16+
) {
17+
self.title = title
18+
self.value = value
19+
}
20+
}
21+
22+
public protocol ListValueRepresentable {
23+
var valueDescription: String { get }
24+
var sublist: [ListItem]? { get }
25+
}
26+
public extension ListValueRepresentable where Self: CustomStringConvertible {
27+
var valueDescription: String {
28+
description
29+
}
30+
}
31+
public extension ListValueRepresentable {
32+
var sublist: [ListItem]? { nil }
33+
}
34+
35+
// Optional
36+
extension Optional: ListValueRepresentable where Wrapped: ListValueRepresentable {
37+
public var valueDescription: String {
38+
switch self {
39+
case .none:
40+
return "nil"
41+
case .some(let wrapped):
42+
return wrapped.valueDescription
43+
}
44+
}
45+
public var sublist: [ListItem]? {
46+
switch self {
47+
case .none:
48+
return nil
49+
case .some(let wrapped):
50+
return wrapped.sublist
51+
}
52+
}
53+
}
54+
55+
// Boolean
56+
extension Bool: ListValueRepresentable { }
57+
58+
// Numeric
59+
extension Int: ListValueRepresentable { }
60+
extension Double: ListValueRepresentable { }
61+
extension Float: ListValueRepresentable { }
62+
extension CGFloat: ListValueRepresentable { }
63+
extension NSNumber: ListValueRepresentable { }
64+
65+
// String
66+
extension String: ListValueRepresentable {
67+
public var valueDescription: String {
68+
"\"" + description + "\""
69+
}
70+
}
71+
72+
// Collections
73+
extension Array: ListValueRepresentable where Element: ListValueRepresentable {
74+
public var valueDescription: String {
75+
isEmpty ? "[∅]" : "[...]"
76+
}
77+
public var sublist: [ListItem]? {
78+
guard !isEmpty else {
79+
return nil
80+
}
81+
82+
var items = [ListItem]()
83+
items.reserveCapacity(count)
84+
85+
for index in 0..<count {
86+
items.append(
87+
ListItem(
88+
title: index.description,
89+
value: self[index]
90+
)
91+
)
92+
}
93+
94+
return items
95+
}
96+
}
97+
extension Set: ListValueRepresentable {
98+
public var valueDescription: String {
99+
isEmpty ? "[∅]" : "set [...]"
100+
}
101+
public var sublist: [ListItem]? {
102+
guard !isEmpty else {
103+
return nil
104+
}
105+
106+
return map {
107+
ListItem(
108+
title: "",
109+
value: $0 as? ListValueRepresentable ?? ""
110+
)
111+
}
112+
}
113+
}
114+
115+
116+
// Dictionary
117+
extension Dictionary: ListValueRepresentable {
118+
public var valueDescription: String {
119+
isEmpty ? "[∅:∅]" : "[ : ]"
120+
}
121+
public var sublist: [ListItem]? {
122+
guard !isEmpty else {
123+
return nil
124+
}
125+
126+
return keys.map { key in
127+
ListItem(
128+
title: (key as? CustomStringConvertible)?.description ?? "",
129+
value: self[key] as? ListValueRepresentable ?? ""
130+
)
131+
}
132+
}
133+
}
134+
extension Dictionary where Key: Comparable {
135+
public var sublist: [ListItem]? {
136+
guard !isEmpty else {
137+
return nil
138+
}
139+
140+
return keys.sorted(by: <).map { key in
141+
ListItem(
142+
title: (key as? CustomStringConvertible)?.description ?? "",
143+
value: self[key] as? ListValueRepresentable ?? ""
144+
)
145+
}
146+
}
147+
}
148+
149+
// Data
150+
extension Data: ListValueRepresentable {
151+
public var valueDescription: String {
152+
"<Data>"
153+
}
154+
}
155+
156+
// UUID
157+
extension UUID: ListValueRepresentable {
158+
public var valueDescription: String {
159+
uuidString
160+
}
161+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//
2+
// RootModule.swift
3+
//
4+
//
5+
// Created by Nikita Mikheev on 27.02.2022.
6+
//
7+
8+
import UIKit
9+
10+
enum RootMenuItem: String, MenuItemProtocol, CaseIterable {
11+
12+
case system
13+
// case persistentData
14+
// case network
15+
// case logs
16+
// case files
17+
18+
// MARK: Protocol Conformance
19+
var id: String {
20+
rawValue
21+
}
22+
var icon: Character {
23+
switch self {
24+
case .system:
25+
return "⚙️"
26+
// case .persistentData:
27+
// return "📇"
28+
// case .network:
29+
// return "🌐"
30+
// case .logs:
31+
// return "🧾"
32+
// case .files:
33+
// return "📦"
34+
}
35+
}
36+
var title: String {
37+
switch self {
38+
// case .persistentData:
39+
// return "Persistent Data"
40+
default:
41+
return rawValue.capitalized
42+
}
43+
}
44+
}
45+
46+
struct RootModule: ModuleProtocol {
47+
typealias View = UIViewController
48+
49+
// MARK: Factories
50+
func build() -> UIViewController {
51+
let router = RootRouter()
52+
let presenter = RootPresenter(
53+
router: router
54+
)
55+
56+
let controller = MenuViewController<RootPresenter>(
57+
presenter: presenter
58+
)
59+
60+
controller.title = "SuperBrowser"
61+
router.viewController = controller
62+
63+
return controller
64+
}
65+
}
66+
67+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// RootPresenter.swift
3+
// Created by Nikita Mikheev on 27.02.2022.
4+
//
5+
6+
import Foundation
7+
8+
protocol RootRouting {
9+
func route(to: RootMenuItem)
10+
}
11+
12+
final class RootPresenter: MenuViewPresenter {
13+
// MARK: Properties
14+
var items: [MenuItemProtocol] {
15+
RootMenuItem.allCases
16+
}
17+
18+
// MARK: Dependencies
19+
private let router: RootRouting
20+
21+
// MARK: Initializers
22+
init(router: RootRouting) {
23+
self.router = router
24+
}
25+
}
26+
27+
// MARK: - MenuViewPresenter
28+
extension RootPresenter: ViewDelegate {
29+
var controllerTitle: String? {
30+
"SuperBrowser"
31+
}
32+
33+
func didUserSelect(item: MenuItemProtocol) {
34+
guard let item = item as? RootMenuItem else {
35+
assertionFailure("Unrecognized menu item selected")
36+
return
37+
}
38+
39+
router.route(to: item)
40+
}
41+
}

0 commit comments

Comments
 (0)