From 4db977dd3a36bc66e92065301383882a383ebba8 Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Wed, 10 Apr 2019 20:42:24 +0200 Subject: [PATCH] Initial commit for new application detail screen --- .travis.yml | 2 +- Podfile | 9 ++ Podfile.lock | 16 +++ Sources/Application/AppDelegate.swift | 10 +- .../Controllers/ApplicationController.swift | 6 +- Sources/Controllers/SplitViewController.swift | 31 ++-- Sources/Controllers/ViewController.swift | 1 + Sources/Factories/ViewControllerFactory.swift | 16 ++- Sources/Factories/WindowFactory.swift | 14 +- .../Application List}/ApplicationView.swift | 0 .../ApplicationActionsViewController.swift | 14 ++ .../ApplicationContainerViewController.swift | 74 ++++++++++ .../ApplicationInfoViewController.swift | 59 ++++++++ .../{ => Core}/BackupController.swift | 0 .../Features/{ => Core}/IconController.swift | 0 .../Features/{ => Core}/SyncController.swift | 0 Sources/Models/Application.swift | 4 +- Sources/Models/InfoPropertyList.swift | 4 +- Sources/Models/Preferences.swift | 2 +- .../SplitViewContainedController.swift | 5 + Sources/Views/Label.swift | 41 ++++++ Sources/Views/MainWindow.swift | 2 +- Syncalicious.xcodeproj/project.pbxproj | 133 +++++++++++++++++- .../contents.xcworkspacedata | 10 ++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ 25 files changed, 419 insertions(+), 42 deletions(-) create mode 100644 Podfile create mode 100644 Podfile.lock rename Sources/{Views => Features/Application List}/ApplicationView.swift (100%) create mode 100644 Sources/Features/ApplicationDetail/ApplicationActionsViewController.swift create mode 100644 Sources/Features/ApplicationDetail/ApplicationContainerViewController.swift create mode 100644 Sources/Features/ApplicationDetail/ApplicationInfoViewController.swift rename Sources/Features/{ => Core}/BackupController.swift (100%) rename Sources/Features/{ => Core}/IconController.swift (100%) rename Sources/Features/{ => Core}/SyncController.swift (100%) create mode 100644 Sources/Protocols/SplitViewContainedController.swift create mode 100644 Syncalicious.xcworkspace/contents.xcworkspacedata create mode 100644 Syncalicious.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/.travis.yml b/.travis.yml index c042816..31de35d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ osx_image: xcode10.2 language: objective-c script: - - set -o pipefail && xcodebuild -project Syncalicious.xcodeproj -scheme "Tests" -sdk macosx clean test build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED="NO" | xcpretty + - set -o pipefail && xcodebuild -workspace Syncalicious.xcworkspace -scheme "Tests" -sdk macosx clean test build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED="NO" | xcpretty after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..95abc77 --- /dev/null +++ b/Podfile @@ -0,0 +1,9 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :macos, '10.14' + +# Frameworks +pod 'Family' + +target 'Syncalicious' +target 'Tests' + diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..d6a814c --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - Family (0.14.3) + +DEPENDENCIES: + - Family + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - Family + +SPEC CHECKSUMS: + Family: e895808117f577305a6b5cabd4fc7463ad262e1f + +PODFILE CHECKSUM: 577eb548a5a12c3ca5c8d9a8a4ae97a7f630192b + +COCOAPODS: 1.6.0 diff --git a/Sources/Application/AppDelegate.swift b/Sources/Application/AppDelegate.swift index 863a89f..1bc7128 100644 --- a/Sources/Application/AppDelegate.swift +++ b/Sources/Application/AppDelegate.swift @@ -109,8 +109,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, BackupControllerDelegate, Ap "title": item.propertyList.bundleName, "subtitle": subtitle, "bundleIdentifier": item.propertyList.bundleIdentifier, - "path": item.path, - "enabled": true + "path": item.url, + "enabled": true, + "model": item ]) } let models = applications @@ -119,7 +120,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, BackupControllerDelegate, Ap if let mainViewController = mainViewController { mainViewController.reload(with: models) - mainViewController.collectionView.selectItems(at: [IndexPath.init(item: 0, section: 0)], scrollPosition: .top) + + let collectionView = mainViewController.collectionView + collectionView.selectItems(at: [IndexPath.init(item: 18, section: 0)], scrollPosition: .centeredHorizontally) + collectionView.delegate?.collectionView?(collectionView, didSelectItemsAt: [IndexPath.init(item: 18, section: 0)]) } debugPrint("Loaded \(applications.count) applications.") diff --git a/Sources/Controllers/ApplicationController.swift b/Sources/Controllers/ApplicationController.swift index ad1e672..884c7ef 100644 --- a/Sources/Controllers/ApplicationController.swift +++ b/Sources/Controllers/ApplicationController.swift @@ -103,11 +103,11 @@ class ApplicationController { return applications } - private func loadApplication(at path: URL) throws -> Application { - let infoPath = path.appendingPathComponent("Contents/Info.plist") + private func loadApplication(at url: URL) throws -> Application { + let infoPath = url.appendingPathComponent("Contents/Info.plist") let propertyList = try infoPlistController.load(at: infoPath) let preferences = try preferencesController.load(propertyList) - let application = Application(path: path, + let application = Application(url: url, propertyList: propertyList, preferences: preferences) return application diff --git a/Sources/Controllers/SplitViewController.swift b/Sources/Controllers/SplitViewController.swift index d14896c..bfb4419 100644 --- a/Sources/Controllers/SplitViewController.swift +++ b/Sources/Controllers/SplitViewController.swift @@ -42,12 +42,28 @@ class SplitViewController: NSSplitViewController { verticalDividerLight.belongsToView = view self.view.addSubview(verticalDividerLight) - let label = Label() - label.textColor = NSColor.windowFrameTextColor - label.stringValue = viewController.title ?? "" - label.alignment = .center - label.belongsToView = view - self.view.addSubview(label) + if let containedViewController = viewController as? SplitViewContainedController { + containedViewController.titlebarView.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(containedViewController.titlebarView) + layoutConstraints.append(contentsOf: [ + containedViewController.titlebarView.topAnchor.constraint(equalTo: toolbarBackground.topAnchor), + containedViewController.titlebarView.leadingAnchor.constraint(equalTo: toolbarBackground.leadingAnchor), + containedViewController.titlebarView.trailingAnchor.constraint(equalTo: toolbarBackground.trailingAnchor), + containedViewController.titlebarView.bottomAnchor.constraint(equalTo: toolbarBackground.bottomAnchor) + ]) + } else { + let label = SmallLabel() + label.textColor = NSColor.windowFrameTextColor + label.stringValue = viewController.title ?? "" + label.alignment = .center + label.belongsToView = view + self.view.addSubview(label) + + layoutConstraints.append(contentsOf: [ + label.centerYAnchor.constraint(equalTo: toolbarBackground.centerYAnchor), + label.centerXAnchor.constraint(equalTo: toolbarBackground.centerXAnchor) + ]) + } layoutConstraints.append(contentsOf: [ toolbarBackground.topAnchor.constraint(equalTo: self.view.topAnchor), @@ -55,9 +71,6 @@ class SplitViewController: NSSplitViewController { toolbarBackground.trailingAnchor.constraint(equalTo: view.trailingAnchor), toolbarBackground.heightAnchor.constraint(equalToConstant: 38), - label.centerYAnchor.constraint(equalTo: toolbarBackground.centerYAnchor), - label.centerXAnchor.constraint(equalTo: toolbarBackground.centerXAnchor), - contentBackgroundView.topAnchor.constraint(equalTo: self.view.topAnchor), contentBackgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor), contentBackgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor), diff --git a/Sources/Controllers/ViewController.swift b/Sources/Controllers/ViewController.swift index 72dd843..74f1ab4 100644 --- a/Sources/Controllers/ViewController.swift +++ b/Sources/Controllers/ViewController.swift @@ -3,5 +3,6 @@ import Cocoa open class ViewController: NSViewController { open override func loadView() { view = NSView() + view.wantsLayer = true } } diff --git a/Sources/Factories/ViewControllerFactory.swift b/Sources/Factories/ViewControllerFactory.swift index e9c050a..61d2333 100644 --- a/Sources/Factories/ViewControllerFactory.swift +++ b/Sources/Factories/ViewControllerFactory.swift @@ -8,11 +8,17 @@ class ViewControllerFactory { } func createApplicationListViewController(with layout: NSCollectionViewFlowLayout) -> ApplicationItemViewController { - let listViewController = ApplicationItemViewController(layout: layout, iconStore: dependencyContainer) - listViewController.view.wantsLayer = true - listViewController.view.layer?.backgroundColor = NSColor.white.cgColor - listViewController.title = Bundle.main.infoDictionary?["CFBundleName"] as? String + let viewController = ApplicationItemViewController(layout: layout, iconStore: dependencyContainer) + viewController.view.wantsLayer = true + viewController.view.layer?.backgroundColor = NSColor.white.cgColor + viewController.title = Bundle.main.infoDictionary?["CFBundleName"] as? String - return listViewController + return viewController + } + + func createApplicationDetailViewController() -> ApplicationContainerViewController { + let detailViewController = ApplicationInfoViewController() + let containerViewController = ApplicationContainerViewController(detailViewController: detailViewController) + return containerViewController } } diff --git a/Sources/Factories/WindowFactory.swift b/Sources/Factories/WindowFactory.swift index 42a517a..6631652 100644 --- a/Sources/Factories/WindowFactory.swift +++ b/Sources/Factories/WindowFactory.swift @@ -31,25 +31,17 @@ class WindowFactory { sidebarItem.maximumThickness = sidebarItem.minimumThickness sidebarItem.canCollapse = true - let detailViewController = ViewController() + let detailViewController = viewControllerFactory.createApplicationDetailViewController() detailViewController.view.wantsLayer = true detailViewController.view.layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor detailViewController.title = "Customize" + detailViewController.listViewController = listViewController + listViewController.collectionView.delegate = detailViewController let detailControllerItem = NSSplitViewItem(viewController: detailViewController) detailControllerItem.minimumThickness = 320 detailControllerItem.canCollapse = false - let inspectorController = ViewController() - inspectorController.view.wantsLayer = true - inspectorController.view.layer?.backgroundColor = NSColor.white.cgColor - - let inspectorControllerItem = NSSplitViewItem(viewController: inspectorController) - inspectorControllerItem.holdingPriority = .init(rawValue: 260) - inspectorControllerItem.minimumThickness = 260 - inspectorControllerItem.maximumThickness = 260 - inspectorControllerItem.canCollapse = true - let windowController = WindowController(window: window, with: [sidebarItem, detailControllerItem]) diff --git a/Sources/Views/ApplicationView.swift b/Sources/Features/Application List/ApplicationView.swift similarity index 100% rename from Sources/Views/ApplicationView.swift rename to Sources/Features/Application List/ApplicationView.swift diff --git a/Sources/Features/ApplicationDetail/ApplicationActionsViewController.swift b/Sources/Features/ApplicationDetail/ApplicationActionsViewController.swift new file mode 100644 index 0000000..6a26746 --- /dev/null +++ b/Sources/Features/ApplicationDetail/ApplicationActionsViewController.swift @@ -0,0 +1,14 @@ +import Cocoa + +class ApplicationActionsViewController: ViewController { + private var layoutConstraints = [NSLayoutConstraint]() + + override func viewDidLoad() { + super.viewDidLoad() + view.subviews.forEach { $0.removeFromSuperview() } + + NSLayoutConstraint.deactivate(layoutConstraints) + layoutConstraints = [] + NSLayoutConstraint.activate(layoutConstraints) + } +} diff --git a/Sources/Features/ApplicationDetail/ApplicationContainerViewController.swift b/Sources/Features/ApplicationDetail/ApplicationContainerViewController.swift new file mode 100644 index 0000000..6dcd148 --- /dev/null +++ b/Sources/Features/ApplicationDetail/ApplicationContainerViewController.swift @@ -0,0 +1,74 @@ +import Cocoa +import Family + +class ApplicationContainerViewController: FamilyViewController, + SplitViewContainedController, NSCollectionViewDelegate { + weak var listViewController: ApplicationItemViewController? + + lazy var titleLabel = SmallBoldLabel() + lazy var titlebarView = NSView() + + private var layoutConstraints = [NSLayoutConstraint]() + + let applicationInfoViewController: ApplicationInfoViewController + + init(detailViewController: ApplicationInfoViewController) { + self.applicationInfoViewController = detailViewController + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - View lifecycle + + override func viewDidLoad() { + super.viewDidLoad() + addChild(applicationInfoViewController, + customInsets: .init(top: 15, left: 15, bottom: 15, right: 15), + height: 120) + addChild(ApplicationActionsViewController(), + customInsets: .init(top: 15, left: 105, bottom: 15, right: 105), + height: 20) + } + + // MARK: - Private methods + + private func render(_ application: Application) { + applicationInfoViewController.render(application) + NSLayoutConstraint.deactivate(layoutConstraints) + layoutConstraints = [] + + titlebarView.subviews.forEach { $0.removeFromSuperview() } + titleLabel.stringValue = application.propertyList.bundleName + titleLabel.alignment = .center + titleLabel.translatesAutoresizingMaskIntoConstraints = false + titlebarView.wantsLayer = true + titlebarView.addSubview(titleLabel) + + let button = NSButton(title: "Apply changes", target: nil, action: nil) + button.translatesAutoresizingMaskIntoConstraints = false + titlebarView.addSubview(button) + + layoutConstraints.append(contentsOf: [ + titleLabel.leadingAnchor.constraint(equalTo: titlebarView.leadingAnchor, constant: 10), + titleLabel.trailingAnchor.constraint(equalTo: titlebarView.trailingAnchor, constant: -10), + titleLabel.centerYAnchor.constraint(equalTo: titlebarView.centerYAnchor), + button.centerYAnchor.constraint(equalTo: titlebarView.centerYAnchor), + button.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor) + ]) + + NSLayoutConstraint.activate(layoutConstraints) + } + + // MARK: - NSCollectionViewDelegate + + func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set) { + guard let indexPath = indexPaths.first else { return } + guard let listViewController = listViewController else { return } + guard let application = listViewController.model(at: indexPath).data["model"] as? Application else { return } + + render(application) + } +} diff --git a/Sources/Features/ApplicationDetail/ApplicationInfoViewController.swift b/Sources/Features/ApplicationDetail/ApplicationInfoViewController.swift new file mode 100644 index 0000000..2dd0024 --- /dev/null +++ b/Sources/Features/ApplicationDetail/ApplicationInfoViewController.swift @@ -0,0 +1,59 @@ +import Cocoa + +class ApplicationInfoViewController: ViewController { + private var layoutConstraints = [NSLayoutConstraint]() + + lazy var stackView = NSStackView() + + func render(_ application: Application) { + view.subviews.forEach { $0.removeFromSuperview() } + stackView.subviews.forEach { $0.removeFromSuperview() } + NSLayoutConstraint.deactivate(layoutConstraints) + layoutConstraints = [] + + let iconView = NSImageView() + let image = NSWorkspace.shared.icon(forFile: application.url.path) + iconView.image = image + + let nameLabel = Label(text: application.propertyList.bundleName) + nameLabel.font = NSFont.boldSystemFont(ofSize: 32) + + let horizontalStackView = NSStackView() + horizontalStackView.orientation = .horizontal + horizontalStackView.addArrangedSubview(iconView) + horizontalStackView.addArrangedSubview(nameLabel) + + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.orientation = .vertical + stackView.alignment = .leading + stackView.distribution = .fillProportionally + stackView.addArrangedSubview(horizontalStackView) + + stackView.addArrangedSubview(createVerticalStackView(with: [ + BoldLabel(text: "Version:"), + Label(text: application.propertyList.versionString), + BoldLabel(text: "Bundle identifier:"), + Label(text: application.propertyList.bundleIdentifier)])) + + stackView.addArrangedSubview(createVerticalStackView(with: [BoldLabel(text: "Location:"), + Label(text: application.url.path)])) + view.addSubview(stackView) + layoutConstraints = [ + stackView.topAnchor.constraint(equalTo: view.topAnchor), + stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ] + NSLayoutConstraint.activate(layoutConstraints) + } + + func createVerticalStackView(with views: [NSView]) -> NSStackView { + let stackView = NSStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.orientation = .horizontal + stackView.alignment = .firstBaseline + stackView.spacing = 5 + views.forEach { stackView.addArrangedSubview($0) } + return stackView + } +} diff --git a/Sources/Features/BackupController.swift b/Sources/Features/Core/BackupController.swift similarity index 100% rename from Sources/Features/BackupController.swift rename to Sources/Features/Core/BackupController.swift diff --git a/Sources/Features/IconController.swift b/Sources/Features/Core/IconController.swift similarity index 100% rename from Sources/Features/IconController.swift rename to Sources/Features/Core/IconController.swift diff --git a/Sources/Features/SyncController.swift b/Sources/Features/Core/SyncController.swift similarity index 100% rename from Sources/Features/SyncController.swift rename to Sources/Features/Core/SyncController.swift diff --git a/Sources/Models/Application.swift b/Sources/Models/Application.swift index 9732dfe..f9a381a 100644 --- a/Sources/Models/Application.swift +++ b/Sources/Models/Application.swift @@ -1,7 +1,7 @@ import Foundation -struct Application { - let path: URL +struct Application: Hashable { + let url: URL let propertyList: InfoPropertyList let preferences: Preferences } diff --git a/Sources/Models/InfoPropertyList.swift b/Sources/Models/InfoPropertyList.swift index 1e0cfd1..403f4dc 100644 --- a/Sources/Models/InfoPropertyList.swift +++ b/Sources/Models/InfoPropertyList.swift @@ -1,6 +1,6 @@ import Foundation -enum InfoPropertyListKey: String { +enum InfoPropertyListKey: String, Hashable { case buildVersion = "CFBundleVersion" case bundleIdentifier = "CFBundleIdentifier" case bundleName = "CFBundleName" @@ -10,7 +10,7 @@ enum InfoPropertyListKey: String { case versionString = "CFBundleShortVersionString" } -struct InfoPropertyList { +struct InfoPropertyList: Hashable { let buildVersion: String let bundleIdentifier: String let bundleName: String diff --git a/Sources/Models/Preferences.swift b/Sources/Models/Preferences.swift index f7b7b4f..5425578 100644 --- a/Sources/Models/Preferences.swift +++ b/Sources/Models/Preferences.swift @@ -1,5 +1,5 @@ import Foundation -struct Preferences { +struct Preferences: Hashable { let path: URL } diff --git a/Sources/Protocols/SplitViewContainedController.swift b/Sources/Protocols/SplitViewContainedController.swift new file mode 100644 index 0000000..18b1909 --- /dev/null +++ b/Sources/Protocols/SplitViewContainedController.swift @@ -0,0 +1,5 @@ +import Cocoa + +protocol SplitViewContainedController { + var titlebarView: NSView { get } +} diff --git a/Sources/Views/Label.swift b/Sources/Views/Label.swift index ad8cd6c..bb91e8f 100644 --- a/Sources/Views/Label.swift +++ b/Sources/Views/Label.swift @@ -3,8 +3,14 @@ import Cocoa class Label: NSTextField, DecorationView { weak var belongsToView: NSView? + convenience init(text: String) { + self.init(frame: .zero) + stringValue = text + } + override init(frame frameRect: NSRect) { super.init(frame: frameRect) + font = NSFont.systemFont(ofSize: 15) translatesAutoresizingMaskIntoConstraints = false isBezeled = false isBordered = false @@ -17,3 +23,38 @@ class Label: NSTextField, DecorationView { fatalError("init(coder:) has not been implemented") } } + +class SmallLabel: Label { + + override init(frame frameRect: NSRect) { + super.init(frame: frameRect) + font = NSFont.systemFont(ofSize: 13) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +class SmallBoldLabel: Label { + + override init(frame frameRect: NSRect) { + super.init(frame: frameRect) + font = NSFont.boldSystemFont(ofSize: 13) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +class BoldLabel: Label { + override init(frame frameRect: NSRect) { + super.init(frame: frameRect) + font = NSFont.boldSystemFont(ofSize: font?.pointSize ?? 13) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Sources/Views/MainWindow.swift b/Sources/Views/MainWindow.swift index a88de97..309260f 100644 --- a/Sources/Views/MainWindow.swift +++ b/Sources/Views/MainWindow.swift @@ -2,7 +2,7 @@ import Cocoa class MainWindow: NSWindow { func loadWindow() { - let windowSize = CGSize(width: 650, height: 480) + let windowSize = CGSize(width: 680, height: 480) styleMask = [ .closable, .miniaturizable, .resizable, .titled, .fullSizeContentView ] diff --git a/Syncalicious.xcodeproj/project.pbxproj b/Syncalicious.xcodeproj/project.pbxproj index e4905e7..e48fae9 100644 --- a/Syncalicious.xcodeproj/project.pbxproj +++ b/Syncalicious.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 315E2FCDA36B3A59799011D2 /* libPods-Syncalicious.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E8791082ED91FA1B97EC440 /* libPods-Syncalicious.a */; }; + A47DC085643951080DBAE4EF /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F2371A240BEC8532FF8BBC27 /* libPods-Tests.a */; }; BD084B722258D92D00E91A7F /* SyncController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD084B712258D92D00E91A7F /* SyncController.swift */; }; BD084B742258DA7800E91A7F /* SyncControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD084B732258DA7800E91A7F /* SyncControllerTests.swift */; }; BD084B772258E07C00E91A7F /* TestApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD084B762258E07C00E91A7F /* TestApplicationDelegate.swift */; }; @@ -51,6 +53,10 @@ BDDAA33E225DB56B00D87664 /* WindowFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDAA33D225DB56B00D87664 /* WindowFactory.swift */; }; BDDAA340225DB57500D87664 /* ViewControllerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDAA33F225DB57500D87664 /* ViewControllerFactory.swift */; }; BDDAA342225DB79300D87664 /* CollectionViewLayoutFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDAA341225DB79300D87664 /* CollectionViewLayoutFactory.swift */; }; + BDDAA347225DC89F00D87664 /* ApplicationInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDAA346225DC89F00D87664 /* ApplicationInfoViewController.swift */; }; + BDDAA34D225E460100D87664 /* SplitViewContainedController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDAA34C225E460100D87664 /* SplitViewContainedController.swift */; }; + BDDAA34F225E52DA00D87664 /* ApplicationContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDAA34E225E52DA00D87664 /* ApplicationContainerViewController.swift */; }; + BDDAD908225E671F007D694F /* ApplicationActionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDAD907225E671F007D694F /* ApplicationActionsViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -64,6 +70,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0D524E3138AC0B59B67FF0DD /* Pods-Syncalicious.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Syncalicious.debug.xcconfig"; path = "Target Support Files/Pods-Syncalicious/Pods-Syncalicious.debug.xcconfig"; sourceTree = ""; }; + 8D3875EE15B4C6FB1AFB28CF /* Pods-Syncalicious.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Syncalicious.release.xcconfig"; path = "Target Support Files/Pods-Syncalicious/Pods-Syncalicious.release.xcconfig"; sourceTree = ""; }; + 9E8791082ED91FA1B97EC440 /* libPods-Syncalicious.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Syncalicious.a"; sourceTree = BUILT_PRODUCTS_DIR; }; BD084B712258D92D00E91A7F /* SyncController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncController.swift; sourceTree = ""; }; BD084B732258DA7800E91A7F /* SyncControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncControllerTests.swift; sourceTree = ""; }; BD084B762258E07C00E91A7F /* TestApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestApplicationDelegate.swift; sourceTree = ""; }; @@ -120,6 +129,13 @@ BDDAA33D225DB56B00D87664 /* WindowFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowFactory.swift; sourceTree = ""; }; BDDAA33F225DB57500D87664 /* ViewControllerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerFactory.swift; sourceTree = ""; }; BDDAA341225DB79300D87664 /* CollectionViewLayoutFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewLayoutFactory.swift; sourceTree = ""; }; + BDDAA346225DC89F00D87664 /* ApplicationInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationInfoViewController.swift; sourceTree = ""; }; + BDDAA34C225E460100D87664 /* SplitViewContainedController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewContainedController.swift; sourceTree = ""; }; + BDDAA34E225E52DA00D87664 /* ApplicationContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationContainerViewController.swift; sourceTree = ""; }; + BDDAD907225E671F007D694F /* ApplicationActionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationActionsViewController.swift; sourceTree = ""; }; + D6AB979C990CE4B2663D292E /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = ""; }; + F2371A240BEC8532FF8BBC27 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F9C19719F2BC6AF42A7CB265 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -127,6 +143,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 315E2FCDA36B3A59799011D2 /* libPods-Syncalicious.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -134,12 +151,33 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + A47DC085643951080DBAE4EF /* libPods-Tests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 3650F35871850161786D5AC3 /* Pods */ = { + isa = PBXGroup; + children = ( + 0D524E3138AC0B59B67FF0DD /* Pods-Syncalicious.debug.xcconfig */, + 8D3875EE15B4C6FB1AFB28CF /* Pods-Syncalicious.release.xcconfig */, + D6AB979C990CE4B2663D292E /* Pods-Tests.debug.xcconfig */, + F9C19719F2BC6AF42A7CB265 /* Pods-Tests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 7C856D046EFDDAA5C3AD5549 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9E8791082ED91FA1B97EC440 /* libPods-Syncalicious.a */, + F2371A240BEC8532FF8BBC27 /* libPods-Tests.a */, + ); + name = Frameworks; + sourceTree = ""; + }; BD084B752258E06E00E91A7F /* Helpers */ = { isa = PBXGroup; children = ( @@ -153,7 +191,6 @@ BD4A69382253DCF100F588AD /* Views */ = { isa = PBXGroup; children = ( - BD8EDD7D22553ADD00110E56 /* ApplicationView.swift */, BDDAA336225D37D100D87664 /* BackgroundView.swift */, BDDAA338225D37DE00D87664 /* DividerView.swift */, BDDAA33A225D383400D87664 /* Label.swift */, @@ -216,9 +253,9 @@ BD7D961A22532B5900C93211 /* Features */ = { isa = PBXGroup; children = ( - BD7D961B22532B6900C93211 /* BackupController.swift */, - BD8EDD812255CE3400110E56 /* IconController.swift */, - BD084B712258D92D00E91A7F /* SyncController.swift */, + BDDAA345225DC88F00D87664 /* ApplicationDetail */, + BDDAA344225DC87300D87664 /* Application List */, + BDDAA343225DC86200D87664 /* Core */, ); path = Features; sourceTree = ""; @@ -272,6 +309,7 @@ children = ( BD8EDD882255CF7500110E56 /* Component.swift */, BDDAA334225D37C700D87664 /* DecorationView.swift */, + BDDAA34C225E460100D87664 /* SplitViewContainedController.swift */, ); path = Protocols; sourceTree = ""; @@ -290,6 +328,8 @@ BD9313852251703400D116E4 /* Sources */, BDCBB2A922551372007C9404 /* Tests */, BD8EDD73225538D400110E56 /* Sourcery */, + 3650F35871850161786D5AC3 /* Pods */, + 7C856D046EFDDAA5C3AD5549 /* Frameworks */, ); sourceTree = ""; }; @@ -338,6 +378,34 @@ path = Factories; sourceTree = ""; }; + BDDAA343225DC86200D87664 /* Core */ = { + isa = PBXGroup; + children = ( + BD7D961B22532B6900C93211 /* BackupController.swift */, + BD8EDD812255CE3400110E56 /* IconController.swift */, + BD084B712258D92D00E91A7F /* SyncController.swift */, + ); + path = Core; + sourceTree = ""; + }; + BDDAA344225DC87300D87664 /* Application List */ = { + isa = PBXGroup; + children = ( + BD8EDD7D22553ADD00110E56 /* ApplicationView.swift */, + ); + path = "Application List"; + sourceTree = ""; + }; + BDDAA345225DC88F00D87664 /* ApplicationDetail */ = { + isa = PBXGroup; + children = ( + BDDAA346225DC89F00D87664 /* ApplicationInfoViewController.swift */, + BDDAA34E225E52DA00D87664 /* ApplicationContainerViewController.swift */, + BDDAD907225E671F007D694F /* ApplicationActionsViewController.swift */, + ); + path = ApplicationDetail; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -345,6 +413,7 @@ isa = PBXNativeTarget; buildConfigurationList = BD9313912251703700D116E4 /* Build configuration list for PBXNativeTarget "Syncalicious" */; buildPhases = ( + 98646FDFCCE7B4C815986960 /* [CP] Check Pods Manifest.lock */, BD93137F2251703400D116E4 /* Sources */, BD9313802251703400D116E4 /* Frameworks */, BD9313812251703400D116E4 /* Resources */, @@ -363,6 +432,7 @@ isa = PBXNativeTarget; buildConfigurationList = BDCBB2B122551372007C9404 /* Build configuration list for PBXNativeTarget "Tests" */; buildPhases = ( + F1632E0DF195D6AA3BF584DC /* [CP] Check Pods Manifest.lock */, BDCBB2A422551372007C9404 /* Sources */, BDCBB2A522551372007C9404 /* Frameworks */, BDCBB2A622551372007C9404 /* Resources */, @@ -393,6 +463,9 @@ com.apple.Sandbox = { enabled = 0; }; + com.apple.iCloud = { + enabled = 0; + }; }; }; BDCBB2A722551372007C9404 = { @@ -441,6 +514,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 98646FDFCCE7B4C815986960 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Syncalicious-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; BDCBB2B5225516F1007C9404 /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -459,6 +554,28 @@ shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; + F1632E0DF195D6AA3BF584DC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Tests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -479,8 +596,10 @@ BDDAA337225D37D100D87664 /* BackgroundView.swift in Sources */, BD4A693A2253DCF300F588AD /* MainWindow.swift in Sources */, BD8EDD822255CE3400110E56 /* IconController.swift in Sources */, + BDDAA34F225E52DA00D87664 /* ApplicationContainerViewController.swift in Sources */, BD3CC250225B147F006D7877 /* SplitViewController.swift in Sources */, BDDAA33B225D383400D87664 /* Label.swift in Sources */, + BDDAD908225E671F007D694F /* ApplicationActionsViewController.swift in Sources */, BD084B722258D92D00E91A7F /* SyncController.swift in Sources */, BD4A69312253BADE00F588AD /* MachineController.swift in Sources */, BD4A6941225406A300F588AD /* ViewController.swift in Sources */, @@ -488,10 +607,12 @@ BD7D960E2252888000C93211 /* Application.swift in Sources */, BDDAA335225D37C700D87664 /* DecorationView.swift in Sources */, BD7D962122533CE100C93211 /* DependencyContainer.swift in Sources */, + BDDAA34D225E460100D87664 /* SplitViewContainedController.swift in Sources */, BD3CC24E225B1463006D7877 /* WindowController.swift in Sources */, BDDAA339225D37DE00D87664 /* DividerView.swift in Sources */, BD895C01225A67C200DEC9FE /* PrototypeItem.swift in Sources */, BD7D960C2252849100C93211 /* ApplicationController.swift in Sources */, + BDDAA347225DC89F00D87664 /* ApplicationInfoViewController.swift in Sources */, BDDAA342225DB79300D87664 /* CollectionViewLayoutFactory.swift in Sources */, BD8EDD892255CF7500110E56 /* Component.swift in Sources */, BD8EDD7A22553A5A00110E56 /* CollectionViewItemComponent.swift in Sources */, @@ -664,6 +785,7 @@ }; BD9313922251703700D116E4 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 0D524E3138AC0B59B67FF0DD /* Pods-Syncalicious.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; @@ -682,6 +804,7 @@ }; BD9313932251703700D116E4 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 8D3875EE15B4C6FB1AFB28CF /* Pods-Syncalicious.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; @@ -700,6 +823,7 @@ }; BDCBB2AF22551372007C9404 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D6AB979C990CE4B2663D292E /* Pods-Tests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_IDENTITY = "-"; @@ -720,6 +844,7 @@ }; BDCBB2B022551372007C9404 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F9C19719F2BC6AF42A7CB265 /* Pods-Tests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_IDENTITY = "-"; diff --git a/Syncalicious.xcworkspace/contents.xcworkspacedata b/Syncalicious.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..5e72f4f --- /dev/null +++ b/Syncalicious.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Syncalicious.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Syncalicious.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Syncalicious.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + +