├── .gitignore
├── Historian-ios
├── Historian
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── .gitignore
└── Historian.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
│ └── project.pbxproj
├── Historian-macos
├── Historian
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── Historian.entitlements
│ ├── Info.plist
│ ├── AppDelegate.swift
│ └── Base.lproj
│ │ └── Main.storyboard
└── Historian.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
│ └── project.pbxproj
├── HistoryView
├── Extensions
│ └── RangeReplaceableCollection+ext.swift
├── Step.swift
├── RowView.swift
├── HistoryView+CA.swift
└── HistoryView.swift
└── Readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | xcuserdata/
2 |
--------------------------------------------------------------------------------
/Historian-ios/Historian/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Historian-macos/Historian/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Historian-ios/Historian/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Historian-macos/Historian/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Historian-ios/Historian.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Historian-macos/Historian.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Historian-ios/Historian.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Historian-macos/Historian.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Historian-macos/Historian/Historian.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/HistoryView/Extensions/RangeReplaceableCollection+ext.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RangeReplaceableCollection+ext.swift
3 | // Playgrounder
4 | //
5 | // Created by Sven A. Schmidt on 18/01/2020.
6 | // Copyright © 2020 finestructure. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | extension RangeReplaceableCollection where Element: Equatable {
13 | @discardableResult
14 | mutating func removeFirst(value: Element) -> Element? {
15 | guard let idx = firstIndex(of: value) else { return nil }
16 | return remove(at: idx)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Historian
2 |
3 | Historian is an app state viewer and manipulator for apps written in [Pointfree.co's Composable Architecture](https://www.pointfree.co/collections/composable-architecture).
4 |
5 |
6 |
7 | For more information see this [introductory blog post](https://finestructure.co/blog/2020/3/30/state-of-the-app-state-surfing).
8 |
9 | ## OS variants
10 |
11 | The iOS and macOS apps are only minimally different and can probably be merged soon.
12 |
13 | The main reason it's not the case yet is that using a single app target seems to make the whole app a catalyst app, even when using SwiftUI.
14 |
15 | It would probably be possible to integrate both into single app even without doing so but since most of the code really sits in the dependency `HistoryView` and the apps are simple viewer shell it's likely more hassle that it's worth.
16 |
--------------------------------------------------------------------------------
/Historian-macos/Historian/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "2x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "1x",
26 | "size" : "128x128"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "2x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "1x",
36 | "size" : "256x256"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "2x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "1x",
46 | "size" : "512x512"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "2x",
51 | "size" : "512x512"
52 | }
53 | ],
54 | "info" : {
55 | "author" : "xcode",
56 | "version" : 1
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Historian-macos/Historian/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | Copyright © 2020 finestructure. All rights reserved.
27 | NSMainStoryboardFile
28 | Main
29 | NSPrincipalClass
30 | NSApplication
31 | NSSupportsAutomaticTermination
32 |
33 | NSSupportsSuddenTermination
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/HistoryView/Step.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Step.swift
3 | //
4 | //
5 | // Created by Sven A. Schmidt on 16/03/2020.
6 | //
7 |
8 | import CasePaths
9 | import Foundation
10 |
11 |
12 | public enum Step: Hashable {
13 | case initial
14 | case step(Value)
15 |
16 | public struct Value: Hashable {
17 | var index: Int
18 | var action: String
19 | var resultingState: Data
20 | }
21 |
22 | public init(index: Int, action: String, resultingState: Data) {
23 | self = .step(.init(index: index, action: action, resultingState: resultingState))
24 | }
25 | }
26 |
27 |
28 | extension Step {
29 | var value: Value? { (/Step.step).extract(from: self) }
30 |
31 | var resultingState: Data? {
32 | switch self {
33 | case .initial: return nil
34 | case .step(let step): return step.resultingState
35 | }
36 | }
37 | }
38 |
39 |
40 | extension Step: Identifiable {
41 | public var id: Step { self }
42 | }
43 |
44 |
45 | extension Step: Equatable {
46 | public static func == (lhs: Step, rhs: Step) -> Bool {
47 | switch (lhs, rhs) {
48 | case (.initial, .initial):
49 | return true
50 | case let (.step(a), .step(b)):
51 | return a.index == b.index
52 | default:
53 | return false
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Historian-ios/Historian.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "CompArch",
6 | "repositoryURL": "https://github.com/finestructure/CompArch",
7 | "state": {
8 | "branch": null,
9 | "revision": "b3bbb247b18b29549e905e31e5a19ebc46d1cefb",
10 | "version": "0.7.2"
11 | }
12 | },
13 | {
14 | "package": "HistoryTransceiver",
15 | "repositoryURL": "https://github.com/finestructure/HistoryTransceiver",
16 | "state": {
17 | "branch": null,
18 | "revision": "fd88668d1648e5f7f61843e676ecbe4cafa4a642",
19 | "version": "0.0.3"
20 | }
21 | },
22 | {
23 | "package": "MultipeerKit",
24 | "repositoryURL": "https://github.com/insidegui/MultipeerKit",
25 | "state": {
26 | "branch": null,
27 | "revision": "3f430bc28e1426ba42cdaa8b19fb4d89ce6d1c3b",
28 | "version": "0.1.2"
29 | }
30 | },
31 | {
32 | "package": "CasePaths",
33 | "repositoryURL": "https://github.com/pointfreeco/swift-case-paths",
34 | "state": {
35 | "branch": null,
36 | "revision": "a9c1e05518b6d95cf5844d823020376f2b6ff842",
37 | "version": "0.1.0"
38 | }
39 | }
40 | ]
41 | },
42 | "version": 1
43 | }
44 |
--------------------------------------------------------------------------------
/Historian-macos/Historian.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "CompArch",
6 | "repositoryURL": "https://github.com/finestructure/CompArch",
7 | "state": {
8 | "branch": null,
9 | "revision": "b3bbb247b18b29549e905e31e5a19ebc46d1cefb",
10 | "version": "0.7.2"
11 | }
12 | },
13 | {
14 | "package": "HistoryTransceiver",
15 | "repositoryURL": "https://github.com/finestructure/HistoryTransceiver",
16 | "state": {
17 | "branch": null,
18 | "revision": "fd88668d1648e5f7f61843e676ecbe4cafa4a642",
19 | "version": "0.0.3"
20 | }
21 | },
22 | {
23 | "package": "MultipeerKit",
24 | "repositoryURL": "https://github.com/insidegui/MultipeerKit",
25 | "state": {
26 | "branch": null,
27 | "revision": "3f430bc28e1426ba42cdaa8b19fb4d89ce6d1c3b",
28 | "version": "0.1.2"
29 | }
30 | },
31 | {
32 | "package": "CasePaths",
33 | "repositoryURL": "https://github.com/pointfreeco/swift-case-paths",
34 | "state": {
35 | "branch": null,
36 | "revision": "a9c1e05518b6d95cf5844d823020376f2b6ff842",
37 | "version": "0.1.0"
38 | }
39 | }
40 | ]
41 | },
42 | "version": 1
43 | }
44 |
--------------------------------------------------------------------------------
/Historian-ios/Historian/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Historian
4 | //
5 | // Created by Sven A. Schmidt on 15/03/2020.
6 | // Copyright © 2020 finestructure. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | @UIApplicationMain
13 | class AppDelegate: UIResponder, UIApplicationDelegate {
14 |
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | // MARK: UISceneSession Lifecycle
23 |
24 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
25 | // Called when a new scene session is being created.
26 | // Use this method to select a configuration to create the new scene with.
27 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
28 | }
29 |
30 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
31 | // Called when the user discards a scene session.
32 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
33 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
34 | }
35 |
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/Historian-macos/Historian/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Historian
4 | //
5 | // Created by Sven A. Schmidt on 16/03/2020.
6 | // Copyright © 2020 finestructure. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import HistoryTransceiver
11 | import SwiftUI
12 |
13 |
14 | var historyStore = HistoryView.store(history: [], broadcastEnabled: true)
15 |
16 |
17 | @NSApplicationMain
18 | class AppDelegate: NSObject, NSApplicationDelegate {
19 |
20 | var window: NSWindow!
21 |
22 |
23 | func applicationDidFinishLaunching(_ aNotification: Notification) {
24 | Transceiver.shared.receive(Message.self) { msg in
25 | historyStore.send(HistoryView.Action.appendStep("\(msg.action)", msg.state))
26 | }
27 | Transceiver.shared.resume()
28 |
29 | let contentView = HistoryView(store: historyStore)
30 | .environmentObject(Transceiver.dataSource)
31 |
32 | // Create the window and set the content view.
33 | window = NSWindow(
34 | contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
35 | styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
36 | backing: .buffered, defer: false)
37 | window.center()
38 | window.setFrameAutosaveName("Main Window")
39 | window.contentView = NSHostingView(rootView: contentView)
40 | window.makeKeyAndOrderFront(nil)
41 | }
42 |
43 | func applicationWillTerminate(_ aNotification: Notification) {
44 | // Insert code here to tear down your application
45 | }
46 |
47 |
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/Historian-ios/Historian/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Historian-ios/Historian/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Historian-ios/Historian/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/HistoryView/RowView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RowView.swift
3 | // Historian
4 | //
5 | // Created by Sven A. Schmidt on 15/03/2020.
6 | // Copyright © 2020 finestructure. All rights reserved.
7 | //
8 |
9 | import CompArch
10 | import SwiftUI
11 |
12 |
13 | public typealias IdentifiedRow = Identified
14 |
15 |
16 | public struct RowView: View {
17 | @ObservedObject var store: Store
18 |
19 | var indexLabel: String {
20 | switch self.store.value.step {
21 | case .initial: return "0"
22 | case .step(let step): return "\(step.index)"
23 | }
24 | }
25 |
26 | var actionLabel: String {
27 | switch self.store.value.step {
28 | case .initial: return "initial"
29 | case .step(let step): return step.action
30 | }
31 | }
32 |
33 | public var body: some View {
34 | #if os(macOS)
35 | let view = HStack {
36 | Text(indexLabel)
37 | .frame(width: 30, alignment: .trailing)
38 | Text(actionLabel)
39 | }
40 | .onDrag {
41 | NSItemProvider(object: String(decoding: self.store.value.step.resultingState ?? Data(),
42 | as: UTF8.self) as NSString)
43 | }
44 | #else
45 | let view = HStack {
46 | Button(action: { self.store.send(.rowTapped) },
47 | label: {
48 | HStack {
49 | #if os(iOS)
50 | Image(systemName: "arrowtriangle.right.fill")
51 | .foregroundColor(self.store.value.selected ? .blue : .clear)
52 | #endif
53 | Text(indexLabel)
54 | .frame(width: 30, alignment: .trailing)
55 | Text(actionLabel)
56 | }
57 | })
58 | }
59 | #endif
60 | return view
61 | }
62 | }
63 |
64 |
65 | extension RowView {
66 | public struct State: Identifiable {
67 | public var id: Step { step }
68 | var step: Step
69 | var selected = false
70 | }
71 |
72 | public enum Action {
73 | case rowTapped
74 | }
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/Historian-ios/Historian/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // Historian
4 | //
5 | // Created by Sven A. Schmidt on 15/03/2020.
6 | // Copyright © 2020 finestructure. All rights reserved.
7 | //
8 |
9 | import HistoryTransceiver
10 | import UIKit
11 | import SwiftUI
12 |
13 |
14 | var historyStore = HistoryView.store(history: [], broadcastEnabled: true)
15 |
16 |
17 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
18 |
19 | var window: UIWindow?
20 |
21 |
22 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
23 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
24 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
25 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
26 |
27 | Transceiver.shared.receive(Message.self) { msg in
28 | historyStore.send(HistoryView.Action.appendStep("\(msg.action)", msg.state))
29 | }
30 | Transceiver.shared.resume()
31 |
32 | // Create the SwiftUI view that provides the window contents.
33 | let contentView = HistoryView(store: historyStore)
34 | .environmentObject(Transceiver.dataSource)
35 |
36 | // Use a UIHostingController as window root view controller.
37 | if let windowScene = scene as? UIWindowScene {
38 | let window = UIWindow(windowScene: windowScene)
39 | window.rootViewController = UIHostingController(rootView: contentView)
40 | self.window = window
41 | window.makeKeyAndVisible()
42 | }
43 | }
44 |
45 | func sceneDidDisconnect(_ scene: UIScene) {
46 | // Called as the scene is being released by the system.
47 | // This occurs shortly after the scene enters the background, or when its session is discarded.
48 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
49 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
50 | }
51 |
52 | func sceneDidBecomeActive(_ scene: UIScene) {
53 | // Called when the scene has moved from an inactive state to an active state.
54 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
55 | }
56 |
57 | func sceneWillResignActive(_ scene: UIScene) {
58 | // Called when the scene will move from an active state to an inactive state.
59 | // This may occur due to temporary interruptions (ex. an incoming phone call).
60 | }
61 |
62 | func sceneWillEnterForeground(_ scene: UIScene) {
63 | // Called as the scene transitions from the background to the foreground.
64 | // Use this method to undo the changes made on entering the background.
65 | }
66 |
67 | func sceneDidEnterBackground(_ scene: UIScene) {
68 | // Called as the scene transitions from the foreground to the background.
69 | // Use this method to save data, release shared resources, and store enough scene-specific state information
70 | // to restore the scene back to its current state.
71 | }
72 |
73 |
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/HistoryView/HistoryView+CA.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HistoryView+CA.swift
3 | //
4 | //
5 | // Created by Sven A. Schmidt on 16/03/2020.
6 | //
7 |
8 | import HistoryTransceiver
9 | import CompArch
10 | import Foundation
11 |
12 |
13 | // MARK: - State, Action, Reducer - CA machinery
14 |
15 | extension HistoryView {
16 | public struct State {
17 | var history: [Step] = []
18 | var selection: Step? = nil
19 | var broadcastEnabled = false
20 |
21 | func stepAfter(_ step: Step) -> Step? {
22 | guard
23 | let idx = history.firstIndex(of: step),
24 | case let nextIdx = history.index(after: idx),
25 | history.indices.contains(nextIdx)
26 | else { return nil }
27 | return history[nextIdx]
28 | }
29 |
30 | func stepBefore(_ step: Step) -> Step? {
31 | guard
32 | let idx = history.firstIndex(of: step),
33 | case let prevIdx = history.index(before: idx),
34 | history.indices.contains(prevIdx)
35 | else { return nil }
36 | return history[prevIdx]
37 | }
38 |
39 | public init(history: [Step] = [], selection: Step? = nil, broadcastEnabled: Bool = false) {
40 | self.history = history
41 | self.selection = selection
42 | self.broadcastEnabled = broadcastEnabled
43 | }
44 | }
45 |
46 | public enum Action {
47 | case appendStep(String, Data?)
48 | case selection(Step?)
49 | case deleteTapped
50 | case backTapped
51 | case forwardTapped
52 | case newState(Data?)
53 | case row(IdentifiedRow)
54 | }
55 |
56 | public static var reducer: Reducer {
57 | return { state, action in
58 | switch action {
59 | case let .appendStep(stepAction, .some(postActionState)):
60 | if state.history.isEmpty {
61 | state.history.append(.initial)
62 | }
63 | let newStep = Step(index: state.history.count,
64 | action: stepAction,
65 | resultingState: postActionState)
66 | state.history.append(newStep)
67 | state.selection = newStep
68 | return []
69 | case .appendStep(_, .none):
70 | // ignore empty data when appending
71 | return []
72 | case .selection(let step):
73 | state.selection = step
74 | guard let step = step else { return [] }
75 | return [ .sync { .newState(step.resultingState) } ]
76 | case .deleteTapped:
77 | guard
78 | let current = state.selection,
79 | current != .initial
80 | else { return [] }
81 | defer { state.history.removeFirst(value: current) }
82 | let previous = state.stepBefore(current)
83 | state.selection = previous
84 | return [ .sync { .newState(previous?.resultingState) } ]
85 | case .backTapped:
86 | guard
87 | let current = state.selection,
88 | current != .initial
89 | else { return [] }
90 | let previous = state.stepBefore(current)
91 | state.selection = previous
92 | return [ .sync { .newState(previous?.resultingState) } ]
93 | case .forwardTapped:
94 | guard let current = state.selection else { return [] }
95 | guard
96 | let idx = state.history.firstIndex(of: current),
97 | idx != state.history.count - 1
98 | // can't advance further than tip
99 | else { return [] }
100 | guard let next = state.stepAfter(current) else { return [] }
101 | state.selection = next
102 | return [ .sync { .newState(next.resultingState) } ]
103 | case .newState(let newState):
104 | if state.broadcastEnabled {
105 | let msg = Message(command: .reset, action: "", state: newState)
106 | Transceiver.shared.broadcast(msg)
107 | }
108 | return []
109 | case .row((let step, .rowTapped)):
110 | state.selection = step
111 | return [ .sync { .newState(step.resultingState) } ]
112 | }
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/HistoryView/HistoryView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HistoryView.swift
3 | // Playgrounder
4 | //
5 | // Created by Sven A. Schmidt on 11/03/2020.
6 | // Copyright © 2020 finestructure. All rights reserved.
7 | //
8 |
9 | import CasePaths
10 | import CompArch
11 | import HistoryTransceiver
12 | import MultipeerKit
13 | import SwiftUI
14 |
15 |
16 | struct Config {
17 | #if os(macOS)
18 | var minWidth: CGFloat? = 500
19 | var minHeight: CGFloat? = 300
20 | var titlePadding: Edge.Set = [.leading, .top]
21 | var peerListHeight: CGFloat = 100
22 | #else
23 | var minWidth: CGFloat? = nil
24 | var minHeight: CGFloat? = nil
25 | var titlePadding: Edge.Set = .all
26 | var peerListHeight: CGFloat = 150
27 | #endif
28 | }
29 |
30 |
31 | public struct HistoryView: View {
32 | @ObservedObject var store: Store
33 | @EnvironmentObject var dataSource: MultipeerDataSource
34 | @SwiftUI.State var targeted = false
35 | var config = Config()
36 |
37 | public var body: some View {
38 | VStack(alignment: .leading) {
39 | peerList
40 | historyList.frame(minWidth: config.minWidth, minHeight: config.minHeight)
41 | }
42 | }
43 |
44 | var peerList: some View {
45 | VStack(alignment: .leading) {
46 | Text("Peers").font(.system(.headline)).padding(config.titlePadding)
47 | List {
48 | ForEach(dataSource.availablePeers) { peer in
49 | HStack {
50 | Circle()
51 | .frame(width: 12, height: 12)
52 | .foregroundColor(peer.isConnected ? .green : .gray)
53 | Text(peer.name)
54 | Spacer()
55 | }
56 | }
57 | }
58 | .frame(height: config.peerListHeight)
59 | }
60 | }
61 |
62 | var historyList: some View {
63 | VStack(alignment: .leading) {
64 | Text("History").font(.system(.headline)).padding(config.titlePadding)
65 |
66 | List(selection: store.binding(value: \.selection, action: /Action.selection)) {
67 | ForEach(store.value.history.reversed(), id: \.self) {
68 | self.rowView(for: $0)
69 | }
70 | }
71 | ._onDrop(of: [uti], isTargeted: $targeted, perform: dropHandler)
72 |
73 | HStack {
74 | Button(action: { self.store.send(.deleteTapped) }, label: {
75 | self.buttonLabel(title: "Delete", systemImage: "trash")
76 | })
77 | Spacer()
78 | Button(action: { self.store.send(.backTapped) }, label: {
79 | self.buttonLabel(title: "←", systemImage: "backward")
80 | })
81 | Button(action: { self.store.send(.forwardTapped) }, label: {
82 | self.buttonLabel(title: "→", systemImage: "forward")
83 | })
84 | }
85 | .padding()
86 | }
87 | }
88 |
89 | func buttonLabel(title: String, systemImage: String) -> some View {
90 | #if os(macOS)
91 | return AnyView(Text(title))
92 | #else
93 | return AnyView(Image(systemName: systemImage).padding())
94 | #endif
95 | }
96 |
97 | func rowView(for step: Step) -> AnyView {
98 | guard let step = store.value.history.first(where: { $0.id == step.id }) else {
99 | return AnyView(EmptyView())
100 | }
101 | let row = RowView.State(step: step, selected: step.id == store.value.selection?.id)
102 | return AnyView(
103 | RowView(store: self.store.view(
104 | value: { _ in row },
105 | action: { .row(IdentifiedRow(id: row.id, action: $0)) }))
106 | )
107 | }
108 |
109 | }
110 |
111 |
112 |
113 | // MARK: - Initializers / Setup
114 |
115 | extension HistoryView {
116 | public static func store(history: [Step], broadcastEnabled: Bool) -> Store {
117 | return Store(initialValue: State(history: history, broadcastEnabled: broadcastEnabled),
118 | reducer: reducer)
119 | }
120 |
121 | public init(store: Store) { self.store = store }
122 |
123 | public init(history: [Step], broadcastEnabled: Bool) {
124 | self.store = Self.store(history: history, broadcastEnabled: broadcastEnabled)
125 | }
126 | }
127 |
128 |
129 |
130 | // MARK: - Drop handling
131 |
132 | extension View {
133 | func _onDrop(of supportedTypes: [String],
134 | isTargeted targeted: Binding?,
135 | perform action: @escaping ([NSItemProvider]) -> Bool) -> some View {
136 | #if os(macOS)
137 | return AnyView(self.onDrop(of: supportedTypes, isTargeted: targeted, perform: action))
138 | #else
139 | return AnyView(self)
140 | #endif
141 | }
142 | }
143 |
144 |
145 | extension HistoryView {
146 | var uti: String { "public.utf8-plain-text" }
147 |
148 | func dropHandler(_ items: [NSItemProvider]) -> Bool {
149 | guard let item = items.first else { return false }
150 | print(item.registeredTypeIdentifiers)
151 | item.loadItem(forTypeIdentifier: uti, options: nil) { (data, error) in
152 | DispatchQueue.main.async {
153 | if self.store.value.broadcastEnabled, let data = data as? Data {
154 | let msg = Message(command: .reset, action: "", state: data)
155 | Transceiver.shared.broadcast(msg)
156 | }
157 | }
158 | }
159 | return true
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/Historian-ios/Historian/.gitignore:
--------------------------------------------------------------------------------
1 | #########################
2 | # .gitignore file for Xcode4 and Xcode5 Source projects
3 | #
4 | # Apple bugs, waiting for Apple to fix/respond:
5 | #
6 | # 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation?
7 | #
8 | # Version 2.6
9 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects
10 | #
11 | # 2015 updates:
12 | # - Fixed typo in "xccheckout" line - thanks to @lyck for pointing it out!
13 | # - Fixed the .idea optional ignore. Thanks to @hashier for pointing this out
14 | # - Finally added "xccheckout" to the ignore. Apple still refuses to answer support requests about this, but in practice it seems you should ignore it.
15 | # - minor tweaks from Jona and Coeur (slightly more precise xc* filtering/names)
16 | # 2014 updates:
17 | # - appended non-standard items DISABLED by default (uncomment if you use those tools)
18 | # - removed the edit that an SO.com moderator made without bothering to ask me
19 | # - researched CocoaPods .lock more carefully, thanks to Gokhan Celiker
20 | # 2013 updates:
21 | # - fixed the broken "save personal Schemes"
22 | # - added line-by-line explanations for EVERYTHING (some were missing)
23 | #
24 | # NB: if you are storing "built" products, this WILL NOT WORK,
25 | # and you should use a different .gitignore (or none at all)
26 | # This file is for SOURCE projects, where there are many extra
27 | # files that we want to exclude
28 | #
29 | #########################
30 |
31 | #####
32 | # OS X temporary files that should never be committed
33 | #
34 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html
35 |
36 | .DS_Store
37 |
38 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html
39 |
40 | .Trashes
41 |
42 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html
43 |
44 | *.swp
45 |
46 | #
47 | # *.lock - this is used and abused by many editors for many different things.
48 | # For the main ones I use (e.g. Eclipse), it should be excluded
49 | # from source-control, but YMMV.
50 | # (lock files are usually local-only file-synchronization on the local FS that should NOT go in git)
51 | # c.f. the "OPTIONAL" section at bottom though, for tool-specific variations!
52 | #
53 | # In particular, if you're using CocoaPods, you'll want to comment-out this line:
54 | *.lock
55 |
56 |
57 | #
58 | # profile - REMOVED temporarily (on double-checking, I can't find it in OS X docs?)
59 | #profile
60 |
61 |
62 | ####
63 | # Xcode temporary files that should never be committed
64 | #
65 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this...
66 |
67 | *~.nib
68 |
69 |
70 | ####
71 | # Xcode build files -
72 | #
73 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData"
74 |
75 | DerivedData/
76 |
77 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build"
78 |
79 | build/
80 |
81 |
82 | #####
83 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups)
84 | #
85 | # This is complicated:
86 | #
87 | # SOMETIMES you need to put this file in version control.
88 | # Apple designed it poorly - if you use "custom executables", they are
89 | # saved in this file.
90 | # 99% of projects do NOT use those, so they do NOT want to version control this file.
91 | # ..but if you're in the 1%, comment out the line "*.pbxuser"
92 |
93 | # .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html
94 |
95 | *.pbxuser
96 |
97 | # .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
98 |
99 | *.mode1v3
100 |
101 | # .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
102 |
103 | *.mode2v3
104 |
105 | # .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file
106 |
107 | *.perspectivev3
108 |
109 | # NB: also, whitelist the default ones, some projects need to use these
110 | !default.pbxuser
111 | !default.mode1v3
112 | !default.mode2v3
113 | !default.perspectivev3
114 |
115 |
116 | ####
117 | # Xcode 4 - semi-personal settings
118 | #
119 | # Apple Shared data that Apple put in the wrong folder
120 | # c.f. http://stackoverflow.com/a/19260712/153422
121 | # FROM ANSWER: Apple says "don't ignore it"
122 | # FROM COMMENTS: Apple is wrong; Apple code is too buggy to trust; there are no known negative side-effects to ignoring Apple's unofficial advice and instead doing the thing that actively fixes bugs in Xcode
123 | # Up to you, but ... current advice: ignore it.
124 | *.xccheckout
125 |
126 | #
127 | #
128 | # OPTION 1: ---------------------------------
129 | # throw away ALL personal settings (including custom schemes!
130 | # - unless they are "shared")
131 | # As per build/ and DerivedData/, this ought to have a trailing slash
132 | #
133 | # NB: this is exclusive with OPTION 2 below
134 | xcuserdata/
135 |
136 | # OPTION 2: ---------------------------------
137 | # get rid of ALL personal settings, but KEEP SOME OF THEM
138 | # - NB: you must manually uncomment the bits you want to keep
139 | #
140 | # NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X,
141 | # or manually install git over the top of the OS X version
142 | # NB: this is exclusive with OPTION 1 above
143 | #
144 | #xcuserdata/**/*
145 |
146 | # (requires option 2 above): Personal Schemes
147 | #
148 | #!xcuserdata/**/xcschemes/*
149 |
150 | ####
151 | # XCode 4 workspaces - more detailed
152 | #
153 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :)
154 | #
155 | # Workspace layout is quite spammy. For reference:
156 | #
157 | # /(root)/
158 | # /(project-name).xcodeproj/
159 | # project.pbxproj
160 | # /project.xcworkspace/
161 | # contents.xcworkspacedata
162 | # /xcuserdata/
163 | # /(your name)/xcuserdatad/
164 | # UserInterfaceState.xcuserstate
165 | # /xcshareddata/
166 | # /xcschemes/
167 | # (shared scheme name).xcscheme
168 | # /xcuserdata/
169 | # /(your name)/xcuserdatad/
170 | # (private scheme).xcscheme
171 | # xcschememanagement.plist
172 | #
173 | #
174 |
175 | ####
176 | # Xcode 4 - Deprecated classes
177 | #
178 | # Allegedly, if you manually "deprecate" your classes, they get moved here.
179 | #
180 | # We're using source-control, so this is a "feature" that we do not want!
181 |
182 | *.moved-aside
183 |
184 | ####
185 | # OPTIONAL: Some well-known tools that people use side-by-side with Xcode / iOS development
186 | #
187 | # NB: I'd rather not include these here, but gitignore's design is weak and doesn't allow
188 | # modular gitignore: you have to put EVERYTHING in one file.
189 | #
190 | # COCOAPODS:
191 | #
192 | # c.f. http://guides.cocoapods.org/using/using-cocoapods.html#what-is-a-podfilelock
193 | # c.f. http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
194 | #
195 | #!Podfile.lock
196 | #
197 | # RUBY:
198 | #
199 | # c.f. http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/
200 | #
201 | #!Gemfile.lock
202 | #
203 | # IDEA:
204 | #
205 | # c.f. https://www.jetbrains.com/objc/help/managing-projects-under-version-control.html?search=workspace.xml
206 | #
207 | #.idea/workspace.xml
208 | #
209 | # TEXTMATE:
210 | #
211 | # -- UNVERIFIED: c.f. http://stackoverflow.com/a/50283/153422
212 | #
213 | #tm_build_errors
214 |
215 | ####
216 | # UNKNOWN: recommended by others, but I can't discover what these files are
217 | #
--------------------------------------------------------------------------------
/Historian-macos/Historian.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 52;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5A2780B6241F911A00D015F2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A2780B5241F911A00D015F2 /* AppDelegate.swift */; };
11 | 5A2780BA241F911B00D015F2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5A2780B9241F911B00D015F2 /* Assets.xcassets */; };
12 | 5A2780BD241F911B00D015F2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5A2780BC241F911B00D015F2 /* Preview Assets.xcassets */; };
13 | 5A2780C0241F911B00D015F2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5A2780BE241F911B00D015F2 /* Main.storyboard */; };
14 | 5A4871162421015D00C05EBE /* HistoryTransceiver in Frameworks */ = {isa = PBXBuildFile; productRef = 5A4871152421015D00C05EBE /* HistoryTransceiver */; };
15 | 5A64C37F24200BE900B167C3 /* HistoryView+CA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C37724200BE900B167C3 /* HistoryView+CA.swift */; };
16 | 5A64C38024200BE900B167C3 /* RangeReplaceableCollection+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C37924200BE900B167C3 /* RangeReplaceableCollection+ext.swift */; };
17 | 5A64C38124200BE900B167C3 /* Step.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C37A24200BE900B167C3 /* Step.swift */; };
18 | 5A64C38224200BE900B167C3 /* HistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C37B24200BE900B167C3 /* HistoryView.swift */; };
19 | 5A64C38324200BE900B167C3 /* RowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C37C24200BE900B167C3 /* RowView.swift */; };
20 | 5A64C3862420B5F500B167C3 /* CompArch in Frameworks */ = {isa = PBXBuildFile; productRef = 5A64C3852420B5F500B167C3 /* CompArch */; };
21 | 5A64C38C2420B65500B167C3 /* CasePaths in Frameworks */ = {isa = PBXBuildFile; productRef = 5A64C38B2420B65500B167C3 /* CasePaths */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXFileReference section */
25 | 5A2780B2241F911A00D015F2 /* Historian.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Historian.app; sourceTree = BUILT_PRODUCTS_DIR; };
26 | 5A2780B5241F911A00D015F2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
27 | 5A2780B9241F911B00D015F2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
28 | 5A2780BC241F911B00D015F2 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
29 | 5A2780BF241F911B00D015F2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
30 | 5A2780C1241F911B00D015F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 5A2780C2241F911B00D015F2 /* Historian.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Historian.entitlements; sourceTree = ""; };
32 | 5A64C37724200BE900B167C3 /* HistoryView+CA.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "HistoryView+CA.swift"; sourceTree = ""; };
33 | 5A64C37924200BE900B167C3 /* RangeReplaceableCollection+ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RangeReplaceableCollection+ext.swift"; sourceTree = ""; };
34 | 5A64C37A24200BE900B167C3 /* Step.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Step.swift; sourceTree = ""; };
35 | 5A64C37B24200BE900B167C3 /* HistoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = ""; };
36 | 5A64C37C24200BE900B167C3 /* RowView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowView.swift; sourceTree = ""; };
37 | /* End PBXFileReference section */
38 |
39 | /* Begin PBXFrameworksBuildPhase section */
40 | 5A2780AF241F911A00D015F2 /* Frameworks */ = {
41 | isa = PBXFrameworksBuildPhase;
42 | buildActionMask = 2147483647;
43 | files = (
44 | 5A4871162421015D00C05EBE /* HistoryTransceiver in Frameworks */,
45 | 5A64C3862420B5F500B167C3 /* CompArch in Frameworks */,
46 | 5A64C38C2420B65500B167C3 /* CasePaths in Frameworks */,
47 | );
48 | runOnlyForDeploymentPostprocessing = 0;
49 | };
50 | /* End PBXFrameworksBuildPhase section */
51 |
52 | /* Begin PBXGroup section */
53 | 5A2780A9241F911A00D015F2 = {
54 | isa = PBXGroup;
55 | children = (
56 | 5A2780B4241F911A00D015F2 /* Historian */,
57 | 5A64C37424200BE900B167C3 /* HistoryView */,
58 | 5A2780B3241F911A00D015F2 /* Products */,
59 | );
60 | sourceTree = "";
61 | };
62 | 5A2780B3241F911A00D015F2 /* Products */ = {
63 | isa = PBXGroup;
64 | children = (
65 | 5A2780B2241F911A00D015F2 /* Historian.app */,
66 | );
67 | name = Products;
68 | sourceTree = "";
69 | };
70 | 5A2780B4241F911A00D015F2 /* Historian */ = {
71 | isa = PBXGroup;
72 | children = (
73 | 5A2780B5241F911A00D015F2 /* AppDelegate.swift */,
74 | 5A2780B9241F911B00D015F2 /* Assets.xcassets */,
75 | 5A2780BE241F911B00D015F2 /* Main.storyboard */,
76 | 5A2780C1241F911B00D015F2 /* Info.plist */,
77 | 5A2780C2241F911B00D015F2 /* Historian.entitlements */,
78 | 5A2780BB241F911B00D015F2 /* Preview Content */,
79 | );
80 | path = Historian;
81 | sourceTree = "";
82 | };
83 | 5A2780BB241F911B00D015F2 /* Preview Content */ = {
84 | isa = PBXGroup;
85 | children = (
86 | 5A2780BC241F911B00D015F2 /* Preview Assets.xcassets */,
87 | );
88 | path = "Preview Content";
89 | sourceTree = "";
90 | };
91 | 5A64C37424200BE900B167C3 /* HistoryView */ = {
92 | isa = PBXGroup;
93 | children = (
94 | 5A64C37B24200BE900B167C3 /* HistoryView.swift */,
95 | 5A64C37724200BE900B167C3 /* HistoryView+CA.swift */,
96 | 5A64C37C24200BE900B167C3 /* RowView.swift */,
97 | 5A64C37A24200BE900B167C3 /* Step.swift */,
98 | 5A64C37824200BE900B167C3 /* Extensions */,
99 | );
100 | name = HistoryView;
101 | path = ../HistoryView;
102 | sourceTree = "";
103 | };
104 | 5A64C37824200BE900B167C3 /* Extensions */ = {
105 | isa = PBXGroup;
106 | children = (
107 | 5A64C37924200BE900B167C3 /* RangeReplaceableCollection+ext.swift */,
108 | );
109 | path = Extensions;
110 | sourceTree = "";
111 | };
112 | /* End PBXGroup section */
113 |
114 | /* Begin PBXNativeTarget section */
115 | 5A2780B1241F911A00D015F2 /* Historian */ = {
116 | isa = PBXNativeTarget;
117 | buildConfigurationList = 5A2780C5241F911B00D015F2 /* Build configuration list for PBXNativeTarget "Historian" */;
118 | buildPhases = (
119 | 5A2780AE241F911A00D015F2 /* Sources */,
120 | 5A2780AF241F911A00D015F2 /* Frameworks */,
121 | 5A2780B0241F911A00D015F2 /* Resources */,
122 | );
123 | buildRules = (
124 | );
125 | dependencies = (
126 | );
127 | name = Historian;
128 | packageProductDependencies = (
129 | 5A64C3852420B5F500B167C3 /* CompArch */,
130 | 5A64C38B2420B65500B167C3 /* CasePaths */,
131 | 5A4871152421015D00C05EBE /* HistoryTransceiver */,
132 | );
133 | productName = Historian;
134 | productReference = 5A2780B2241F911A00D015F2 /* Historian.app */;
135 | productType = "com.apple.product-type.application";
136 | };
137 | /* End PBXNativeTarget section */
138 |
139 | /* Begin PBXProject section */
140 | 5A2780AA241F911A00D015F2 /* Project object */ = {
141 | isa = PBXProject;
142 | attributes = {
143 | LastSwiftUpdateCheck = 1140;
144 | LastUpgradeCheck = 1140;
145 | ORGANIZATIONNAME = finestructure;
146 | TargetAttributes = {
147 | 5A2780B1241F911A00D015F2 = {
148 | CreatedOnToolsVersion = 11.4;
149 | };
150 | };
151 | };
152 | buildConfigurationList = 5A2780AD241F911A00D015F2 /* Build configuration list for PBXProject "Historian" */;
153 | compatibilityVersion = "Xcode 9.3";
154 | developmentRegion = en;
155 | hasScannedForEncodings = 0;
156 | knownRegions = (
157 | en,
158 | Base,
159 | );
160 | mainGroup = 5A2780A9241F911A00D015F2;
161 | packageReferences = (
162 | 5A64C3842420B5F500B167C3 /* XCRemoteSwiftPackageReference "CompArch" */,
163 | 5A64C38A2420B65500B167C3 /* XCRemoteSwiftPackageReference "swift-case-paths" */,
164 | 5A4871142421015D00C05EBE /* XCRemoteSwiftPackageReference "HistoryTransceiver" */,
165 | );
166 | productRefGroup = 5A2780B3241F911A00D015F2 /* Products */;
167 | projectDirPath = "";
168 | projectRoot = "";
169 | targets = (
170 | 5A2780B1241F911A00D015F2 /* Historian */,
171 | );
172 | };
173 | /* End PBXProject section */
174 |
175 | /* Begin PBXResourcesBuildPhase section */
176 | 5A2780B0241F911A00D015F2 /* Resources */ = {
177 | isa = PBXResourcesBuildPhase;
178 | buildActionMask = 2147483647;
179 | files = (
180 | 5A2780C0241F911B00D015F2 /* Main.storyboard in Resources */,
181 | 5A2780BD241F911B00D015F2 /* Preview Assets.xcassets in Resources */,
182 | 5A2780BA241F911B00D015F2 /* Assets.xcassets in Resources */,
183 | );
184 | runOnlyForDeploymentPostprocessing = 0;
185 | };
186 | /* End PBXResourcesBuildPhase section */
187 |
188 | /* Begin PBXSourcesBuildPhase section */
189 | 5A2780AE241F911A00D015F2 /* Sources */ = {
190 | isa = PBXSourcesBuildPhase;
191 | buildActionMask = 2147483647;
192 | files = (
193 | 5A64C38224200BE900B167C3 /* HistoryView.swift in Sources */,
194 | 5A64C38024200BE900B167C3 /* RangeReplaceableCollection+ext.swift in Sources */,
195 | 5A64C38324200BE900B167C3 /* RowView.swift in Sources */,
196 | 5A2780B6241F911A00D015F2 /* AppDelegate.swift in Sources */,
197 | 5A64C37F24200BE900B167C3 /* HistoryView+CA.swift in Sources */,
198 | 5A64C38124200BE900B167C3 /* Step.swift in Sources */,
199 | );
200 | runOnlyForDeploymentPostprocessing = 0;
201 | };
202 | /* End PBXSourcesBuildPhase section */
203 |
204 | /* Begin PBXVariantGroup section */
205 | 5A2780BE241F911B00D015F2 /* Main.storyboard */ = {
206 | isa = PBXVariantGroup;
207 | children = (
208 | 5A2780BF241F911B00D015F2 /* Base */,
209 | );
210 | name = Main.storyboard;
211 | sourceTree = "";
212 | };
213 | /* End PBXVariantGroup section */
214 |
215 | /* Begin XCBuildConfiguration section */
216 | 5A2780C3241F911B00D015F2 /* Debug */ = {
217 | isa = XCBuildConfiguration;
218 | buildSettings = {
219 | ALWAYS_SEARCH_USER_PATHS = NO;
220 | CLANG_ANALYZER_NONNULL = YES;
221 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
223 | CLANG_CXX_LIBRARY = "libc++";
224 | CLANG_ENABLE_MODULES = YES;
225 | CLANG_ENABLE_OBJC_ARC = YES;
226 | CLANG_ENABLE_OBJC_WEAK = YES;
227 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
228 | CLANG_WARN_BOOL_CONVERSION = YES;
229 | CLANG_WARN_COMMA = YES;
230 | CLANG_WARN_CONSTANT_CONVERSION = YES;
231 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
232 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
233 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
234 | CLANG_WARN_EMPTY_BODY = YES;
235 | CLANG_WARN_ENUM_CONVERSION = YES;
236 | CLANG_WARN_INFINITE_RECURSION = YES;
237 | CLANG_WARN_INT_CONVERSION = YES;
238 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
239 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
240 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
241 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
242 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
243 | CLANG_WARN_STRICT_PROTOTYPES = YES;
244 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
245 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
246 | CLANG_WARN_UNREACHABLE_CODE = YES;
247 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
248 | COPY_PHASE_STRIP = NO;
249 | DEBUG_INFORMATION_FORMAT = dwarf;
250 | ENABLE_STRICT_OBJC_MSGSEND = YES;
251 | ENABLE_TESTABILITY = YES;
252 | GCC_C_LANGUAGE_STANDARD = gnu11;
253 | GCC_DYNAMIC_NO_PIC = NO;
254 | GCC_NO_COMMON_BLOCKS = YES;
255 | GCC_OPTIMIZATION_LEVEL = 0;
256 | GCC_PREPROCESSOR_DEFINITIONS = (
257 | "DEBUG=1",
258 | "$(inherited)",
259 | );
260 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
261 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
262 | GCC_WARN_UNDECLARED_SELECTOR = YES;
263 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
264 | GCC_WARN_UNUSED_FUNCTION = YES;
265 | GCC_WARN_UNUSED_VARIABLE = YES;
266 | MACOSX_DEPLOYMENT_TARGET = 10.15;
267 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
268 | MTL_FAST_MATH = YES;
269 | ONLY_ACTIVE_ARCH = YES;
270 | SDKROOT = macosx;
271 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
272 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
273 | };
274 | name = Debug;
275 | };
276 | 5A2780C4241F911B00D015F2 /* Release */ = {
277 | isa = XCBuildConfiguration;
278 | buildSettings = {
279 | ALWAYS_SEARCH_USER_PATHS = NO;
280 | CLANG_ANALYZER_NONNULL = YES;
281 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
282 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
283 | CLANG_CXX_LIBRARY = "libc++";
284 | CLANG_ENABLE_MODULES = YES;
285 | CLANG_ENABLE_OBJC_ARC = YES;
286 | CLANG_ENABLE_OBJC_WEAK = YES;
287 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
288 | CLANG_WARN_BOOL_CONVERSION = YES;
289 | CLANG_WARN_COMMA = YES;
290 | CLANG_WARN_CONSTANT_CONVERSION = YES;
291 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
292 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
293 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
294 | CLANG_WARN_EMPTY_BODY = YES;
295 | CLANG_WARN_ENUM_CONVERSION = YES;
296 | CLANG_WARN_INFINITE_RECURSION = YES;
297 | CLANG_WARN_INT_CONVERSION = YES;
298 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
299 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
300 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
301 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
302 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
303 | CLANG_WARN_STRICT_PROTOTYPES = YES;
304 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
305 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
306 | CLANG_WARN_UNREACHABLE_CODE = YES;
307 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
308 | COPY_PHASE_STRIP = NO;
309 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
310 | ENABLE_NS_ASSERTIONS = NO;
311 | ENABLE_STRICT_OBJC_MSGSEND = YES;
312 | GCC_C_LANGUAGE_STANDARD = gnu11;
313 | GCC_NO_COMMON_BLOCKS = YES;
314 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
315 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
316 | GCC_WARN_UNDECLARED_SELECTOR = YES;
317 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
318 | GCC_WARN_UNUSED_FUNCTION = YES;
319 | GCC_WARN_UNUSED_VARIABLE = YES;
320 | MACOSX_DEPLOYMENT_TARGET = 10.15;
321 | MTL_ENABLE_DEBUG_INFO = NO;
322 | MTL_FAST_MATH = YES;
323 | SDKROOT = macosx;
324 | SWIFT_COMPILATION_MODE = wholemodule;
325 | SWIFT_OPTIMIZATION_LEVEL = "-O";
326 | };
327 | name = Release;
328 | };
329 | 5A2780C6241F911B00D015F2 /* Debug */ = {
330 | isa = XCBuildConfiguration;
331 | buildSettings = {
332 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
333 | CODE_SIGN_ENTITLEMENTS = Historian/Historian.entitlements;
334 | CODE_SIGN_STYLE = Automatic;
335 | COMBINE_HIDPI_IMAGES = YES;
336 | DEVELOPMENT_ASSET_PATHS = "\"Historian/Preview Content\"";
337 | DEVELOPMENT_TEAM = A42K5AU657;
338 | ENABLE_HARDENED_RUNTIME = YES;
339 | ENABLE_PREVIEWS = YES;
340 | INFOPLIST_FILE = Historian/Info.plist;
341 | LD_RUNPATH_SEARCH_PATHS = (
342 | "$(inherited)",
343 | "@executable_path/../Frameworks",
344 | );
345 | MACOSX_DEPLOYMENT_TARGET = 10.15;
346 | PRODUCT_BUNDLE_IDENTIFIER = co.finestructure.Historian;
347 | PRODUCT_NAME = "$(TARGET_NAME)";
348 | SWIFT_VERSION = 5.0;
349 | };
350 | name = Debug;
351 | };
352 | 5A2780C7241F911B00D015F2 /* Release */ = {
353 | isa = XCBuildConfiguration;
354 | buildSettings = {
355 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
356 | CODE_SIGN_ENTITLEMENTS = Historian/Historian.entitlements;
357 | CODE_SIGN_STYLE = Automatic;
358 | COMBINE_HIDPI_IMAGES = YES;
359 | DEVELOPMENT_ASSET_PATHS = "\"Historian/Preview Content\"";
360 | DEVELOPMENT_TEAM = A42K5AU657;
361 | ENABLE_HARDENED_RUNTIME = YES;
362 | ENABLE_PREVIEWS = YES;
363 | INFOPLIST_FILE = Historian/Info.plist;
364 | LD_RUNPATH_SEARCH_PATHS = (
365 | "$(inherited)",
366 | "@executable_path/../Frameworks",
367 | );
368 | MACOSX_DEPLOYMENT_TARGET = 10.15;
369 | PRODUCT_BUNDLE_IDENTIFIER = co.finestructure.Historian;
370 | PRODUCT_NAME = "$(TARGET_NAME)";
371 | SWIFT_VERSION = 5.0;
372 | };
373 | name = Release;
374 | };
375 | /* End XCBuildConfiguration section */
376 |
377 | /* Begin XCConfigurationList section */
378 | 5A2780AD241F911A00D015F2 /* Build configuration list for PBXProject "Historian" */ = {
379 | isa = XCConfigurationList;
380 | buildConfigurations = (
381 | 5A2780C3241F911B00D015F2 /* Debug */,
382 | 5A2780C4241F911B00D015F2 /* Release */,
383 | );
384 | defaultConfigurationIsVisible = 0;
385 | defaultConfigurationName = Release;
386 | };
387 | 5A2780C5241F911B00D015F2 /* Build configuration list for PBXNativeTarget "Historian" */ = {
388 | isa = XCConfigurationList;
389 | buildConfigurations = (
390 | 5A2780C6241F911B00D015F2 /* Debug */,
391 | 5A2780C7241F911B00D015F2 /* Release */,
392 | );
393 | defaultConfigurationIsVisible = 0;
394 | defaultConfigurationName = Release;
395 | };
396 | /* End XCConfigurationList section */
397 |
398 | /* Begin XCRemoteSwiftPackageReference section */
399 | 5A4871142421015D00C05EBE /* XCRemoteSwiftPackageReference "HistoryTransceiver" */ = {
400 | isa = XCRemoteSwiftPackageReference;
401 | repositoryURL = "https://github.com/finestructure/HistoryTransceiver";
402 | requirement = {
403 | kind = upToNextMajorVersion;
404 | minimumVersion = 0.0.3;
405 | };
406 | };
407 | 5A64C3842420B5F500B167C3 /* XCRemoteSwiftPackageReference "CompArch" */ = {
408 | isa = XCRemoteSwiftPackageReference;
409 | repositoryURL = "https://github.com/finestructure/CompArch";
410 | requirement = {
411 | kind = upToNextMajorVersion;
412 | minimumVersion = 0.7.2;
413 | };
414 | };
415 | 5A64C38A2420B65500B167C3 /* XCRemoteSwiftPackageReference "swift-case-paths" */ = {
416 | isa = XCRemoteSwiftPackageReference;
417 | repositoryURL = "https://github.com/pointfreeco/swift-case-paths";
418 | requirement = {
419 | kind = upToNextMajorVersion;
420 | minimumVersion = 0.1.0;
421 | };
422 | };
423 | /* End XCRemoteSwiftPackageReference section */
424 |
425 | /* Begin XCSwiftPackageProductDependency section */
426 | 5A4871152421015D00C05EBE /* HistoryTransceiver */ = {
427 | isa = XCSwiftPackageProductDependency;
428 | package = 5A4871142421015D00C05EBE /* XCRemoteSwiftPackageReference "HistoryTransceiver" */;
429 | productName = HistoryTransceiver;
430 | };
431 | 5A64C3852420B5F500B167C3 /* CompArch */ = {
432 | isa = XCSwiftPackageProductDependency;
433 | package = 5A64C3842420B5F500B167C3 /* XCRemoteSwiftPackageReference "CompArch" */;
434 | productName = CompArch;
435 | };
436 | 5A64C38B2420B65500B167C3 /* CasePaths */ = {
437 | isa = XCSwiftPackageProductDependency;
438 | package = 5A64C38A2420B65500B167C3 /* XCRemoteSwiftPackageReference "swift-case-paths" */;
439 | productName = CasePaths;
440 | };
441 | /* End XCSwiftPackageProductDependency section */
442 | };
443 | rootObject = 5A2780AA241F911A00D015F2 /* Project object */;
444 | }
445 |
--------------------------------------------------------------------------------
/Historian-ios/Historian.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 52;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5A27802A241E522F00D015F2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A278029241E522F00D015F2 /* AppDelegate.swift */; };
11 | 5A27802C241E522F00D015F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A27802B241E522F00D015F2 /* SceneDelegate.swift */; };
12 | 5A278030241E523100D015F2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5A27802F241E523100D015F2 /* Assets.xcassets */; };
13 | 5A278033241E523100D015F2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5A278032241E523100D015F2 /* Preview Assets.xcassets */; };
14 | 5A278036241E523100D015F2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5A278034241E523100D015F2 /* LaunchScreen.storyboard */; };
15 | 5A278045241E55E900D015F2 /* CompArch in Frameworks */ = {isa = PBXBuildFile; productRef = 5A278044241E55E900D015F2 /* CompArch */; };
16 | 5A4871132420FF4500C05EBE /* HistoryTransceiver in Frameworks */ = {isa = PBXBuildFile; productRef = 5A4871122420FF4500C05EBE /* HistoryTransceiver */; };
17 | 5A64C38F2420F0B800B167C3 /* CasePaths in Frameworks */ = {isa = PBXBuildFile; productRef = 5A64C38E2420F0B800B167C3 /* CasePaths */; };
18 | 5A64C39B2420F1F400B167C3 /* HistoryView+CA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C3932420F1F400B167C3 /* HistoryView+CA.swift */; };
19 | 5A64C39C2420F1F400B167C3 /* RangeReplaceableCollection+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C3952420F1F400B167C3 /* RangeReplaceableCollection+ext.swift */; };
20 | 5A64C39D2420F1F400B167C3 /* Step.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C3962420F1F400B167C3 /* Step.swift */; };
21 | 5A64C39E2420F1F400B167C3 /* HistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C3972420F1F400B167C3 /* HistoryView.swift */; };
22 | 5A64C39F2420F1F400B167C3 /* RowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A64C3982420F1F400B167C3 /* RowView.swift */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXFileReference section */
26 | 5A278026241E522F00D015F2 /* Historian.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Historian.app; sourceTree = BUILT_PRODUCTS_DIR; };
27 | 5A278029241E522F00D015F2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
28 | 5A27802B241E522F00D015F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
29 | 5A27802F241E523100D015F2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
30 | 5A278032241E523100D015F2 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
31 | 5A278035241E523100D015F2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
32 | 5A278037241E523100D015F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
33 | 5A64C3932420F1F400B167C3 /* HistoryView+CA.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "HistoryView+CA.swift"; sourceTree = ""; };
34 | 5A64C3952420F1F400B167C3 /* RangeReplaceableCollection+ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RangeReplaceableCollection+ext.swift"; sourceTree = ""; };
35 | 5A64C3962420F1F400B167C3 /* Step.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Step.swift; sourceTree = ""; };
36 | 5A64C3972420F1F400B167C3 /* HistoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = ""; };
37 | 5A64C3982420F1F400B167C3 /* RowView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowView.swift; sourceTree = ""; };
38 | /* End PBXFileReference section */
39 |
40 | /* Begin PBXFrameworksBuildPhase section */
41 | 5A278023241E522F00D015F2 /* Frameworks */ = {
42 | isa = PBXFrameworksBuildPhase;
43 | buildActionMask = 2147483647;
44 | files = (
45 | 5A4871132420FF4500C05EBE /* HistoryTransceiver in Frameworks */,
46 | 5A278045241E55E900D015F2 /* CompArch in Frameworks */,
47 | 5A64C38F2420F0B800B167C3 /* CasePaths in Frameworks */,
48 | );
49 | runOnlyForDeploymentPostprocessing = 0;
50 | };
51 | /* End PBXFrameworksBuildPhase section */
52 |
53 | /* Begin PBXGroup section */
54 | 5A27801D241E522F00D015F2 = {
55 | isa = PBXGroup;
56 | children = (
57 | 5A278028241E522F00D015F2 /* Historian */,
58 | 5A64C3902420F1F400B167C3 /* HistoryView */,
59 | 5A278027241E522F00D015F2 /* Products */,
60 | );
61 | sourceTree = "";
62 | };
63 | 5A278027241E522F00D015F2 /* Products */ = {
64 | isa = PBXGroup;
65 | children = (
66 | 5A278026241E522F00D015F2 /* Historian.app */,
67 | );
68 | name = Products;
69 | sourceTree = "";
70 | };
71 | 5A278028241E522F00D015F2 /* Historian */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 5A278037241E523100D015F2 /* Info.plist */,
75 | 5A278029241E522F00D015F2 /* AppDelegate.swift */,
76 | 5A27802B241E522F00D015F2 /* SceneDelegate.swift */,
77 | 5A27802F241E523100D015F2 /* Assets.xcassets */,
78 | 5A278034241E523100D015F2 /* LaunchScreen.storyboard */,
79 | 5A278031241E523100D015F2 /* Preview Content */,
80 | );
81 | path = Historian;
82 | sourceTree = "";
83 | };
84 | 5A278031241E523100D015F2 /* Preview Content */ = {
85 | isa = PBXGroup;
86 | children = (
87 | 5A278032241E523100D015F2 /* Preview Assets.xcassets */,
88 | );
89 | path = "Preview Content";
90 | sourceTree = "";
91 | };
92 | 5A64C3902420F1F400B167C3 /* HistoryView */ = {
93 | isa = PBXGroup;
94 | children = (
95 | 5A64C3972420F1F400B167C3 /* HistoryView.swift */,
96 | 5A64C3932420F1F400B167C3 /* HistoryView+CA.swift */,
97 | 5A64C3982420F1F400B167C3 /* RowView.swift */,
98 | 5A64C3962420F1F400B167C3 /* Step.swift */,
99 | 5A64C3942420F1F400B167C3 /* Extensions */,
100 | );
101 | name = HistoryView;
102 | path = ../HistoryView;
103 | sourceTree = "";
104 | };
105 | 5A64C3942420F1F400B167C3 /* Extensions */ = {
106 | isa = PBXGroup;
107 | children = (
108 | 5A64C3952420F1F400B167C3 /* RangeReplaceableCollection+ext.swift */,
109 | );
110 | path = Extensions;
111 | sourceTree = "";
112 | };
113 | /* End PBXGroup section */
114 |
115 | /* Begin PBXNativeTarget section */
116 | 5A278025241E522F00D015F2 /* Historian */ = {
117 | isa = PBXNativeTarget;
118 | buildConfigurationList = 5A27803A241E523100D015F2 /* Build configuration list for PBXNativeTarget "Historian" */;
119 | buildPhases = (
120 | 5A278022241E522F00D015F2 /* Sources */,
121 | 5A278023241E522F00D015F2 /* Frameworks */,
122 | 5A278024241E522F00D015F2 /* Resources */,
123 | );
124 | buildRules = (
125 | );
126 | dependencies = (
127 | );
128 | name = Historian;
129 | packageProductDependencies = (
130 | 5A278044241E55E900D015F2 /* CompArch */,
131 | 5A64C38E2420F0B800B167C3 /* CasePaths */,
132 | 5A4871122420FF4500C05EBE /* HistoryTransceiver */,
133 | );
134 | productName = Historian;
135 | productReference = 5A278026241E522F00D015F2 /* Historian.app */;
136 | productType = "com.apple.product-type.application";
137 | };
138 | /* End PBXNativeTarget section */
139 |
140 | /* Begin PBXProject section */
141 | 5A27801E241E522F00D015F2 /* Project object */ = {
142 | isa = PBXProject;
143 | attributes = {
144 | LastSwiftUpdateCheck = 1140;
145 | LastUpgradeCheck = 1140;
146 | ORGANIZATIONNAME = finestructure;
147 | TargetAttributes = {
148 | 5A278025241E522F00D015F2 = {
149 | CreatedOnToolsVersion = 11.4;
150 | };
151 | };
152 | };
153 | buildConfigurationList = 5A278021241E522F00D015F2 /* Build configuration list for PBXProject "Historian" */;
154 | compatibilityVersion = "Xcode 9.3";
155 | developmentRegion = en;
156 | hasScannedForEncodings = 0;
157 | knownRegions = (
158 | en,
159 | Base,
160 | );
161 | mainGroup = 5A27801D241E522F00D015F2;
162 | packageReferences = (
163 | 5A278043241E55E900D015F2 /* XCRemoteSwiftPackageReference "CompArch" */,
164 | 5A64C38D2420F0B800B167C3 /* XCRemoteSwiftPackageReference "swift-case-paths" */,
165 | 5A4871112420FF4500C05EBE /* XCRemoteSwiftPackageReference "HistoryTransceiver" */,
166 | );
167 | productRefGroup = 5A278027241E522F00D015F2 /* Products */;
168 | projectDirPath = "";
169 | projectRoot = "";
170 | targets = (
171 | 5A278025241E522F00D015F2 /* Historian */,
172 | );
173 | };
174 | /* End PBXProject section */
175 |
176 | /* Begin PBXResourcesBuildPhase section */
177 | 5A278024241E522F00D015F2 /* Resources */ = {
178 | isa = PBXResourcesBuildPhase;
179 | buildActionMask = 2147483647;
180 | files = (
181 | 5A278036241E523100D015F2 /* LaunchScreen.storyboard in Resources */,
182 | 5A278033241E523100D015F2 /* Preview Assets.xcassets in Resources */,
183 | 5A278030241E523100D015F2 /* Assets.xcassets in Resources */,
184 | );
185 | runOnlyForDeploymentPostprocessing = 0;
186 | };
187 | /* End PBXResourcesBuildPhase section */
188 |
189 | /* Begin PBXSourcesBuildPhase section */
190 | 5A278022241E522F00D015F2 /* Sources */ = {
191 | isa = PBXSourcesBuildPhase;
192 | buildActionMask = 2147483647;
193 | files = (
194 | 5A64C39B2420F1F400B167C3 /* HistoryView+CA.swift in Sources */,
195 | 5A64C39E2420F1F400B167C3 /* HistoryView.swift in Sources */,
196 | 5A64C39C2420F1F400B167C3 /* RangeReplaceableCollection+ext.swift in Sources */,
197 | 5A64C39F2420F1F400B167C3 /* RowView.swift in Sources */,
198 | 5A64C39D2420F1F400B167C3 /* Step.swift in Sources */,
199 | 5A27802A241E522F00D015F2 /* AppDelegate.swift in Sources */,
200 | 5A27802C241E522F00D015F2 /* SceneDelegate.swift in Sources */,
201 | );
202 | runOnlyForDeploymentPostprocessing = 0;
203 | };
204 | /* End PBXSourcesBuildPhase section */
205 |
206 | /* Begin PBXVariantGroup section */
207 | 5A278034241E523100D015F2 /* LaunchScreen.storyboard */ = {
208 | isa = PBXVariantGroup;
209 | children = (
210 | 5A278035241E523100D015F2 /* Base */,
211 | );
212 | name = LaunchScreen.storyboard;
213 | sourceTree = "";
214 | };
215 | /* End PBXVariantGroup section */
216 |
217 | /* Begin XCBuildConfiguration section */
218 | 5A278038241E523100D015F2 /* Debug */ = {
219 | isa = XCBuildConfiguration;
220 | buildSettings = {
221 | ALWAYS_SEARCH_USER_PATHS = NO;
222 | CLANG_ANALYZER_NONNULL = YES;
223 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
224 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
225 | CLANG_CXX_LIBRARY = "libc++";
226 | CLANG_ENABLE_MODULES = YES;
227 | CLANG_ENABLE_OBJC_ARC = YES;
228 | CLANG_ENABLE_OBJC_WEAK = YES;
229 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
230 | CLANG_WARN_BOOL_CONVERSION = YES;
231 | CLANG_WARN_COMMA = YES;
232 | CLANG_WARN_CONSTANT_CONVERSION = YES;
233 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
234 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
235 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
236 | CLANG_WARN_EMPTY_BODY = YES;
237 | CLANG_WARN_ENUM_CONVERSION = YES;
238 | CLANG_WARN_INFINITE_RECURSION = YES;
239 | CLANG_WARN_INT_CONVERSION = YES;
240 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
241 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
242 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
243 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
244 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
245 | CLANG_WARN_STRICT_PROTOTYPES = YES;
246 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
247 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
248 | CLANG_WARN_UNREACHABLE_CODE = YES;
249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
250 | COPY_PHASE_STRIP = NO;
251 | DEBUG_INFORMATION_FORMAT = dwarf;
252 | ENABLE_STRICT_OBJC_MSGSEND = YES;
253 | ENABLE_TESTABILITY = YES;
254 | GCC_C_LANGUAGE_STANDARD = gnu11;
255 | GCC_DYNAMIC_NO_PIC = NO;
256 | GCC_NO_COMMON_BLOCKS = YES;
257 | GCC_OPTIMIZATION_LEVEL = 0;
258 | GCC_PREPROCESSOR_DEFINITIONS = (
259 | "DEBUG=1",
260 | "$(inherited)",
261 | );
262 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
263 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
264 | GCC_WARN_UNDECLARED_SELECTOR = YES;
265 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
266 | GCC_WARN_UNUSED_FUNCTION = YES;
267 | GCC_WARN_UNUSED_VARIABLE = YES;
268 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
269 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
270 | MTL_FAST_MATH = YES;
271 | ONLY_ACTIVE_ARCH = YES;
272 | SDKROOT = iphoneos;
273 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
274 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
275 | };
276 | name = Debug;
277 | };
278 | 5A278039241E523100D015F2 /* Release */ = {
279 | isa = XCBuildConfiguration;
280 | buildSettings = {
281 | ALWAYS_SEARCH_USER_PATHS = NO;
282 | CLANG_ANALYZER_NONNULL = YES;
283 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
284 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
285 | CLANG_CXX_LIBRARY = "libc++";
286 | CLANG_ENABLE_MODULES = YES;
287 | CLANG_ENABLE_OBJC_ARC = YES;
288 | CLANG_ENABLE_OBJC_WEAK = YES;
289 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
290 | CLANG_WARN_BOOL_CONVERSION = YES;
291 | CLANG_WARN_COMMA = YES;
292 | CLANG_WARN_CONSTANT_CONVERSION = YES;
293 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
294 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
295 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
296 | CLANG_WARN_EMPTY_BODY = YES;
297 | CLANG_WARN_ENUM_CONVERSION = YES;
298 | CLANG_WARN_INFINITE_RECURSION = YES;
299 | CLANG_WARN_INT_CONVERSION = YES;
300 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
301 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
302 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
303 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
304 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
305 | CLANG_WARN_STRICT_PROTOTYPES = YES;
306 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
307 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
308 | CLANG_WARN_UNREACHABLE_CODE = YES;
309 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
310 | COPY_PHASE_STRIP = NO;
311 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
312 | ENABLE_NS_ASSERTIONS = NO;
313 | ENABLE_STRICT_OBJC_MSGSEND = YES;
314 | GCC_C_LANGUAGE_STANDARD = gnu11;
315 | GCC_NO_COMMON_BLOCKS = YES;
316 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
317 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
318 | GCC_WARN_UNDECLARED_SELECTOR = YES;
319 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
320 | GCC_WARN_UNUSED_FUNCTION = YES;
321 | GCC_WARN_UNUSED_VARIABLE = YES;
322 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
323 | MTL_ENABLE_DEBUG_INFO = NO;
324 | MTL_FAST_MATH = YES;
325 | SDKROOT = iphoneos;
326 | SWIFT_COMPILATION_MODE = wholemodule;
327 | SWIFT_OPTIMIZATION_LEVEL = "-O";
328 | VALIDATE_PRODUCT = YES;
329 | };
330 | name = Release;
331 | };
332 | 5A27803B241E523100D015F2 /* Debug */ = {
333 | isa = XCBuildConfiguration;
334 | buildSettings = {
335 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
336 | CODE_SIGN_STYLE = Automatic;
337 | DEVELOPMENT_ASSET_PATHS = "\"Historian/Preview Content\"";
338 | DEVELOPMENT_TEAM = A42K5AU657;
339 | ENABLE_PREVIEWS = YES;
340 | INFOPLIST_FILE = Historian/Info.plist;
341 | LD_RUNPATH_SEARCH_PATHS = (
342 | "$(inherited)",
343 | "@executable_path/Frameworks",
344 | );
345 | PRODUCT_BUNDLE_IDENTIFIER = co.finestructure.Historian;
346 | PRODUCT_NAME = "$(TARGET_NAME)";
347 | SWIFT_VERSION = 5.0;
348 | TARGETED_DEVICE_FAMILY = "1,2";
349 | };
350 | name = Debug;
351 | };
352 | 5A27803C241E523100D015F2 /* Release */ = {
353 | isa = XCBuildConfiguration;
354 | buildSettings = {
355 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
356 | CODE_SIGN_STYLE = Automatic;
357 | DEVELOPMENT_ASSET_PATHS = "\"Historian/Preview Content\"";
358 | DEVELOPMENT_TEAM = A42K5AU657;
359 | ENABLE_PREVIEWS = YES;
360 | INFOPLIST_FILE = Historian/Info.plist;
361 | LD_RUNPATH_SEARCH_PATHS = (
362 | "$(inherited)",
363 | "@executable_path/Frameworks",
364 | );
365 | PRODUCT_BUNDLE_IDENTIFIER = co.finestructure.Historian;
366 | PRODUCT_NAME = "$(TARGET_NAME)";
367 | SWIFT_VERSION = 5.0;
368 | TARGETED_DEVICE_FAMILY = "1,2";
369 | };
370 | name = Release;
371 | };
372 | /* End XCBuildConfiguration section */
373 |
374 | /* Begin XCConfigurationList section */
375 | 5A278021241E522F00D015F2 /* Build configuration list for PBXProject "Historian" */ = {
376 | isa = XCConfigurationList;
377 | buildConfigurations = (
378 | 5A278038241E523100D015F2 /* Debug */,
379 | 5A278039241E523100D015F2 /* Release */,
380 | );
381 | defaultConfigurationIsVisible = 0;
382 | defaultConfigurationName = Release;
383 | };
384 | 5A27803A241E523100D015F2 /* Build configuration list for PBXNativeTarget "Historian" */ = {
385 | isa = XCConfigurationList;
386 | buildConfigurations = (
387 | 5A27803B241E523100D015F2 /* Debug */,
388 | 5A27803C241E523100D015F2 /* Release */,
389 | );
390 | defaultConfigurationIsVisible = 0;
391 | defaultConfigurationName = Release;
392 | };
393 | /* End XCConfigurationList section */
394 |
395 | /* Begin XCRemoteSwiftPackageReference section */
396 | 5A278043241E55E900D015F2 /* XCRemoteSwiftPackageReference "CompArch" */ = {
397 | isa = XCRemoteSwiftPackageReference;
398 | repositoryURL = "https://github.com/finestructure/CompArch";
399 | requirement = {
400 | kind = upToNextMajorVersion;
401 | minimumVersion = 0.7.1;
402 | };
403 | };
404 | 5A4871112420FF4500C05EBE /* XCRemoteSwiftPackageReference "HistoryTransceiver" */ = {
405 | isa = XCRemoteSwiftPackageReference;
406 | repositoryURL = "https://github.com/finestructure/HistoryTransceiver";
407 | requirement = {
408 | kind = upToNextMajorVersion;
409 | minimumVersion = 0.0.1;
410 | };
411 | };
412 | 5A64C38D2420F0B800B167C3 /* XCRemoteSwiftPackageReference "swift-case-paths" */ = {
413 | isa = XCRemoteSwiftPackageReference;
414 | repositoryURL = "https://github.com/pointfreeco/swift-case-paths";
415 | requirement = {
416 | kind = upToNextMajorVersion;
417 | minimumVersion = 0.1.0;
418 | };
419 | };
420 | /* End XCRemoteSwiftPackageReference section */
421 |
422 | /* Begin XCSwiftPackageProductDependency section */
423 | 5A278044241E55E900D015F2 /* CompArch */ = {
424 | isa = XCSwiftPackageProductDependency;
425 | package = 5A278043241E55E900D015F2 /* XCRemoteSwiftPackageReference "CompArch" */;
426 | productName = CompArch;
427 | };
428 | 5A4871122420FF4500C05EBE /* HistoryTransceiver */ = {
429 | isa = XCSwiftPackageProductDependency;
430 | package = 5A4871112420FF4500C05EBE /* XCRemoteSwiftPackageReference "HistoryTransceiver" */;
431 | productName = HistoryTransceiver;
432 | };
433 | 5A64C38E2420F0B800B167C3 /* CasePaths */ = {
434 | isa = XCSwiftPackageProductDependency;
435 | package = 5A64C38D2420F0B800B167C3 /* XCRemoteSwiftPackageReference "swift-case-paths" */;
436 | productName = CasePaths;
437 | };
438 | /* End XCSwiftPackageProductDependency section */
439 | };
440 | rootObject = 5A27801E241E522F00D015F2 /* Project object */;
441 | }
442 |
--------------------------------------------------------------------------------
/Historian-macos/Historian/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
--------------------------------------------------------------------------------