Possible SwiftUI migration
|
|
@ -3,376 +3,399 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 46;
|
objectVersion = 55;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
C9188EE01CD65DCB00F0F8B6 /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */; };
|
C982F859283B9F9000D491F4 /* SimDirsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F858283B9F9000D491F4 /* SimDirsApp.swift */; };
|
||||||
C921B3C71CD6219F0091C1AD /* DetailController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3C51CD6219F0091C1AD /* DetailController.swift */; };
|
C982F85B283B9F9000D491F4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F85A283B9F9000D491F4 /* ContentView.swift */; };
|
||||||
C921B3CA1CD629180091C1AD /* DetailTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3C91CD629180091C1AD /* DetailTableView.swift */; };
|
C982F85D283B9F9200D491F4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C982F85C283B9F9200D491F4 /* Assets.xcassets */; };
|
||||||
C921B3CC1CD63EF30091C1AD /* ActionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3CB1CD63EF30091C1AD /* ActionCell.swift */; };
|
C982F860283B9F9200D491F4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */; };
|
||||||
C948814E1CD3EA5500209C09 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C948814D1CD3EA5500209C09 /* AppDelegate.swift */; };
|
C982F86B283BA22100D491F4 /* SimPlatform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F86A283BA22100D491F4 /* SimPlatform.swift */; };
|
||||||
C94881501CD3EA5500209C09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C948814F1CD3EA5500209C09 /* Assets.xcassets */; };
|
C982F871283CE7B800D491F4 /* SimRuntime.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F870283CE7B800D491F4 /* SimRuntime.swift */; };
|
||||||
C9AE594A1CD4EAD80090655C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9AE59481CD4EAD80090655C /* Main.storyboard */; };
|
C982F873283CE9AD00D491F4 /* SimDeviceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F872283CE9AD00D491F4 /* SimDeviceType.swift */; };
|
||||||
C9AE594C1CD4F1C70090655C /* SourceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9AE594B1CD4F1C70090655C /* SourceController.swift */; };
|
C982F875283CEEBB00D491F4 /* SimDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F874283CEEBB00D491F4 /* SimDevice.swift */; };
|
||||||
C9ECF8A41CD4CEE300499965 /* SimPlatform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */; };
|
C982F877283D020C00D491F4 /* SimProductFamily.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F876283D020C00D491F4 /* SimProductFamily.swift */; };
|
||||||
C9ECF8A61CD4CF1600499965 /* SimOSVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */; };
|
C982F879283D042E00D491F4 /* SimModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F878283D042E00D491F4 /* SimModel.swift */; };
|
||||||
C9ECF8A81CD4CF4000499965 /* SimDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A71CD4CF4000499965 /* SimDevice.swift */; };
|
C982F87B283E40C800D491F4 /* SimCtl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87A283E40C800D491F4 /* SimCtl.swift */; };
|
||||||
C9ECF8AA1CD4CF5A00499965 /* SimApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A91CD4CF5A00499965 /* SimApp.swift */; };
|
C982F87E283E57B200D491F4 /* PresentableModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87D283E57B200D491F4 /* PresentableModel.swift */; };
|
||||||
C9ECF8AC1CD4CF8400499965 /* Support.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8AB1CD4CF8400499965 /* Support.swift */; };
|
C982F880283E57E600D491F4 /* PresentationItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87F283E57E600D491F4 /* PresentationItem.swift */; };
|
||||||
C9ECF8B21CD4E26300499965 /* CoreUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9ECF8B11CD4E26300499965 /* CoreUI.framework */; };
|
C982F883283E813F00D491F4 /* DeviceTypeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F882283E813F00D491F4 /* DeviceTypeView.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; };
|
C982F855283B9F9000D491F4 /* SimDirs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimDirs.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
C921B3C51CD6219F0091C1AD /* DetailController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailController.swift; sourceTree = "<group>"; };
|
C982F858283B9F9000D491F4 /* SimDirsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDirsApp.swift; sourceTree = "<group>"; };
|
||||||
C921B3C91CD629180091C1AD /* DetailTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailTableView.swift; sourceTree = "<group>"; };
|
C982F85A283B9F9000D491F4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||||
C921B3CB1CD63EF30091C1AD /* ActionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionCell.swift; sourceTree = "<group>"; };
|
C982F85C283B9F9200D491F4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
C948814B1CD3EA5500209C09 /* SimDirs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimDirs.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
C948814D1CD3EA5500209C09 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
C982F861283B9F9200D491F4 /* SimDirs.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SimDirs.entitlements; sourceTree = "<group>"; };
|
||||||
C948814F1CD3EA5500209C09 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
C982F86A283BA22100D491F4 /* SimPlatform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimPlatform.swift; sourceTree = "<group>"; };
|
||||||
C94881541CD3EA5500209C09 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
C982F870283CE7B800D491F4 /* SimRuntime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimRuntime.swift; sourceTree = "<group>"; };
|
||||||
C9AE59491CD4EAD80090655C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
C982F872283CE9AD00D491F4 /* SimDeviceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDeviceType.swift; sourceTree = "<group>"; };
|
||||||
C9AE594B1CD4F1C70090655C /* SourceController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceController.swift; sourceTree = "<group>"; };
|
C982F874283CEEBB00D491F4 /* SimDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDevice.swift; sourceTree = "<group>"; };
|
||||||
C9AE594D1CD503850090655C /* CUINamedLayerStack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUINamedLayerStack.h; sourceTree = "<group>"; };
|
C982F876283D020C00D491F4 /* SimProductFamily.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimProductFamily.swift; sourceTree = "<group>"; };
|
||||||
C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimPlatform.swift; sourceTree = "<group>"; };
|
C982F878283D042E00D491F4 /* SimModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimModel.swift; sourceTree = "<group>"; };
|
||||||
C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimOSVersion.swift; sourceTree = "<group>"; };
|
C982F87A283E40C800D491F4 /* SimCtl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimCtl.swift; sourceTree = "<group>"; };
|
||||||
C9ECF8A71CD4CF4000499965 /* SimDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimDevice.swift; sourceTree = "<group>"; };
|
C982F87D283E57B200D491F4 /* PresentableModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentableModel.swift; sourceTree = "<group>"; };
|
||||||
C9ECF8A91CD4CF5A00499965 /* SimApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimApp.swift; sourceTree = "<group>"; };
|
C982F87F283E57E600D491F4 /* PresentationItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationItem.swift; sourceTree = "<group>"; };
|
||||||
C9ECF8AB1CD4CF8400499965 /* Support.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Support.swift; sourceTree = "<group>"; };
|
C982F882283E813F00D491F4 /* DeviceTypeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceTypeView.swift; sourceTree = "<group>"; };
|
||||||
C9ECF8AF1CD4E13500499965 /* CUICatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUICatalog.h; sourceTree = "<group>"; };
|
|
||||||
C9ECF8B01CD4E14C00499965 /* SimDirs-Bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SimDirs-Bridge.h"; sourceTree = "<group>"; };
|
|
||||||
C9ECF8B11CD4E26300499965 /* CoreUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreUI.framework; path = /System/Library/PrivateFrameworks/CoreUI.framework; sourceTree = "<absolute>"; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
C94881481CD3EA5500209C09 /* Frameworks */ = {
|
C982F852283B9F9000D491F4 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
C9ECF8B21CD4E26300499965 /* CoreUI.framework in Frameworks */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
C9194D1C19C09A03004178EB = {
|
C982F84C283B9F9000D491F4 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C948814C1CD3EA5500209C09 /* SimDirs */,
|
C982F857283B9F9000D491F4 /* SimDirs */,
|
||||||
C9ECF8B31CD4E27B00499965 /* Frameworks */,
|
C982F856283B9F9000D491F4 /* Products */,
|
||||||
C9194D2619C09A03004178EB /* Products */,
|
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C9194D2619C09A03004178EB /* Products */ = {
|
C982F856283B9F9000D491F4 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C948814B1CD3EA5500209C09 /* SimDirs.app */,
|
C982F855283B9F9000D491F4 /* SimDirs.app */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C948814C1CD3EA5500209C09 /* SimDirs */ = {
|
C982F857283B9F9000D491F4 /* SimDirs */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C9ECF8A21CD4CEC800499965 /* Model */,
|
C982F858283B9F9000D491F4 /* SimDirsApp.swift */,
|
||||||
C9ECF8AE1CD4E13500499965 /* Support */,
|
C982F85A283B9F9000D491F4 /* ContentView.swift */,
|
||||||
C9ECF8B41CD4E96A00499965 /* UI */,
|
C982F867283BA09B00D491F4 /* Model */,
|
||||||
C948814D1CD3EA5500209C09 /* AppDelegate.swift */,
|
C982F881283E7F0400D491F4 /* Views */,
|
||||||
C9ECF8AB1CD4CF8400499965 /* Support.swift */,
|
C982F85C283B9F9200D491F4 /* Assets.xcassets */,
|
||||||
C948814F1CD3EA5500209C09 /* Assets.xcassets */,
|
C982F861283B9F9200D491F4 /* SimDirs.entitlements */,
|
||||||
C9AE59481CD4EAD80090655C /* Main.storyboard */,
|
C982F85E283B9F9200D491F4 /* Preview Content */,
|
||||||
C94881541CD3EA5500209C09 /* Info.plist */,
|
|
||||||
);
|
);
|
||||||
path = SimDirs;
|
path = SimDirs;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C9ECF8A21CD4CEC800499965 /* Model */ = {
|
C982F85E283B9F9200D491F4 /* Preview Content */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C9ECF8A91CD4CF5A00499965 /* SimApp.swift */,
|
C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */,
|
||||||
C9ECF8A71CD4CF4000499965 /* SimDevice.swift */,
|
);
|
||||||
C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */,
|
path = "Preview Content";
|
||||||
C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */,
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
C982F867283BA09B00D491F4 /* Model */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C982F87C283E579900D491F4 /* Presentation */,
|
||||||
|
C982F87A283E40C800D491F4 /* SimCtl.swift */,
|
||||||
|
C982F878283D042E00D491F4 /* SimModel.swift */,
|
||||||
|
C982F874283CEEBB00D491F4 /* SimDevice.swift */,
|
||||||
|
C982F872283CE9AD00D491F4 /* SimDeviceType.swift */,
|
||||||
|
C982F86A283BA22100D491F4 /* SimPlatform.swift */,
|
||||||
|
C982F876283D020C00D491F4 /* SimProductFamily.swift */,
|
||||||
|
C982F870283CE7B800D491F4 /* SimRuntime.swift */,
|
||||||
);
|
);
|
||||||
path = Model;
|
path = Model;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C9ECF8AE1CD4E13500499965 /* Support */ = {
|
C982F87C283E579900D491F4 /* Presentation */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C9ECF8AF1CD4E13500499965 /* CUICatalog.h */,
|
C982F87D283E57B200D491F4 /* PresentableModel.swift */,
|
||||||
C9AE594D1CD503850090655C /* CUINamedLayerStack.h */,
|
C982F87F283E57E600D491F4 /* PresentationItem.swift */,
|
||||||
C9ECF8B01CD4E14C00499965 /* SimDirs-Bridge.h */,
|
|
||||||
);
|
);
|
||||||
path = Support;
|
path = Presentation;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C9ECF8B31CD4E27B00499965 /* Frameworks */ = {
|
C982F881283E7F0400D491F4 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C9ECF8B11CD4E26300499965 /* CoreUI.framework */,
|
C982F882283E813F00D491F4 /* DeviceTypeView.swift */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
C9ECF8B41CD4E96A00499965 /* UI */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
C921B3CB1CD63EF30091C1AD /* ActionCell.swift */,
|
|
||||||
C921B3C51CD6219F0091C1AD /* DetailController.swift */,
|
|
||||||
C921B3C91CD629180091C1AD /* DetailTableView.swift */,
|
|
||||||
C9AE594B1CD4F1C70090655C /* SourceController.swift */,
|
|
||||||
C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */,
|
|
||||||
);
|
|
||||||
path = UI;
|
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
C948814A1CD3EA5500209C09 /* SimDirs */ = {
|
C982F854283B9F9000D491F4 /* SimDirs */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = C94881571CD3EA5500209C09 /* Build configuration list for PBXNativeTarget "SimDirs" */;
|
buildConfigurationList = C982F864283B9F9200D491F4 /* Build configuration list for PBXNativeTarget "SimDirs" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
C94881471CD3EA5500209C09 /* Sources */,
|
C982F851283B9F9000D491F4 /* Sources */,
|
||||||
C94881481CD3EA5500209C09 /* Frameworks */,
|
C982F852283B9F9000D491F4 /* Frameworks */,
|
||||||
C94881491CD3EA5500209C09 /* Resources */,
|
C982F853283B9F9000D491F4 /* Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
name = SimDirs;
|
name = SimDirs;
|
||||||
productName = SimDirs2;
|
productName = SimDirs;
|
||||||
productReference = C948814B1CD3EA5500209C09 /* SimDirs.app */;
|
productReference = C982F855283B9F9000D491F4 /* SimDirs.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
/* Begin PBXProject section */
|
||||||
C9194D1D19C09A03004178EB /* Project object */ = {
|
C982F84D283B9F9000D491F4 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 0730;
|
BuildIndependentTargetsInParallel = 1;
|
||||||
LastUpgradeCheck = 0600;
|
LastSwiftUpdateCheck = 1340;
|
||||||
ORGANIZATIONNAME = "Quiet Spark";
|
LastUpgradeCheck = 1340;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
C948814A1CD3EA5500209C09 = {
|
C982F854283B9F9000D491F4 = {
|
||||||
CreatedOnToolsVersion = 7.3;
|
CreatedOnToolsVersion = 13.4;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = C9194D2019C09A03004178EB /* Build configuration list for PBXProject "SimDirs" */;
|
buildConfigurationList = C982F850283B9F9000D491F4 /* Build configuration list for PBXProject "SimDirs" */;
|
||||||
compatibilityVersion = "Xcode 3.2";
|
compatibilityVersion = "Xcode 13.0";
|
||||||
developmentRegion = English;
|
developmentRegion = en;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
knownRegions = (
|
knownRegions = (
|
||||||
English,
|
|
||||||
en,
|
en,
|
||||||
Base,
|
Base,
|
||||||
);
|
);
|
||||||
mainGroup = C9194D1C19C09A03004178EB;
|
mainGroup = C982F84C283B9F9000D491F4;
|
||||||
productRefGroup = C9194D2619C09A03004178EB /* Products */;
|
productRefGroup = C982F856283B9F9000D491F4 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
C948814A1CD3EA5500209C09 /* SimDirs */,
|
C982F854283B9F9000D491F4 /* SimDirs */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
C94881491CD3EA5500209C09 /* Resources */ = {
|
C982F853283B9F9000D491F4 /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
C9AE594A1CD4EAD80090655C /* Main.storyboard in Resources */,
|
C982F860283B9F9200D491F4 /* Preview Assets.xcassets in Resources */,
|
||||||
C94881501CD3EA5500209C09 /* Assets.xcassets in Resources */,
|
C982F85D283B9F9200D491F4 /* Assets.xcassets in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
C94881471CD3EA5500209C09 /* Sources */ = {
|
C982F851283B9F9000D491F4 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
C921B3C71CD6219F0091C1AD /* DetailController.swift in Sources */,
|
C982F883283E813F00D491F4 /* DeviceTypeView.swift in Sources */,
|
||||||
C921B3CC1CD63EF30091C1AD /* ActionCell.swift in Sources */,
|
C982F85B283B9F9000D491F4 /* ContentView.swift in Sources */,
|
||||||
C9ECF8A41CD4CEE300499965 /* SimPlatform.swift in Sources */,
|
C982F875283CEEBB00D491F4 /* SimDevice.swift in Sources */,
|
||||||
C9ECF8A61CD4CF1600499965 /* SimOSVersion.swift in Sources */,
|
C982F873283CE9AD00D491F4 /* SimDeviceType.swift in Sources */,
|
||||||
C921B3CA1CD629180091C1AD /* DetailTableView.swift in Sources */,
|
C982F877283D020C00D491F4 /* SimProductFamily.swift in Sources */,
|
||||||
C9AE594C1CD4F1C70090655C /* SourceController.swift in Sources */,
|
C982F859283B9F9000D491F4 /* SimDirsApp.swift in Sources */,
|
||||||
C9ECF8AA1CD4CF5A00499965 /* SimApp.swift in Sources */,
|
C982F871283CE7B800D491F4 /* SimRuntime.swift in Sources */,
|
||||||
C9188EE01CD65DCB00F0F8B6 /* WindowController.swift in Sources */,
|
C982F86B283BA22100D491F4 /* SimPlatform.swift in Sources */,
|
||||||
C948814E1CD3EA5500209C09 /* AppDelegate.swift in Sources */,
|
C982F87E283E57B200D491F4 /* PresentableModel.swift in Sources */,
|
||||||
C9ECF8A81CD4CF4000499965 /* SimDevice.swift in Sources */,
|
C982F880283E57E600D491F4 /* PresentationItem.swift in Sources */,
|
||||||
C9ECF8AC1CD4CF8400499965 /* Support.swift in Sources */,
|
C982F879283D042E00D491F4 /* SimModel.swift in Sources */,
|
||||||
|
C982F87B283E40C800D491F4 /* SimCtl.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
|
||||||
C9AE59481CD4EAD80090655C /* Main.storyboard */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
C9AE59491CD4EAD80090655C /* Base */,
|
|
||||||
);
|
|
||||||
name = Main.storyboard;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXVariantGroup section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
C9194D4019C09A03004178EB /* Debug */ = {
|
C982F862283B9F9200D491F4 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "-";
|
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
);
|
);
|
||||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
MACOSX_DEPLOYMENT_TARGET = 12.3;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
C9194D4119C09A03004178EB /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "-";
|
|
||||||
COPY_PHASE_STRIP = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
|
||||||
SDKROOT = macosx;
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
C94881551CD3EA5500209C09 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
||||||
ENABLE_TESTABILITY = YES;
|
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
|
|
||||||
);
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
|
||||||
INFOPLIST_FILE = "$(SRCROOT)/SimDirs/Info.plist";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.quietspark.SimDirs;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "SimDirs/Support/SimDirs-Bridge.h";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
C94881561CD3EA5500209C09 /* Release */ = {
|
C982F863283B9F9200D491F4 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 12.3;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
C982F865283B9F9200D491F4 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = SimDirs/SimDirs.entitlements;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
DEVELOPMENT_ASSET_PATHS = "\"SimDirs/Preview Content\"";
|
||||||
|
ENABLE_PREVIEWS = YES;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
MARKETING_VERSION = 1.0;
|
||||||
INFOPLIST_FILE = "$(SRCROOT)/SimDirs/Info.plist";
|
PRODUCT_BUNDLE_IDENTIFIER = com.sgntn.SimDirs;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.quietspark.SimDirs;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "SimDirs/Support/SimDirs-Bridge.h";
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
C982F866283B9F9200D491F4 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = SimDirs/SimDirs.entitlements;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_ASSET_PATHS = "\"SimDirs/Preview Content\"";
|
||||||
|
ENABLE_PREVIEWS = YES;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.sgntn.SimDirs;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
C9194D2019C09A03004178EB /* Build configuration list for PBXProject "SimDirs" */ = {
|
C982F850283B9F9000D491F4 /* Build configuration list for PBXProject "SimDirs" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
C9194D4019C09A03004178EB /* Debug */,
|
C982F862283B9F9200D491F4 /* Debug */,
|
||||||
C9194D4119C09A03004178EB /* Release */,
|
C982F863283B9F9200D491F4 /* Release */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
C94881571CD3EA5500209C09 /* Build configuration list for PBXNativeTarget "SimDirs" */ = {
|
C982F864283B9F9200D491F4 /* Build configuration list for PBXNativeTarget "SimDirs" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
C94881551CD3EA5500209C09 /* Debug */,
|
C982F865283B9F9200D491F4 /* Debug */,
|
||||||
C94881561CD3EA5500209C09 /* Release */,
|
C982F866283B9F9200D491F4 /* Release */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
rootObject = C9194D1D19C09A03004178EB /* Project object */;
|
rootObject = C982F84D283B9F9000D491F4 /* Project object */;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@
|
||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "self:SimDirs.xcodeproj">
|
location = "self:">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
//
|
|
||||||
// AppDelegate.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 4/29/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
|
|
||||||
@NSApplicationMain
|
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
|
||||||
func applicationDidFinishLaunching(aNotification: NSNotification) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
11
SimDirs/Assets.xcassets/AccentColor.colorset/Contents.json
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,68 +1,58 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"size" : "16x16",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_16x16.png",
|
"scale" : "1x",
|
||||||
"scale" : "1x"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "16x16",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_16x16@2x.png",
|
"scale" : "2x",
|
||||||
"scale" : "2x"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "32x32",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_32x32.png",
|
"scale" : "1x",
|
||||||
"scale" : "1x"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "32x32",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_32x32@2x.png",
|
"scale" : "2x",
|
||||||
"scale" : "2x"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "128x128",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_128x128.png",
|
"scale" : "1x",
|
||||||
"scale" : "1x"
|
"size" : "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "128x128",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_128x128@2x.png",
|
"scale" : "2x",
|
||||||
"scale" : "2x"
|
"size" : "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "256x256",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_256x256.png",
|
"scale" : "1x",
|
||||||
"scale" : "1x"
|
"size" : "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "256x256",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_256x256@2x.png",
|
"scale" : "2x",
|
||||||
"scale" : "2x"
|
"size" : "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "512x512",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_512x512.png",
|
"scale" : "1x",
|
||||||
"scale" : "1x"
|
"size" : "512x512"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "512x512",
|
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon_512x512@2x.png",
|
"scale" : "2x",
|
||||||
"scale" : "2x"
|
"size" : "512x512"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 534 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 438 KiB |
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "default_icon.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "defaultt_icon@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
|
@ -1,488 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="macosx"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
|
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
|
||||||
</dependencies>
|
|
||||||
<scenes>
|
|
||||||
<!--Application-->
|
|
||||||
<scene sceneID="JPo-4y-FX3">
|
|
||||||
<objects>
|
|
||||||
<application id="hnw-xV-0zn" sceneMemberID="viewController">
|
|
||||||
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
|
||||||
<items>
|
|
||||||
<menuItem title="SimDirs" id="1Xt-HY-uBw">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="SimDirs" systemMenu="apple" id="uQy-DD-JDr">
|
|
||||||
<items>
|
|
||||||
<menuItem title="About SimDirs" id="5kV-Vb-QxS">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
|
||||||
<menuItem title="Services" id="NMo-om-nkz">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
|
||||||
<menuItem title="Hide SimDirs" keyEquivalent="h" id="Olw-nP-bQN">
|
|
||||||
<connections>
|
|
||||||
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
|
||||||
<menuItem title="Quit SimDirs" keyEquivalent="q" id="4sb-4s-VLi">
|
|
||||||
<connections>
|
|
||||||
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="File" id="dMs-cI-mzQ">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
|
||||||
<connections>
|
|
||||||
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Format" id="jxT-CU-nIS">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="View" id="H8h-7b-M4v">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Window" id="aUF-d1-5bR">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
|
||||||
<connections>
|
|
||||||
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
|
||||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
|
|
||||||
</connections>
|
|
||||||
</application>
|
|
||||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="SimDirs" customModuleProvider="target"/>
|
|
||||||
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="75" y="0.0"/>
|
|
||||||
</scene>
|
|
||||||
<!--Window Controller-->
|
|
||||||
<scene sceneID="R2V-B0-nI4">
|
|
||||||
<objects>
|
|
||||||
<windowController id="B8D-0N-5wS" customClass="WindowController" customModule="SimDirs" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<window key="window" title="SimDirs" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="" animationBehavior="default" id="IQv-IB-iLA">
|
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
|
|
||||||
<rect key="contentRect" x="35" y="482" width="480" height="270"/>
|
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="B8D-0N-5wS" id="qkq-Ka-avA"/>
|
|
||||||
</connections>
|
|
||||||
</window>
|
|
||||||
<connections>
|
|
||||||
<segue destination="utk-XN-WFQ" kind="relationship" relationship="window.shadowedContentViewController" id="cNr-LA-6PI"/>
|
|
||||||
</connections>
|
|
||||||
</windowController>
|
|
||||||
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="75" y="250"/>
|
|
||||||
</scene>
|
|
||||||
<!--Split View Controller-->
|
|
||||||
<scene sceneID="ANE-qI-AzX">
|
|
||||||
<objects>
|
|
||||||
<splitViewController id="utk-XN-WFQ" sceneMemberID="viewController">
|
|
||||||
<splitViewItems>
|
|
||||||
<splitViewItem holdingPriority="255" behavior="contentList" id="vjm-YC-n35"/>
|
|
||||||
<splitViewItem id="zem-yq-moN"/>
|
|
||||||
</splitViewItems>
|
|
||||||
<splitView key="splitView" dividerStyle="thin" vertical="YES" id="4n7-1p-MYG">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="utk-XN-WFQ" id="zcR-4y-jcI"/>
|
|
||||||
</connections>
|
|
||||||
</splitView>
|
|
||||||
<connections>
|
|
||||||
<outlet property="splitView" destination="4n7-1p-MYG" id="anq-oS-l0b"/>
|
|
||||||
<segue destination="iYR-B6-n1S" kind="relationship" relationship="splitItems" id="5zw-PK-lrP"/>
|
|
||||||
<segue destination="F48-sT-ymT" kind="relationship" relationship="splitItems" id="wSa-fB-x8O"/>
|
|
||||||
</connections>
|
|
||||||
</splitViewController>
|
|
||||||
<customObject id="fvM-of-U7k" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="75" y="704"/>
|
|
||||||
</scene>
|
|
||||||
<!--Source Controller-->
|
|
||||||
<scene sceneID="95M-fv-kdk">
|
|
||||||
<objects>
|
|
||||||
<viewController id="iYR-B6-n1S" customClass="SourceController" customModule="SimDirs" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<view key="view" id="MGo-Qu-2zB">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="220" height="299"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AbX-mV-QBL">
|
|
||||||
<rect key="frame" x="0.0" y="30" width="220" height="269"/>
|
|
||||||
<clipView key="contentView" id="Pi5-bv-Sst">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="220" height="269"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" outlineTableColumn="mzD-l4-yhs" id="mUb-N5-ueO">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="220" height="269"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<size key="intercellSpacing" width="3" height="2"/>
|
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<tableColumns>
|
|
||||||
<tableColumn identifier="title" editable="NO" width="188" minWidth="40" maxWidth="1000" id="mzD-l4-yhs">
|
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
|
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</tableHeaderCell>
|
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" alignment="left" title="Text Cell" id="mde-rH-ONI">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
|
||||||
<prototypeCellViews>
|
|
||||||
<tableCellView identifier="TextCell" id="HAO-IX-sxc" userLabel="Text Cell">
|
|
||||||
<rect key="frame" x="11" y="1" width="197" height="18"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="bfY-42-aRq">
|
|
||||||
<rect key="frame" x="2" y="1" width="197" height="16"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="cnA-t8-jTo">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="bfY-42-aRq" firstAttribute="leading" secondItem="HAO-IX-sxc" secondAttribute="leading" constant="4" id="89t-I4-nZh"/>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="bfY-42-aRq" secondAttribute="centerY" id="D1b-kz-ps5"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="bfY-42-aRq" secondAttribute="trailing" id="Dud-KT-aci"/>
|
|
||||||
</constraints>
|
|
||||||
<connections>
|
|
||||||
<outlet property="textField" destination="bfY-42-aRq" id="ucp-nv-3Ke"/>
|
|
||||||
</connections>
|
|
||||||
</tableCellView>
|
|
||||||
<tableCellView identifier="ImageCell" id="Dwi-Dl-LE4" userLabel="Image & Text Cell">
|
|
||||||
<rect key="frame" x="11" y="21" width="197" height="24"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="5Mz-bX-925">
|
|
||||||
<rect key="frame" x="4" y="-2" width="22" height="28"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="22" id="9JV-jh-a9G"/>
|
|
||||||
<constraint firstAttribute="height" constant="22" id="p7O-pN-kXh"/>
|
|
||||||
</constraints>
|
|
||||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="MLC-9O-NVW"/>
|
|
||||||
</imageView>
|
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wgX-ci-hFu">
|
|
||||||
<rect key="frame" x="28" y="4" width="171" height="16"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="jZj-fZ-DCx">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="5Mz-bX-925" secondAttribute="centerY" id="BKo-y7-kUK"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="wgX-ci-hFu" secondAttribute="trailing" id="dit-vg-hyV"/>
|
|
||||||
<constraint firstItem="wgX-ci-hFu" firstAttribute="leading" secondItem="5Mz-bX-925" secondAttribute="trailing" constant="4" id="sVg-cY-ZoA"/>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="wgX-ci-hFu" secondAttribute="centerY" id="t56-t6-q7e"/>
|
|
||||||
<constraint firstItem="5Mz-bX-925" firstAttribute="leading" secondItem="Dwi-Dl-LE4" secondAttribute="leading" constant="4" id="yqi-4E-9SK"/>
|
|
||||||
</constraints>
|
|
||||||
<connections>
|
|
||||||
<outlet property="imageView" destination="5Mz-bX-925" id="Tqr-NH-n33"/>
|
|
||||||
<outlet property="textField" destination="wgX-ci-hFu" id="QM1-92-bQC"/>
|
|
||||||
</connections>
|
|
||||||
</tableCellView>
|
|
||||||
</prototypeCellViews>
|
|
||||||
</tableColumn>
|
|
||||||
</tableColumns>
|
|
||||||
<connections>
|
|
||||||
<outlet property="dataSource" destination="iYR-B6-n1S" id="r6O-sY-vDK"/>
|
|
||||||
<outlet property="delegate" destination="iYR-B6-n1S" id="dFv-mO-hVs"/>
|
|
||||||
</connections>
|
|
||||||
</outlineView>
|
|
||||||
</subviews>
|
|
||||||
</clipView>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="200" id="Prh-ue-cFO"/>
|
|
||||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="yeB-eV-8JM"/>
|
|
||||||
</constraints>
|
|
||||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="UKV-0Z-h3q">
|
|
||||||
<rect key="frame" x="1" y="284" width="448" height="15"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</scroller>
|
|
||||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="xTK-zV-3rC">
|
|
||||||
<rect key="frame" x="184" y="1" width="15" height="0.0"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</scroller>
|
|
||||||
</scrollView>
|
|
||||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="DfU-U7-lPF">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="220" height="30"/>
|
|
||||||
<subviews>
|
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8XW-ii-1pm">
|
|
||||||
<rect key="frame" x="72" y="-2" width="76" height="32"/>
|
|
||||||
<buttonCell key="cell" type="push" title="Reload" bezelStyle="rounded" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="gGy-Fx-TPk">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="rescan:" target="iYR-B6-n1S" id="K6Y-C3-2it"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" constant="30" id="07R-e0-RcD"/>
|
|
||||||
<constraint firstItem="8XW-ii-1pm" firstAttribute="centerX" secondItem="DfU-U7-lPF" secondAttribute="centerX" id="o8I-3P-AaK"/>
|
|
||||||
<constraint firstItem="8XW-ii-1pm" firstAttribute="centerY" secondItem="DfU-U7-lPF" secondAttribute="centerY" id="yWq-r4-QMO"/>
|
|
||||||
</constraints>
|
|
||||||
</customView>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="DfU-U7-lPF" firstAttribute="top" secondItem="AbX-mV-QBL" secondAttribute="bottom" id="GkT-KT-J9Q"/>
|
|
||||||
<constraint firstItem="DfU-U7-lPF" firstAttribute="leading" secondItem="MGo-Qu-2zB" secondAttribute="leading" id="Je2-3P-DQe"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="DfU-U7-lPF" secondAttribute="trailing" id="Kh3-dO-bzm"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="DfU-U7-lPF" secondAttribute="bottom" id="cjT-GE-N46"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="AbX-mV-QBL" secondAttribute="trailing" id="elr-8R-0p9"/>
|
|
||||||
<constraint firstItem="AbX-mV-QBL" firstAttribute="top" secondItem="MGo-Qu-2zB" secondAttribute="top" id="h7M-GY-dLb"/>
|
|
||||||
<constraint firstItem="AbX-mV-QBL" firstAttribute="leading" secondItem="MGo-Qu-2zB" secondAttribute="leading" id="isG-f2-jDQ"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
|
||||||
<connections>
|
|
||||||
<outlet property="outlineView" destination="mUb-N5-ueO" id="qcM-cj-dLn"/>
|
|
||||||
</connections>
|
|
||||||
</viewController>
|
|
||||||
<customObject id="HIA-tb-x8L" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="715" y="455"/>
|
|
||||||
</scene>
|
|
||||||
<!--Detail Controller-->
|
|
||||||
<scene sceneID="Wbg-Th-oFy">
|
|
||||||
<objects>
|
|
||||||
<viewController id="F48-sT-ymT" customClass="DetailController" customModule="SimDirs" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<view key="view" id="UMm-Xy-nBF">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="460" height="298"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0W4-aZ-Ae5">
|
|
||||||
<rect key="frame" x="18" y="262" width="93" height="16"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Detail Header" id="ZtP-3C-2L8">
|
|
||||||
<font key="font" metaFont="systemBold"/>
|
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="cnN-cy-Bac">
|
|
||||||
<rect key="frame" x="435" y="278" width="5" height="0.0"/>
|
|
||||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="36a-uZ-g0s"/>
|
|
||||||
</imageView>
|
|
||||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JAP-se-fpu">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="399" height="254"/>
|
|
||||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="tnM-9n-jrP">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="399" height="254"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="eyA-kU-AI2" customClass="DetailTableView" customModule="SimDirs" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="399" height="254"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<size key="intercellSpacing" width="3" height="2"/>
|
|
||||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
|
|
||||||
<tableViewGridLines key="gridStyleMask" horizontal="YES"/>
|
|
||||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<tableColumns>
|
|
||||||
<tableColumn identifier="title" width="160" minWidth="40" maxWidth="1000" id="tCe-6w-h4v">
|
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</tableHeaderCell>
|
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Ls1-dG-GNl">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
|
||||||
<prototypeCellViews>
|
|
||||||
<tableCellView identifier="PropertyTitleCell" id="lRo-ld-RBC" userLabel="Property Title">
|
|
||||||
<rect key="frame" x="11" y="1" width="165" height="24"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="TBX-NI-YIG">
|
|
||||||
<rect key="frame" x="0.0" y="4" width="159" height="16"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="fjI-nE-FBC">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="TBX-NI-YIG" firstAttribute="leading" secondItem="lRo-ld-RBC" secondAttribute="leading" constant="2" id="BUg-Ur-Hzl"/>
|
|
||||||
<constraint firstItem="TBX-NI-YIG" firstAttribute="centerY" secondItem="lRo-ld-RBC" secondAttribute="centerY" id="INO-aQ-3HN"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="TBX-NI-YIG" secondAttribute="trailing" constant="8" id="dQf-Hb-UI8"/>
|
|
||||||
</constraints>
|
|
||||||
<connections>
|
|
||||||
<outlet property="textField" destination="TBX-NI-YIG" id="KpA-dH-uNj"/>
|
|
||||||
</connections>
|
|
||||||
</tableCellView>
|
|
||||||
</prototypeCellViews>
|
|
||||||
</tableColumn>
|
|
||||||
<tableColumn identifier="value" width="204" minWidth="40" maxWidth="1000" id="pRb-SO-D2D">
|
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</tableHeaderCell>
|
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="hs3-Z6-Um2">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
|
||||||
<prototypeCellViews>
|
|
||||||
<tableCellView identifier="PropertyValueCell" id="M6i-yS-c78" userLabel="Property Value">
|
|
||||||
<rect key="frame" x="179" y="1" width="208" height="24"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="IMg-r6-yjW">
|
|
||||||
<rect key="frame" x="-2" y="4" width="212" height="16"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="05K-5u-HvY">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="IMg-r6-yjW" secondAttribute="trailing" id="EF1-3C-aMi"/>
|
|
||||||
<constraint firstItem="IMg-r6-yjW" firstAttribute="centerY" secondItem="M6i-yS-c78" secondAttribute="centerY" id="Ude-WE-2uY"/>
|
|
||||||
<constraint firstItem="IMg-r6-yjW" firstAttribute="leading" secondItem="M6i-yS-c78" secondAttribute="leading" id="Zhq-i0-zHb"/>
|
|
||||||
</constraints>
|
|
||||||
<connections>
|
|
||||||
<outlet property="textField" destination="IMg-r6-yjW" id="OA5-by-P3W"/>
|
|
||||||
</connections>
|
|
||||||
</tableCellView>
|
|
||||||
<customView identifier="PropertyActionCell" id="q5G-P3-EGm" userLabel="Reveal Cell" customClass="ActionCell" customModule="SimDirs" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="179" y="27" width="208" height="24"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Jjs-nn-o9R">
|
|
||||||
<rect key="frame" x="-7" y="-5" width="124" height="32"/>
|
|
||||||
<buttonCell key="cell" type="push" title="Show In Finder" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="qaa-xT-Nnr">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="executeAction:" target="q5G-P3-EGm" id="4Id-0c-7mK"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="Jjs-nn-o9R" firstAttribute="centerY" secondItem="q5G-P3-EGm" secondAttribute="centerY" id="njz-TZ-q0l"/>
|
|
||||||
<constraint firstItem="Jjs-nn-o9R" firstAttribute="leading" secondItem="q5G-P3-EGm" secondAttribute="leading" id="xBT-kv-Yby"/>
|
|
||||||
</constraints>
|
|
||||||
<connections>
|
|
||||||
<outlet property="actionButton" destination="Jjs-nn-o9R" id="IiA-iD-gPo"/>
|
|
||||||
</connections>
|
|
||||||
</customView>
|
|
||||||
</prototypeCellViews>
|
|
||||||
</tableColumn>
|
|
||||||
</tableColumns>
|
|
||||||
<connections>
|
|
||||||
<outlet property="dataSource" destination="F48-sT-ymT" id="Iq0-Oq-XqV"/>
|
|
||||||
<outlet property="delegate" destination="F48-sT-ymT" id="f1b-rA-9VC"/>
|
|
||||||
</connections>
|
|
||||||
</tableView>
|
|
||||||
</subviews>
|
|
||||||
</clipView>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="360" id="FDG-SK-zLr"/>
|
|
||||||
</constraints>
|
|
||||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="mGJ-QF-84J">
|
|
||||||
<rect key="frame" x="1" y="119" width="223" height="15"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</scroller>
|
|
||||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="U02-Dv-BpL">
|
|
||||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</scroller>
|
|
||||||
</scrollView>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="cnN-cy-Bac" secondAttribute="trailing" constant="20" symbolic="YES" id="6jt-1y-I45"/>
|
|
||||||
<constraint firstItem="JAP-se-fpu" firstAttribute="top" secondItem="0W4-aZ-Ae5" secondAttribute="bottom" constant="8" symbolic="YES" id="I2y-6k-eoF"/>
|
|
||||||
<constraint firstItem="cnN-cy-Bac" firstAttribute="leading" secondItem="JAP-se-fpu" secondAttribute="trailing" constant="16" id="Mp2-4Z-5Wj"/>
|
|
||||||
<constraint firstItem="0W4-aZ-Ae5" firstAttribute="leading" secondItem="UMm-Xy-nBF" secondAttribute="leading" constant="20" symbolic="YES" id="NxN-dt-Qik"/>
|
|
||||||
<constraint firstItem="JAP-se-fpu" firstAttribute="leading" secondItem="UMm-Xy-nBF" secondAttribute="leading" constant="20" symbolic="YES" id="Tpt-YG-xYq"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="JAP-se-fpu" secondAttribute="bottom" id="e1L-p4-1Hj"/>
|
|
||||||
<constraint firstItem="cnN-cy-Bac" firstAttribute="top" secondItem="UMm-Xy-nBF" secondAttribute="top" constant="20" symbolic="YES" id="fKO-Jw-6co"/>
|
|
||||||
<constraint firstItem="0W4-aZ-Ae5" firstAttribute="top" secondItem="UMm-Xy-nBF" secondAttribute="top" constant="20" symbolic="YES" id="g8h-kr-Or3"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
|
||||||
<connections>
|
|
||||||
<outlet property="headerLabel" destination="0W4-aZ-Ae5" id="BcX-er-8kA"/>
|
|
||||||
<outlet property="imageView" destination="cnN-cy-Bac" id="teZ-DG-dWn"/>
|
|
||||||
<outlet property="propertyTable" destination="eyA-kU-AI2" id="Bq9-nt-FtY"/>
|
|
||||||
</connections>
|
|
||||||
</viewController>
|
|
||||||
<customObject id="F92-9s-t7r" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="715" y="904"/>
|
|
||||||
</scene>
|
|
||||||
</scenes>
|
|
||||||
<resources>
|
|
||||||
<image name="NSActionTemplate" width="15" height="15"/>
|
|
||||||
</resources>
|
|
||||||
</document>
|
|
||||||
80
SimDirs/ContentView.swift
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
//
|
||||||
|
// ContentView.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/23/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct Item: Identifiable {
|
||||||
|
var id: Int
|
||||||
|
var name: String
|
||||||
|
|
||||||
|
init(id: Int) {
|
||||||
|
self.id = id
|
||||||
|
self.name = "\(id)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ContentView: View {
|
||||||
|
@EnvironmentObject var modelData : PresentableModel
|
||||||
|
@State private var toggleVal = false
|
||||||
|
|
||||||
|
let testItems = (0..<10).map({ Item(id: $0) })
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationView {
|
||||||
|
List {
|
||||||
|
OutlineGroup(modelData.items, children: \.children) { item in
|
||||||
|
NavigationLink {
|
||||||
|
VStack {
|
||||||
|
HStack {
|
||||||
|
switch item.underlying {
|
||||||
|
case let deviceType as SimDeviceType:
|
||||||
|
DeviceTypeView(deviceType: deviceType)
|
||||||
|
|
||||||
|
default:
|
||||||
|
Text("\(item.title)")
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.all)
|
||||||
|
.navigationTitle(item.title)
|
||||||
|
} label: {
|
||||||
|
Label(item.title, systemImage: item.imageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.leading, 2.0)
|
||||||
|
}
|
||||||
|
.frame(minWidth: 200)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem {
|
||||||
|
Menu {
|
||||||
|
// Picker("Category", selection: $filter) {
|
||||||
|
// ForEach(FilterCategory.allCases) { category in
|
||||||
|
// Text(category.rawValue).tag(category)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .pickerStyle(.inline)
|
||||||
|
Toggle(isOn: $toggleVal) {
|
||||||
|
Label("Toggle", systemImage: "star.fill")
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Label("Filter", systemImage: "slider.horizontal.3")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text("SimDirs") // If this isn't here things looks weird
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ContentView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
ContentView()
|
||||||
|
.environmentObject(PresentableModel())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIconFile</key>
|
|
||||||
<string></string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>$(PRODUCT_NAME)</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>0.6</string>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>????</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>1</string>
|
|
||||||
<key>LSMinimumSystemVersion</key>
|
|
||||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
|
||||||
<key>NSHumanReadableCopyright</key>
|
|
||||||
<string>Copyright © 2016 Quiet Spark. All rights reserved.</string>
|
|
||||||
<key>NSMainStoryboardFile</key>
|
|
||||||
<string>Main</string>
|
|
||||||
<key>NSPrincipalClass</key>
|
|
||||||
<string>NSApplication</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
100
SimDirs/Model/Presentation/PresentableModel.swift
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
//
|
||||||
|
// PresentableModel.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/25/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class PresentableModel: ObservableObject {
|
||||||
|
enum Style {
|
||||||
|
case byDevice
|
||||||
|
case byRuntime
|
||||||
|
}
|
||||||
|
|
||||||
|
var baseModel = SimModel()
|
||||||
|
var style = Style.byDevice
|
||||||
|
var items = [PresentationItem]()
|
||||||
|
|
||||||
|
init() {
|
||||||
|
rebuildPresentation()
|
||||||
|
// dumpPresentationItems(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
func rebuildPresentation() {
|
||||||
|
switch style {
|
||||||
|
case .byDevice: items = itemsForDevicePresentation()
|
||||||
|
case .byRuntime: items = itemsForRuntimePresentation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func itemsForDevicePresentation() -> [PresentationItem] {
|
||||||
|
return SimProductFamily.presentation.map{ family in
|
||||||
|
var familyItem = PresentationItem(family)
|
||||||
|
|
||||||
|
familyItem.children = baseModel.deviceTypes.filter({ $0.supports(productFamily: family) }).map { deviceType in
|
||||||
|
var deviceTypeItem = PresentationItem(deviceType, identifier: deviceType.id)
|
||||||
|
let deviceTypeChildren : [PresentationItem] = baseModel.runtimes.filter({ $0.supports(deviceType: deviceType) }).map { runtime in
|
||||||
|
var runtimeItem = PresentationItem(runtime, identifier: "\(deviceType.id) - \(runtime.id)")
|
||||||
|
let runtimeItemChildren = runtime.devices.filter({ $0.isDeviceOfType(deviceType) }).map { PresentationItem($0, image: family.imageName) }
|
||||||
|
|
||||||
|
if !runtimeItemChildren.isEmpty {
|
||||||
|
runtimeItem.children = runtimeItemChildren
|
||||||
|
}
|
||||||
|
|
||||||
|
return runtimeItem
|
||||||
|
}
|
||||||
|
|
||||||
|
if !deviceTypeChildren.isEmpty {
|
||||||
|
deviceTypeItem.children = deviceTypeChildren
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceTypeItem
|
||||||
|
}
|
||||||
|
|
||||||
|
return familyItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func itemsForRuntimePresentation() -> [PresentationItem] {
|
||||||
|
return SimPlatform.presentation.map{ platform in
|
||||||
|
var platformItem = PresentationItem(platform)
|
||||||
|
|
||||||
|
platformItem.children = baseModel.runtimes.filter({ $0.supports(platform: platform) }).map { runtime in
|
||||||
|
var runtimeItem = PresentationItem(runtime)
|
||||||
|
let runtimeItemChildren : [PresentationItem] = baseModel.deviceTypes.filter({ $0.supports(runtime: runtime) }).map { deviceType in
|
||||||
|
var deviceTypeItem = PresentationItem(deviceType, identifier: "\(runtime.id) - \(deviceType.id)")
|
||||||
|
let deviceTypeChildren = runtime.devices.filter({ $0.isDeviceOfType(deviceType) }).map { PresentationItem($0, image: deviceType.imageName) }
|
||||||
|
|
||||||
|
if !deviceTypeChildren.isEmpty {
|
||||||
|
deviceTypeItem.children = deviceTypeChildren
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceTypeItem
|
||||||
|
}
|
||||||
|
|
||||||
|
if !runtimeItemChildren.isEmpty {
|
||||||
|
runtimeItem.children = runtimeItemChildren
|
||||||
|
}
|
||||||
|
|
||||||
|
return runtimeItem
|
||||||
|
}
|
||||||
|
|
||||||
|
return platformItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dumpPresentationItems(_ items: [PresentationItem], level: Int = 0) {
|
||||||
|
let ident = Array(repeating: "\t", count: level).joined()
|
||||||
|
|
||||||
|
for item in items {
|
||||||
|
print("\(ident)\(item.title) [\(item.id)]")
|
||||||
|
|
||||||
|
if let children = item.children {
|
||||||
|
dumpPresentationItems(children, level: level + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
40
SimDirs/Model/Presentation/PresentationItem.swift
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// PresentationItem.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/25/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
protocol PresentableItem {
|
||||||
|
var title : String { get }
|
||||||
|
var id : String { get }
|
||||||
|
var imageName : String { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol PresentableContent {
|
||||||
|
associatedtype Content : View
|
||||||
|
|
||||||
|
var view : Content { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PresentationContent<T: PresentableContent> {
|
||||||
|
let underlying : T
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PresentationItem: Identifiable {
|
||||||
|
let underlying : PresentableItem
|
||||||
|
var children : [PresentationItem]?
|
||||||
|
var id : String
|
||||||
|
var customImage : String?
|
||||||
|
|
||||||
|
var title : String { return underlying.title }
|
||||||
|
var imageName : String { return customImage ?? underlying.imageName }
|
||||||
|
|
||||||
|
init(_ presentable: PresentableItem, image: String? = nil, identifier: String? = nil) {
|
||||||
|
underlying = presentable
|
||||||
|
id = identifier ?? underlying.id
|
||||||
|
customImage = image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,205 +0,0 @@
|
||||||
//
|
|
||||||
// SimApp.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 4/30/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
class SimApp: OutlineProvider, PropertyProvider {
|
|
||||||
let bundleID : String
|
|
||||||
var bundleName = ""
|
|
||||||
var displayName = ""
|
|
||||||
var shortVersion = ""
|
|
||||||
var version = ""
|
|
||||||
var minOSVersion : String?
|
|
||||||
var icon : NSImage?
|
|
||||||
var hasValidPaths : Bool { return self.validatedBundlePath != nil || self.validatedSandboxPath != nil }
|
|
||||||
var bundleURL : URL? { return self.validatedBundlePath.map { URL(fileURLWithPath: $0) } }
|
|
||||||
var sandboxURL : URL? { return self.validatedSandboxPath.map { URL(fileURLWithPath: $0) } }
|
|
||||||
private var validatedBundlePath : String?
|
|
||||||
private var validatedSandboxPath : String?
|
|
||||||
|
|
||||||
var bundlePath : String? {
|
|
||||||
get { return self.validatedBundlePath }
|
|
||||||
set {
|
|
||||||
guard let newPath = newValue else { return }
|
|
||||||
if self.validatedBundlePath == nil && newPath.validPath {
|
|
||||||
self.validatedBundlePath = newPath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var sandboxPath : String? {
|
|
||||||
get { return self.validatedSandboxPath }
|
|
||||||
set {
|
|
||||||
guard let newPath = newValue else { return }
|
|
||||||
if self.validatedSandboxPath == nil && newPath.validPath {
|
|
||||||
self.validatedSandboxPath = newPath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init(bundleID: String) {
|
|
||||||
self.bundleID = bundleID
|
|
||||||
}
|
|
||||||
|
|
||||||
func completeScan() {
|
|
||||||
self.refinePaths()
|
|
||||||
self.loadInfoPlist()
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateFrom(launchBundleInfo: [String : AnyObject]) {
|
|
||||||
self.bundlePath = launchBundleInfo["BundleContainer"] as? String
|
|
||||||
self.sandboxPath = launchBundleInfo["Container"] as? String
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateFrom(appStateInfo: [String : AnyObject]) {
|
|
||||||
guard let compatInfo = appStateInfo["compatibilityInfo"] as? [String : AnyObject] else { return }
|
|
||||||
|
|
||||||
self.bundlePath = compatInfo["bundlePath"] as? String
|
|
||||||
self.sandboxPath = compatInfo["sandboxPath"] as? String
|
|
||||||
}
|
|
||||||
|
|
||||||
func refinePaths() {
|
|
||||||
guard let bundleURL = self.bundleURL else { return }
|
|
||||||
let fileMgr = FileManager.default
|
|
||||||
|
|
||||||
if !bundleURL.lastPathComponent.contains("app") {
|
|
||||||
if let dirEnumerator = fileMgr.enumerator(at: bundleURL, includingPropertiesForKeys: nil, options: [ .skipsSubdirectoryDescendants, .skipsHiddenFiles ]) {
|
|
||||||
|
|
||||||
for appURL in dirEnumerator.allObjects.compactMap({ $0 as? URL}) {
|
|
||||||
if appURL.lastPathComponent.contains(".app") {
|
|
||||||
self.validatedBundlePath = appURL.path
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadInfoPlist() {
|
|
||||||
guard let bundleURL = self.bundleURL else { return }
|
|
||||||
let infoPlistURL = bundleURL.appendingPathComponent("Info.plist")
|
|
||||||
|
|
||||||
if let plistInfo = PropertyListSerialization.propertyListWithURL(infoPlistURL) {
|
|
||||||
self.bundleName = plistInfo[String(kCFBundleNameKey)] as? String ?? ""
|
|
||||||
self.displayName = plistInfo["CFBundleDisplayName"] as? String ?? ""
|
|
||||||
self.shortVersion = plistInfo["CFBundleShortVersionString"] as? String ?? ""
|
|
||||||
self.version = plistInfo[String(kCFBundleVersionKey)] as? String ?? ""
|
|
||||||
self.minOSVersion = plistInfo["MinimumOSVersion"] as? String
|
|
||||||
|
|
||||||
if self.displayName.isEmpty {
|
|
||||||
self.displayName = self.bundleName
|
|
||||||
}
|
|
||||||
|
|
||||||
if let bundleIcons = plistInfo["CFBundleIcons"] as? [String : AnyObject] {
|
|
||||||
let primaryIconValue = bundleIcons["CFBundlePrimaryIcon"].flatMap { item -> [String : AnyObject]? in
|
|
||||||
switch item {
|
|
||||||
case let dict as [String : AnyObject]: return dict
|
|
||||||
case let str as String: return ["CFBundleIconFiles" : [str]] as [String : AnyObject]
|
|
||||||
default: return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let primaryIcon = primaryIconValue {
|
|
||||||
if let bundleIconFiles = primaryIcon["CFBundleIconFiles"] as? [String] {
|
|
||||||
for iconName in bundleIconFiles {
|
|
||||||
var iconURL = bundleURL.appendingPathComponent(iconName)
|
|
||||||
let icon2XURL = bundleURL.appendingPathComponent("\(iconName)@2x.png")
|
|
||||||
|
|
||||||
if iconURL.pathExtension.isEmpty {
|
|
||||||
iconURL = iconURL.appendingPathComponent("png")
|
|
||||||
}
|
|
||||||
|
|
||||||
// .car files not yet working :/
|
|
||||||
|
|
||||||
// if !iconURL.validPath && !icon2XURL.validPath { // Believe this would only happen once per bundle
|
|
||||||
// let assetFileURL = bundleURL.URLByAppendingPathComponent("Assets.car")
|
|
||||||
//
|
|
||||||
// if assetFileURL.validPath {
|
|
||||||
// if let catalog = try? CUICatalog.init(URL: assetFileURL) {
|
|
||||||
// let catalogImages = catalog.imagesWithName(iconName)
|
|
||||||
//
|
|
||||||
// for catalogImage in catalogImages {
|
|
||||||
// if let namedImage = catalogImage as? CUINamedImage where !(namedImage is CUINamedLayerStack) {
|
|
||||||
// if self.icon?.size.width ?? 0 < namedImage.size.width {
|
|
||||||
// let imageRep = NSBitmapImageRep(CGImage: namedImage.image)
|
|
||||||
//
|
|
||||||
// imageRep.size = namedImage.size
|
|
||||||
// if let pngData = imageRep.representationUsingType(.NSPNGFileType, properties: [NSImageInterlaced : false]) where pngData.length > 0 {
|
|
||||||
// self.icon = NSImage(data: pngData)
|
|
||||||
// }
|
|
||||||
// self.icon = NSImage(CGImage: namedImage.image, size: namedImage.size)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
if let icon = NSImage(contentsOf: iconURL) {
|
|
||||||
if self.icon?.size.width ?? 0 < icon.size.width {
|
|
||||||
self.icon = icon
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let icon = NSImage(contentsOf: icon2XURL) {
|
|
||||||
if self.icon?.size.width ?? 0 < icon.size.width {
|
|
||||||
self.icon = icon
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.icon == nil {
|
|
||||||
self.icon = NSImage(named: "default_icon")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - OutlineProvider -
|
|
||||||
|
|
||||||
var outlineTitle : String { return self.displayName }
|
|
||||||
var outlineImage : NSImage? { return self.icon }
|
|
||||||
var childCount : Int { return 0 }
|
|
||||||
|
|
||||||
func childAt(index: Int) -> OutlineProvider? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - PropertyProvider -
|
|
||||||
|
|
||||||
var header : String { return "App Information" }
|
|
||||||
var image : NSImage? { return self.icon }
|
|
||||||
var properties : [SimProperty] {
|
|
||||||
var version = self.shortVersion
|
|
||||||
var properties : [SimProperty]
|
|
||||||
|
|
||||||
if self.shortVersion != self.version {
|
|
||||||
version += " \((self.version))"
|
|
||||||
}
|
|
||||||
|
|
||||||
properties = [
|
|
||||||
SimProperty(title: "Display Name", value: .Text(text: self.displayName)),
|
|
||||||
SimProperty(title: "Bundle Name", value: .Text(text: self.bundleName)),
|
|
||||||
SimProperty(title: "Bundle ID", value: .Text(text: self.bundleID)),
|
|
||||||
SimProperty(title: "Version", value: .Text(text: version))
|
|
||||||
]
|
|
||||||
if let minOSVersion = self.minOSVersion {
|
|
||||||
properties.append(SimProperty(title: "Minimum OS Version", value: .Text(text: minOSVersion)))
|
|
||||||
}
|
|
||||||
if let bundleURL = self.bundleURL {
|
|
||||||
properties.append(SimProperty(title: "Bundle", value: .Location(url: bundleURL)))
|
|
||||||
}
|
|
||||||
if let sandboxURL = self.sandboxURL {
|
|
||||||
properties.append(SimProperty(title: "Sandbox", value: .Location(url: sandboxURL)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return properties
|
|
||||||
}
|
|
||||||
}
|
|
||||||
52
SimDirs/Model/SimCtl.swift
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
//
|
||||||
|
// SimCtl.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/23/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class SimCtl {
|
||||||
|
static func run(args: [String]) throws -> Data {
|
||||||
|
let process = Process()
|
||||||
|
let pipe = Pipe()
|
||||||
|
|
||||||
|
process.executableURL = URL(fileURLWithPath: "/usr/bin/xcrun")
|
||||||
|
process.arguments = ["simctl"] + args
|
||||||
|
process.standardOutput = pipe
|
||||||
|
try process.run()
|
||||||
|
|
||||||
|
return pipe.fileHandleForReading.readDataToEndOfFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
static func run(args: [String]) throws -> String {
|
||||||
|
return String(data: try run(args: args), encoding: .utf8) ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
|
static func dumpRuntimes() {
|
||||||
|
print("dumpRuntimes")
|
||||||
|
|
||||||
|
do {
|
||||||
|
let json : String = try run(args: ["list", "-j", "runtimes"])
|
||||||
|
|
||||||
|
print("json: \(json)")
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func dumpDevices() {
|
||||||
|
print("dumpDevices")
|
||||||
|
|
||||||
|
do {
|
||||||
|
let json : String = try run(args: ["list", "-j", "devices"])
|
||||||
|
|
||||||
|
print("json: \(json)")
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,150 +2,31 @@
|
||||||
// SimDevice.swift
|
// SimDevice.swift
|
||||||
// SimDirs
|
// SimDirs
|
||||||
//
|
//
|
||||||
// Created by Casey Fleser on 4/30/16.
|
// Created by Casey Fleser on 5/24/22.
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class SimDevice: OutlineProvider, PropertyProvider {
|
struct SimDevice: Decodable {
|
||||||
let name : String
|
let name : String
|
||||||
let type : String
|
let udid : String
|
||||||
let udid : String
|
let state : String
|
||||||
let baseURL : URL
|
let dataPath : String
|
||||||
var platformName = "Unknown"
|
let dataPathSize : Int
|
||||||
var platformVersion = ""
|
let logPath : String
|
||||||
var platformBuild = ""
|
let isAvailable : Bool
|
||||||
var apps = [SimApp]()
|
let deviceTypeIdentifier : String
|
||||||
|
let availabilityError : String?
|
||||||
|
|
||||||
init(name: String, type: String, udid: String, baseURL: URL) {
|
func isDeviceOfType(_ deviceType: SimDeviceType) -> Bool {
|
||||||
self.name = name
|
return deviceTypeIdentifier == deviceType.identifier
|
||||||
self.type = type
|
}
|
||||||
self.udid = udid
|
|
||||||
self.baseURL = baseURL
|
|
||||||
|
|
||||||
self.gatherBuildInfo()
|
|
||||||
|
|
||||||
self.gatherAppInfoFromLastLaunchMap()
|
|
||||||
self.gatherAppInfoFromAppState()
|
|
||||||
// self.gatherAppInfoFromCaches() obsolete
|
|
||||||
self.gatherAppInfoFromInstallLogs()
|
|
||||||
}
|
|
||||||
|
|
||||||
func completeScan(platformName: String) {
|
|
||||||
self.platformName = platformName
|
|
||||||
self.apps = self.apps.filter { return $0.hasValidPaths }
|
|
||||||
|
|
||||||
for app in self.apps {
|
|
||||||
app.completeScan()
|
|
||||||
}
|
|
||||||
self.apps.sort(by: { $0.displayName < $1.displayName })
|
|
||||||
}
|
|
||||||
|
|
||||||
func gatherBuildInfo() {
|
|
||||||
let buildInfoURL = self.baseURL.appendingPathComponent("data/Library/MobileInstallation/LastBuildInfo.plist")
|
|
||||||
guard let buildInfo = PropertyListSerialization.propertyListWithURL(buildInfoURL) else { return }
|
|
||||||
|
|
||||||
self.platformVersion = buildInfo["ProductVersion"] as? String ?? ""
|
|
||||||
self.platformBuild = buildInfo["ProductBuildVersion"] as? String ?? ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// LastLaunchServicesMap.plist seems to be the most reliable location to gather app info
|
|
||||||
func gatherAppInfoFromLastLaunchMap() {
|
|
||||||
let launchMapInfoURL = self.baseURL.appendingPathComponent("data/Library/MobileInstallation/LastLaunchServicesMap.plist")
|
|
||||||
guard let launchInfo = PropertyListSerialization.propertyListWithURL(launchMapInfoURL) else { return }
|
|
||||||
guard let userInfo = launchInfo["User"] as? [String : AnyObject] else { return }
|
|
||||||
|
|
||||||
for (bundleID, bundleInfo) in userInfo {
|
|
||||||
guard let bundleInfo = bundleInfo as? [String : AnyObject] else { continue }
|
|
||||||
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
|
|
||||||
|
|
||||||
simApp.updateFrom(launchBundleInfo: bundleInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// applicationState.plist sometimes has info that LastLaunchServicesMap.plist doesn't
|
|
||||||
func gatherAppInfoFromAppState() {
|
|
||||||
for pathComponent in ["data/Library/FrontBoard/applicationState.plist", "data/Library/BackBoard/applicationState.plist"] {
|
|
||||||
let appStateInfoURL = self.baseURL.appendingPathComponent(pathComponent)
|
|
||||||
guard let stateInfo = PropertyListSerialization.propertyListWithURL(appStateInfoURL) else { continue }
|
|
||||||
|
|
||||||
for (bundleID, bundleInfo) in stateInfo {
|
|
||||||
if !bundleID.contains("com.apple") {
|
|
||||||
guard let bundleInfo = bundleInfo as? [String : AnyObject] else { continue }
|
|
||||||
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
|
|
||||||
|
|
||||||
simApp.updateFrom(appStateInfo: bundleInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mobile_installation.log.0 is my least favorite, most fragile way to scan for app installations
|
|
||||||
// try this after everything else
|
|
||||||
func gatherAppInfoFromInstallLogs() {
|
|
||||||
let installLogURL = self.baseURL.appendingPathComponent("data/Library/Logs/MobileInstallation/mobile_installation.log.0")
|
|
||||||
|
|
||||||
if let installLog = try? String(contentsOf: installLogURL) {
|
|
||||||
let lines = installLog.components(separatedBy: .newlines)
|
|
||||||
|
|
||||||
for line in lines.reversed() {
|
|
||||||
if !line.contains("com.apple") {
|
|
||||||
if line.contains("makeContainerLiveReplacingContainer") {
|
|
||||||
self.extractBundleLocationFrom(logEntry: line)
|
|
||||||
}
|
|
||||||
if line.contains("_refreshUUIDForContainer") {
|
|
||||||
self.extractSandboxLocationFrom(logEntry: line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractBundleLocationFrom(logEntry: String) {
|
|
||||||
let logComponents = logEntry.split(separator: (" ")).map({ String($0) })
|
|
||||||
|
|
||||||
if let bundlePath = logComponents.last {
|
|
||||||
if let bundleID = logComponents[safe: logComponents.count - 3] {
|
|
||||||
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
|
|
||||||
|
|
||||||
simApp.bundlePath = bundlePath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractSandboxLocationFrom(logEntry: String) {
|
|
||||||
let logComponents = logEntry.split(separator: (" ")).map({ String($0) })
|
|
||||||
|
|
||||||
if let sandboxPath = logComponents.last {
|
|
||||||
if let bundleID = logComponents[safe: logComponents.count - 5] {
|
|
||||||
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
|
|
||||||
|
|
||||||
simApp.sandboxPath = sandboxPath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - OutlineProvider -
|
|
||||||
|
|
||||||
var outlineTitle : String { return self.name }
|
|
||||||
var outlineImage : NSImage? { return nil }
|
|
||||||
var childCount : Int { return self.apps.count }
|
|
||||||
|
|
||||||
func childAt(index: Int) -> OutlineProvider? {
|
|
||||||
return self.apps[index]
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - PropertyProvider -
|
|
||||||
var header : String { return "Device Information" }
|
|
||||||
var image : NSImage? { return nil }
|
|
||||||
var properties : [SimProperty] {
|
|
||||||
return [
|
|
||||||
SimProperty(title: "Name", value: .Text(text: self.name)),
|
|
||||||
SimProperty(title: "Simulated Model", value: .Text(text: self.type)),
|
|
||||||
SimProperty(title: self.platformName, value: .Text(text: "\(self.platformVersion) (\(self.platformBuild))")),
|
|
||||||
SimProperty(title: "Identifier", value: .Text(text: self.udid)),
|
|
||||||
SimProperty(title: "Location", value: .Location(url: self.baseURL))
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SimDevice: PresentableItem {
|
||||||
|
var title : String { return name }
|
||||||
|
var id : String { return udid }
|
||||||
|
|
||||||
|
var imageName : String { return "shippingbox" } // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
46
SimDirs/Model/SimDeviceType.swift
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
//
|
||||||
|
// SimDeviceType.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/24/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct SimDeviceType: Decodable {
|
||||||
|
// enum CodingKeys: String, CodingKey {
|
||||||
|
// case bundlePath
|
||||||
|
// case identifier
|
||||||
|
// case maxRuntimeVersion
|
||||||
|
// case maxRuntimeVersionString
|
||||||
|
// case minRuntimeVersion
|
||||||
|
// case minRuntimeVersionString
|
||||||
|
// case modelIdentifier
|
||||||
|
// case name
|
||||||
|
// case productFamily
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
let name : String
|
||||||
|
let identifier : String
|
||||||
|
let productFamily : SimProductFamily
|
||||||
|
let modelIdentifier : String
|
||||||
|
let bundlePath : String
|
||||||
|
let minRuntimeVersion : Int
|
||||||
|
let maxRuntimeVersion : Int
|
||||||
|
let minRuntimeVersionString : String
|
||||||
|
let maxRuntimeVersionString : String
|
||||||
|
|
||||||
|
func supports(productFamily: SimProductFamily) -> Bool {
|
||||||
|
return productFamily == self.productFamily
|
||||||
|
}
|
||||||
|
|
||||||
|
func supports(runtime: SimRuntime) -> Bool {
|
||||||
|
return runtime.supportedDeviceTypes.contains { $0.identifier == identifier }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SimDeviceType: PresentableItem {
|
||||||
|
var title : String { return name }
|
||||||
|
var id : String { return identifier }
|
||||||
|
var imageName : String { return productFamily.imageName }
|
||||||
|
}
|
||||||
53
SimDirs/Model/SimModel.swift
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
//
|
||||||
|
// SimModel.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/24/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum SimError: Error {
|
||||||
|
case deviceParsingFailure
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SimModel {
|
||||||
|
var deviceTypes : [SimDeviceType]
|
||||||
|
var runtimes : [SimRuntime]
|
||||||
|
|
||||||
|
init() {
|
||||||
|
do {
|
||||||
|
var json : Data
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
let runtimeDevs : [String : [SimDevice]]
|
||||||
|
|
||||||
|
// - [SimDeviceType]
|
||||||
|
json = try SimCtl.run(args: ["list", "-j", "devicetypes"])
|
||||||
|
deviceTypes = try decoder.decode([String : [SimDeviceType]].self, from: json)["devicetypes"] ?? []
|
||||||
|
|
||||||
|
// - [SimRuntime]
|
||||||
|
json = try SimCtl.run(args: ["list", "-j", "runtimes"])
|
||||||
|
runtimes = try decoder.decode([String : [SimRuntime]].self, from: json)["runtimes"] ?? []
|
||||||
|
|
||||||
|
// - [SimDevice]
|
||||||
|
json = try SimCtl.run(args: ["list", "-j", "devices"])
|
||||||
|
runtimeDevs = try decoder.decode([String : [String : [SimDevice]]] .self, from: json)["devices"] ?? [:]
|
||||||
|
|
||||||
|
for (runtimeID, devices) in runtimeDevs {
|
||||||
|
do {
|
||||||
|
let runtimeIdx = try runtimes.indexOfMatchedOrCreated(identifier: runtimeID)
|
||||||
|
|
||||||
|
runtimes[runtimeIdx].setDevices(devices, from: deviceTypes)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
print("Warning: Unable to create placeholder runtime from \(runtimeID)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runtimes.sort()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
fatalError("Failed to initialize data model:\n\(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
//
|
|
||||||
// SimOSVersion.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 4/30/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
class SimOSVersion: OutlineProvider {
|
|
||||||
let name : String
|
|
||||||
var devices = [SimDevice]()
|
|
||||||
|
|
||||||
init(name: String, deviceInfo: [String : AnyObject]) {
|
|
||||||
self.name = name
|
|
||||||
}
|
|
||||||
|
|
||||||
func completeScan(platformName: String) {
|
|
||||||
for device in self.devices {
|
|
||||||
device.completeScan(platformName: platformName)
|
|
||||||
}
|
|
||||||
self.devices.sort(by: { $0.name < $1.name })
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateWith(deviceInfo: [String : AnyObject], baseURL: URL) {
|
|
||||||
guard let deviceName = deviceInfo["name"] as? String else { return }
|
|
||||||
guard let deviceUDID = deviceInfo["UDID"] as? String else { return }
|
|
||||||
guard var deviceType = deviceInfo["deviceType"] as? String else { return }
|
|
||||||
|
|
||||||
deviceType = deviceType.replacingOccurrences(of: "com.apple.CoreSimulator.SimDeviceType.", with: "")
|
|
||||||
deviceType = deviceType.replacingOccurrences(of: "-", with: " ")
|
|
||||||
|
|
||||||
self.devices.append(SimDevice(name: deviceName, type: deviceType, udid: deviceUDID, baseURL: baseURL))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - OutlineProvider -
|
|
||||||
|
|
||||||
var outlineTitle : String { return self.name }
|
|
||||||
var outlineImage : NSImage? { return nil }
|
|
||||||
var childCount : Int { return self.devices.count }
|
|
||||||
|
|
||||||
func childAt(index: Int) -> OutlineProvider? {
|
|
||||||
return self.devices[index]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,71 +2,27 @@
|
||||||
// SimPlatform.swift
|
// SimPlatform.swift
|
||||||
// SimDirs
|
// SimDirs
|
||||||
//
|
//
|
||||||
// Created by Casey Fleser on 4/30/16.
|
// Created by Casey Fleser on 5/23/22.
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class SimPlatform: OutlineProvider {
|
enum SimPlatform: String, Decodable {
|
||||||
let name : String
|
case iOS
|
||||||
var osVersions = [SimOSVersion]()
|
case tvOS
|
||||||
|
case watchOS
|
||||||
class func scan() -> [SimPlatform] {
|
|
||||||
let fileMgr = FileManager.default
|
|
||||||
var platforms = [SimPlatform]()
|
|
||||||
|
|
||||||
if let libraryURL = fileMgr.urls(for: .libraryDirectory, in: .userDomainMask).first {
|
|
||||||
let deviceURL = libraryURL.appendingPathComponent("Developer/CoreSimulator/Devices")
|
|
||||||
|
|
||||||
if let dirEnumerator = fileMgr.enumerator(at: deviceURL, includingPropertiesForKeys: nil, options: [ .skipsSubdirectoryDescendants, .skipsHiddenFiles ], errorHandler: nil) {
|
|
||||||
for baseURL in dirEnumerator.allObjects.compactMap({ $0 as? URL }) {
|
|
||||||
let deviceURL = baseURL.appendingPathComponent("device.plist")
|
|
||||||
guard let deviceInfo = PropertyListSerialization.propertyListWithURL(deviceURL) else { continue }
|
|
||||||
guard let runtime = deviceInfo["runtime"] as? String else { continue }
|
|
||||||
let runtimeComponents = runtime.replacingOccurrences(of: "com.apple.CoreSimulator.SimRuntime.", with: "").split(separator: "-").map({ String($0) })
|
|
||||||
|
|
||||||
if let platformName = runtimeComponents.first {
|
static let presentation : [SimPlatform] = [.iOS, .watchOS, .tvOS]
|
||||||
let platform = platforms.match({ $0.name == platformName }, orMake: { SimPlatform(runtimeComponents: runtimeComponents, deviceInfo: deviceInfo) })
|
}
|
||||||
|
|
||||||
platform.updateWith(runtimeComponents, deviceInfo: deviceInfo, baseURL: baseURL)
|
extension SimPlatform: PresentableItem {
|
||||||
}
|
var title : String { return self.rawValue }
|
||||||
}
|
var id : String { return self.rawValue }
|
||||||
}
|
var imageName : String {
|
||||||
}
|
switch self {
|
||||||
|
case .iOS: return "iphone"
|
||||||
for platform in platforms {
|
case .tvOS: return "appletv"
|
||||||
platform.completeScan()
|
case .watchOS: return "applewatch"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return platforms.sorted { $0.name < $1.name }
|
|
||||||
}
|
|
||||||
|
|
||||||
init(runtimeComponents: [String], deviceInfo: [String : AnyObject]) {
|
|
||||||
self.name = runtimeComponents[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func completeScan() {
|
|
||||||
for osVersion in self.osVersions {
|
|
||||||
osVersion.completeScan(platformName: self.name)
|
|
||||||
}
|
|
||||||
self.osVersions.sort(by: { $0.name > $1.name })
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateWith(_ runtimeComponents: [String], deviceInfo: [String : AnyObject], baseURL: URL) {
|
|
||||||
let versionID = "\(runtimeComponents[safe: 1] ?? "0").\(runtimeComponents[safe: 2] ?? "0")"
|
|
||||||
let osVersion = self.osVersions.match({ $0.name == versionID }, orMake: { SimOSVersion(name: versionID, deviceInfo: deviceInfo) })
|
|
||||||
|
|
||||||
osVersion.updateWith(deviceInfo: deviceInfo, baseURL: baseURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - OutlineProvider -
|
|
||||||
|
|
||||||
var outlineTitle : String { return self.name }
|
|
||||||
var outlineImage : NSImage? { return nil }
|
|
||||||
var childCount : Int { return self.osVersions.count }
|
|
||||||
|
|
||||||
func childAt(index: Int) -> OutlineProvider? {
|
|
||||||
return self.osVersions[index]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
SimDirs/Model/SimProductFamily.swift
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// SimProductFamily.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/24/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum SimProductFamily: String, Decodable {
|
||||||
|
case appleTV = "Apple TV"
|
||||||
|
case appleWatch = "Apple Watch"
|
||||||
|
case iPad
|
||||||
|
case iPhone
|
||||||
|
|
||||||
|
static let presentation : [SimProductFamily] = [.iPhone, .iPad, .appleWatch, .appleTV]
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SimProductFamily: PresentableItem {
|
||||||
|
var title : String { return self.rawValue }
|
||||||
|
var id : String { return self.rawValue }
|
||||||
|
|
||||||
|
var imageName : String {
|
||||||
|
switch self {
|
||||||
|
case .iPad: return "ipad"
|
||||||
|
case .iPhone: return "iphone"
|
||||||
|
case .appleTV: return "appletv"
|
||||||
|
case .appleWatch: return "applewatch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
130
SimDirs/Model/SimRuntime.swift
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
//
|
||||||
|
// SimRuntime.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/24/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct SimRuntime: Comparable, Decodable {
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case availabilityError
|
||||||
|
case bundlePath
|
||||||
|
case buildversion
|
||||||
|
case identifier
|
||||||
|
case isAvailable
|
||||||
|
case isInternal
|
||||||
|
case name
|
||||||
|
case platform
|
||||||
|
case runtimeRoot
|
||||||
|
case supportedDeviceTypes
|
||||||
|
case version
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DeviceType: Decodable {
|
||||||
|
let name : String
|
||||||
|
let bundlePath : String
|
||||||
|
let identifier : String
|
||||||
|
let productFamily : SimProductFamily
|
||||||
|
|
||||||
|
init(canonical: SimDeviceType) {
|
||||||
|
name = canonical.name
|
||||||
|
bundlePath = canonical.bundlePath
|
||||||
|
identifier = canonical.identifier
|
||||||
|
productFamily = canonical.productFamily
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let name : String
|
||||||
|
let version : String
|
||||||
|
let identifier : String
|
||||||
|
let platform : SimPlatform
|
||||||
|
|
||||||
|
let bundlePath : String
|
||||||
|
let buildversion : String
|
||||||
|
let runtimeRoot : String
|
||||||
|
let isInternal : Bool
|
||||||
|
let isAvailable : Bool
|
||||||
|
var supportedDeviceTypes : [DeviceType]
|
||||||
|
let availabilityError : String?
|
||||||
|
|
||||||
|
var devices = [SimDevice]()
|
||||||
|
var isPlaceholder = false
|
||||||
|
|
||||||
|
static func < (lhs: SimRuntime, rhs: SimRuntime) -> Bool {
|
||||||
|
return lhs.name < rhs.name
|
||||||
|
}
|
||||||
|
|
||||||
|
static func == (lhs: SimRuntime, rhs: SimRuntime) -> Bool {
|
||||||
|
return lhs.identifier == rhs.identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
init(platformID: String) throws {
|
||||||
|
guard let lastComponent = platformID.split(separator: ".").last else { throw SimError.deviceParsingFailure }
|
||||||
|
let vComps = lastComponent.split(separator: "-")
|
||||||
|
|
||||||
|
if vComps.count == 3 {
|
||||||
|
guard let compPlatform = SimPlatform(rawValue: String(vComps[0])) else { throw SimError.deviceParsingFailure }
|
||||||
|
guard let major = Int(vComps[1]) else { throw SimError.deviceParsingFailure }
|
||||||
|
guard let minor = Int(vComps[2]) else { throw SimError.deviceParsingFailure }
|
||||||
|
|
||||||
|
platform = compPlatform
|
||||||
|
version = "\(major).\(minor)"
|
||||||
|
name = "\(platform) \(version)"
|
||||||
|
identifier = platformID
|
||||||
|
|
||||||
|
bundlePath = ""
|
||||||
|
buildversion = ""
|
||||||
|
runtimeRoot = ""
|
||||||
|
isInternal = false
|
||||||
|
isAvailable = false
|
||||||
|
supportedDeviceTypes = []
|
||||||
|
availabilityError = "Missing runtime"
|
||||||
|
isPlaceholder = true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw SimError.deviceParsingFailure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func supports(deviceType: SimDeviceType) -> Bool {
|
||||||
|
return supportedDeviceTypes.contains { $0.identifier == deviceType.identifier }
|
||||||
|
}
|
||||||
|
|
||||||
|
func supports(platform: SimPlatform) -> Bool {
|
||||||
|
return self.platform == platform
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func setDevices(_ devices: [SimDevice], from devTypes: [SimDeviceType]) {
|
||||||
|
self.devices = devices
|
||||||
|
|
||||||
|
// If this runtime is a placeholder it will be missing supported device types
|
||||||
|
// create device type stubs based on the devices being added using supplied
|
||||||
|
// fully described device types
|
||||||
|
|
||||||
|
if isPlaceholder {
|
||||||
|
let devTypeIDs = Set(devices.map({ $0.deviceTypeIdentifier }))
|
||||||
|
|
||||||
|
self.supportedDeviceTypes = devTypeIDs.compactMap { devTypeID in
|
||||||
|
devTypes.first(where: { $0.identifier == devTypeID }).map({ SimRuntime.DeviceType(canonical: $0) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SimRuntime: PresentableItem {
|
||||||
|
var title : String { return name }
|
||||||
|
var id : String { return identifier }
|
||||||
|
var imageName : String { return "v.circle" }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Array where Element == SimRuntime {
|
||||||
|
mutating func indexOfMatchedOrCreated(identifier: String) throws -> Index {
|
||||||
|
return try firstIndex { $0.identifier == identifier } ?? {
|
||||||
|
try self.append(SimRuntime(platformID: identifier))
|
||||||
|
|
||||||
|
return self.endIndex - 1
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
<key>com.apple.security.app-sandbox</key>
|
||||||
|
<false/>
|
||||||
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
36
SimDirs/SimDirsApp.swift
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// SimDirsApp.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/23/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct SimDirsApp: App {
|
||||||
|
@StateObject private var modelData = PresentableModel()
|
||||||
|
|
||||||
|
var body: some Scene {
|
||||||
|
WindowGroup {
|
||||||
|
ContentView()
|
||||||
|
.environmentObject(modelData)
|
||||||
|
}
|
||||||
|
.commands {
|
||||||
|
SimCommands()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SimCommands: Commands {
|
||||||
|
var body: some Commands {
|
||||||
|
SidebarCommands()
|
||||||
|
|
||||||
|
CommandMenu("Commands") {
|
||||||
|
Button("Command") {
|
||||||
|
print("Command")
|
||||||
|
}
|
||||||
|
.keyboardShortcut("f", modifiers: [.shift, .option])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
//
|
|
||||||
// Support.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 4/30/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
// Assorted convenience extensions
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension Array {
|
|
||||||
mutating func match(_ predicate: (Element) -> Bool, orMake: () -> Element) -> Element {
|
|
||||||
let element : Element
|
|
||||||
|
|
||||||
if let match = self.first(where: predicate) {
|
|
||||||
element = match
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
element = orMake()
|
|
||||||
self.append(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
return element
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Collection {
|
|
||||||
subscript (safe index: Index) -> Iterator.Element? {
|
|
||||||
return indices.contains(index) ? self[index] : nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension String {
|
|
||||||
var validPath : Bool { return FileManager.default.fileExists(atPath: self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
extension NSURL {
|
|
||||||
var validPath : Bool { return self.path.map { FileManager.default.fileExists(atPath: $0) } ?? false }
|
|
||||||
}
|
|
||||||
|
|
||||||
extension PropertyListSerialization {
|
|
||||||
class func propertyListWithURL(_ url: URL) -> [String : AnyObject]? {
|
|
||||||
guard let plistData = try? Data(contentsOf: url) else { return nil }
|
|
||||||
let plist : [String : AnyObject]?
|
|
||||||
|
|
||||||
do {
|
|
||||||
plist = try PropertyListSerialization.propertyList(from: plistData, options: [], format: nil) as? [String : AnyObject]
|
|
||||||
} catch {
|
|
||||||
plist = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return plist
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
//
|
|
||||||
// CUICatalog.h
|
|
||||||
// Asset Catalog Tinkerer
|
|
||||||
//
|
|
||||||
// Created by Guilherme Rambo on 27/09/15.
|
|
||||||
// Copyright (c) 2014 Guilherme Rambo. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
@interface CUINamedImage : NSObject
|
|
||||||
|
|
||||||
@property (copy, nonatomic) NSString *name;
|
|
||||||
@property (readonly, nonatomic) int exifOrientation;
|
|
||||||
@property (readonly, nonatomic) BOOL isStructured;
|
|
||||||
@property (readonly, nonatomic) NSInteger templateRenderingMode;
|
|
||||||
@property (readonly, nonatomic) BOOL isTemplate;
|
|
||||||
@property (readonly, nonatomic) BOOL isVectorBased;
|
|
||||||
@property (readonly, nonatomic) BOOL hasSliceInformation;
|
|
||||||
@property (readonly, nonatomic) NSInteger resizingMode;
|
|
||||||
@property (readonly, nonatomic) int blendMode;
|
|
||||||
@property (readonly, nonatomic) CGFloat opacity;
|
|
||||||
@property (readonly, nonatomic) NSInteger imageType;
|
|
||||||
@property (readonly, nonatomic) CGFloat scale;
|
|
||||||
@property (readonly, nonatomic) NSSize size;
|
|
||||||
@property (readonly, nonatomic) CGImageRef image;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface CUICatalog : NSObject
|
|
||||||
|
|
||||||
+ (instancetype)systemUICatalog;
|
|
||||||
+ (instancetype)defaultUICatalog;
|
|
||||||
|
|
||||||
- (instancetype)initWithURL:(NSURL *)url error:(NSError **)outError;
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSArray *allImageNames;
|
|
||||||
- (NSArray *)imagesWithName:(NSString *)name;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
//
|
|
||||||
// CUINamedLayerStack.h
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 4/30/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "CUICatalog.h"
|
|
||||||
|
|
||||||
@interface CUINamedLayerStack : CUINamedImage
|
|
||||||
|
|
||||||
@property(retain, nonatomic) NSArray *layers; // @synthesize layers=_layers;
|
|
||||||
|
|
||||||
@property(readonly, nonatomic) struct CGImage *radiosityImage;
|
|
||||||
@property(readonly, nonatomic) struct CGImage *flattenedImage;
|
|
||||||
- (id)layerImageAtIndex:(unsigned long long)arg1;
|
|
||||||
@property(readonly, nonatomic) struct CGSize size;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface CUINamedLayerImage : CUINamedImage
|
|
||||||
|
|
||||||
@property(nonatomic) int blendMode; // @synthesize blendMode=_blendMode;
|
|
||||||
@property(nonatomic) double opacity; // @synthesize opacity=_opacity;
|
|
||||||
@property(nonatomic) struct CGRect frame; // @synthesize frame=_frame;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
//
|
|
||||||
// SimDirs-Bridge.h
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 4/30/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "CUICatalog.h"
|
|
||||||
#import "CUINamedLayerStack.h"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
//
|
|
||||||
// ActionCell.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 5/1/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
|
|
||||||
class ActionCell: NSView {
|
|
||||||
@IBOutlet weak var actionButton : NSButton!
|
|
||||||
var action : (() -> ())?
|
|
||||||
|
|
||||||
@IBAction func executeAction(_ sender: Any) {
|
|
||||||
action?()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
//
|
|
||||||
// DetailController.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 5/1/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
|
|
||||||
struct SimProperty {
|
|
||||||
enum Value {
|
|
||||||
case Text(text: String)
|
|
||||||
case Location(url: URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
let title : String
|
|
||||||
let value : Value
|
|
||||||
|
|
||||||
init(title: String, value: Value) {
|
|
||||||
self.title = title
|
|
||||||
self.value = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol PropertyProvider: AnyObject {
|
|
||||||
var header : String { get }
|
|
||||||
var image : NSImage? { get }
|
|
||||||
var properties : [SimProperty] { get }
|
|
||||||
}
|
|
||||||
|
|
||||||
class EmptyProvider: PropertyProvider {
|
|
||||||
let header = ""
|
|
||||||
let image : NSImage? = nil
|
|
||||||
let properties = [SimProperty]()
|
|
||||||
}
|
|
||||||
|
|
||||||
class DetailController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
|
|
||||||
@IBOutlet weak var headerLabel : NSTextField!
|
|
||||||
@IBOutlet weak var imageView : NSImageView!
|
|
||||||
@IBOutlet weak var propertyTable : NSTableView!
|
|
||||||
let emptyProvider = EmptyProvider()
|
|
||||||
var selectedItem : Any? { didSet { self.reload() } }
|
|
||||||
var selectedProvider : PropertyProvider { return (self.selectedItem as? PropertyProvider) ?? self.emptyProvider }
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
self.reload()
|
|
||||||
}
|
|
||||||
|
|
||||||
func reload() {
|
|
||||||
self.headerLabel.stringValue = self.selectedProvider.header
|
|
||||||
self.imageView.image = self.selectedProvider.image
|
|
||||||
self.propertyTable.reloadData()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - NSTableViewDataSource -
|
|
||||||
|
|
||||||
func numberOfRows(in tableView: NSTableView) -> Int {
|
|
||||||
return self.selectedProvider.properties.count
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - NSTableViewDelegate -
|
|
||||||
|
|
||||||
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
|
||||||
let selectedProperty = self.selectedProvider.properties[row]
|
|
||||||
let columnIdentifier = tableColumn?.identifier ?? NSUserInterfaceItemIdentifier("")
|
|
||||||
let view : NSView?
|
|
||||||
|
|
||||||
switch columnIdentifier.rawValue {
|
|
||||||
case "value":
|
|
||||||
switch selectedProperty.value {
|
|
||||||
case .Text(let text):
|
|
||||||
view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyValueCell"), owner: self)
|
|
||||||
(view as? NSTableCellView)?.textField?.stringValue = text
|
|
||||||
|
|
||||||
case .Location(let url):
|
|
||||||
view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyActionCell"), owner: self)
|
|
||||||
if let actionCell = view as? ActionCell {
|
|
||||||
actionCell.action = { NSWorkspace.shared.activateFileViewerSelecting([url]) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyTitleCell"), owner: self)
|
|
||||||
(view as? NSTableCellView)?.textField?.stringValue = selectedProperty.title
|
|
||||||
}
|
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
//
|
|
||||||
// DetailTableView.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 5/1/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
|
|
||||||
class DetailTableView: NSTableView {
|
|
||||||
override func drawGrid(inClipRect: NSRect) {
|
|
||||||
let lastRowRect = self.rect(ofRow: self.numberOfRows - 1)
|
|
||||||
let adjClipRect = NSRect(x: 0.0, y: 0.0, width: lastRowRect.width, height: lastRowRect.maxY)
|
|
||||||
|
|
||||||
super.drawGrid(inClipRect: NSIntersectionRect(inClipRect, adjClipRect))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
//
|
|
||||||
// SourceController.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 4/30/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
|
|
||||||
protocol OutlineProvider: AnyObject {
|
|
||||||
var outlineTitle : String { get }
|
|
||||||
var outlineImage : NSImage? { get }
|
|
||||||
var childCount : Int { get }
|
|
||||||
|
|
||||||
func childAt(index: Int) -> OutlineProvider?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension OutlineProvider {
|
|
||||||
var expandable : Bool { return self.childCount > 0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
class SourceController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate {
|
|
||||||
@IBOutlet weak var outlineView : NSOutlineView!
|
|
||||||
private var platforms = [SimPlatform]()
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
self.rescan(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - NSOutlineViewDataSource -
|
|
||||||
|
|
||||||
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
|
||||||
return (item as? OutlineProvider)?.childCount ?? self.platforms.count
|
|
||||||
}
|
|
||||||
|
|
||||||
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
|
|
||||||
return (item as? OutlineProvider)?.childAt(index: index) ?? self.platforms[index]
|
|
||||||
}
|
|
||||||
|
|
||||||
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
|
|
||||||
return (item as? OutlineProvider)?.expandable ?? (self.platforms.count > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - NSOutlineViewDelegate -
|
|
||||||
|
|
||||||
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
|
|
||||||
var view : NSTableCellView? = nil
|
|
||||||
var title = ""
|
|
||||||
var image : NSImage? = nil
|
|
||||||
|
|
||||||
if let outlineProvider = item as? OutlineProvider {
|
|
||||||
title = outlineProvider.outlineTitle
|
|
||||||
image = outlineProvider.outlineImage
|
|
||||||
}
|
|
||||||
|
|
||||||
if let outlineCell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(image != nil ? "ImageCell" : "TextCell"), owner: self) as? NSTableCellView {
|
|
||||||
outlineCell.textField?.stringValue = title
|
|
||||||
outlineCell.imageView?.image = image
|
|
||||||
view = outlineCell
|
|
||||||
}
|
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
|
|
||||||
return (item as? OutlineProvider)?.outlineImage != nil ? 24.0 : 20.0
|
|
||||||
}
|
|
||||||
|
|
||||||
func outlineViewSelectionDidChange(_ notification: Notification) {
|
|
||||||
if let thing = (self.parent as? NSSplitViewController)?.splitViewItems[safe: 1]?.viewController as? DetailController {
|
|
||||||
var selectedItem : Any? = nil
|
|
||||||
let row = self.outlineView.selectedRow
|
|
||||||
|
|
||||||
if row != NSNotFound {
|
|
||||||
selectedItem = self.outlineView.item(atRow: row)
|
|
||||||
}
|
|
||||||
|
|
||||||
thing.selectedItem = selectedItem
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Interaction -
|
|
||||||
|
|
||||||
@IBAction func rescan(_ sender: AnyObject?) {
|
|
||||||
self.platforms = SimPlatform.scan()
|
|
||||||
self.outlineView.reloadData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
//
|
|
||||||
// WindowController.swift
|
|
||||||
// SimDirs
|
|
||||||
//
|
|
||||||
// Created by Casey Fleser on 5/1/16.
|
|
||||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Cocoa
|
|
||||||
|
|
||||||
class WindowController: NSWindowController {
|
|
||||||
|
|
||||||
override func windowDidLoad() {
|
|
||||||
super.windowDidLoad()
|
|
||||||
|
|
||||||
self.window?.setFrameAutosaveName("main")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
38
SimDirs/Views/DeviceTypeView.swift
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
// DeviceTypeView.swift
|
||||||
|
// SimDirs
|
||||||
|
//
|
||||||
|
// Created by Casey Fleser on 5/25/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct DeviceTypeView: View {
|
||||||
|
var deviceType : SimDeviceType
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 2.0) {
|
||||||
|
// Text(deviceType.name)
|
||||||
|
// .font(.title)
|
||||||
|
// .padding(.bottom, 5.0)
|
||||||
|
Group {
|
||||||
|
Text("Product Family: \(deviceType.productFamily.title)")
|
||||||
|
Text("Model ID: \(deviceType.modelIdentifier)")
|
||||||
|
Text("Identifier: \(deviceType.identifier)")
|
||||||
|
Text("Min Runtime: \(deviceType.minRuntimeVersionString)")
|
||||||
|
Text("Max Runtime: \(UInt32.max == deviceType.maxRuntimeVersion ? "-" : deviceType.maxRuntimeVersionString)")
|
||||||
|
Text("Bundle Path: \(deviceType.bundlePath)")
|
||||||
|
}
|
||||||
|
.font(.subheadline)
|
||||||
|
}
|
||||||
|
// .background(Color.red)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DeviceTypeView_Previews: PreviewProvider {
|
||||||
|
static let model = PresentableModel().baseModel
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
DeviceTypeView(deviceType: model.deviceTypes[26])
|
||||||
|
}
|
||||||
|
}
|
||||||