diff --git a/SimDirs.xcodeproj/project.pbxproj b/SimDirs.xcodeproj/project.pbxproj index 5332ced..95d3eda 100644 --- a/SimDirs.xcodeproj/project.pbxproj +++ b/SimDirs.xcodeproj/project.pbxproj @@ -3,376 +3,399 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 55; objects = { /* Begin PBXBuildFile section */ - C9188EE01CD65DCB00F0F8B6 /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */; }; - C921B3C71CD6219F0091C1AD /* DetailController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3C51CD6219F0091C1AD /* DetailController.swift */; }; - C921B3CA1CD629180091C1AD /* DetailTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3C91CD629180091C1AD /* DetailTableView.swift */; }; - C921B3CC1CD63EF30091C1AD /* ActionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3CB1CD63EF30091C1AD /* ActionCell.swift */; }; - C948814E1CD3EA5500209C09 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C948814D1CD3EA5500209C09 /* AppDelegate.swift */; }; - C94881501CD3EA5500209C09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C948814F1CD3EA5500209C09 /* Assets.xcassets */; }; - C9AE594A1CD4EAD80090655C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9AE59481CD4EAD80090655C /* Main.storyboard */; }; - C9AE594C1CD4F1C70090655C /* SourceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9AE594B1CD4F1C70090655C /* SourceController.swift */; }; - C9ECF8A41CD4CEE300499965 /* SimPlatform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */; }; - C9ECF8A61CD4CF1600499965 /* SimOSVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */; }; - C9ECF8A81CD4CF4000499965 /* SimDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A71CD4CF4000499965 /* SimDevice.swift */; }; - C9ECF8AA1CD4CF5A00499965 /* SimApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A91CD4CF5A00499965 /* SimApp.swift */; }; - C9ECF8AC1CD4CF8400499965 /* Support.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8AB1CD4CF8400499965 /* Support.swift */; }; - C9ECF8B21CD4E26300499965 /* CoreUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9ECF8B11CD4E26300499965 /* CoreUI.framework */; }; + C982F859283B9F9000D491F4 /* SimDirsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F858283B9F9000D491F4 /* SimDirsApp.swift */; }; + C982F85B283B9F9000D491F4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F85A283B9F9000D491F4 /* ContentView.swift */; }; + C982F85D283B9F9200D491F4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C982F85C283B9F9200D491F4 /* Assets.xcassets */; }; + C982F860283B9F9200D491F4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */; }; + C982F86B283BA22100D491F4 /* SimPlatform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F86A283BA22100D491F4 /* SimPlatform.swift */; }; + C982F871283CE7B800D491F4 /* SimRuntime.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F870283CE7B800D491F4 /* SimRuntime.swift */; }; + C982F873283CE9AD00D491F4 /* SimDeviceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F872283CE9AD00D491F4 /* SimDeviceType.swift */; }; + C982F875283CEEBB00D491F4 /* SimDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F874283CEEBB00D491F4 /* SimDevice.swift */; }; + C982F877283D020C00D491F4 /* SimProductFamily.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F876283D020C00D491F4 /* SimProductFamily.swift */; }; + C982F879283D042E00D491F4 /* SimModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F878283D042E00D491F4 /* SimModel.swift */; }; + C982F87B283E40C800D491F4 /* SimCtl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87A283E40C800D491F4 /* SimCtl.swift */; }; + C982F87E283E57B200D491F4 /* PresentableModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87D283E57B200D491F4 /* PresentableModel.swift */; }; + C982F880283E57E600D491F4 /* PresentationItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87F283E57E600D491F4 /* PresentationItem.swift */; }; + C982F883283E813F00D491F4 /* DeviceTypeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F882283E813F00D491F4 /* DeviceTypeView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = ""; }; - C921B3C51CD6219F0091C1AD /* DetailController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailController.swift; sourceTree = ""; }; - C921B3C91CD629180091C1AD /* DetailTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailTableView.swift; sourceTree = ""; }; - C921B3CB1CD63EF30091C1AD /* ActionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionCell.swift; sourceTree = ""; }; - C948814B1CD3EA5500209C09 /* SimDirs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimDirs.app; sourceTree = BUILT_PRODUCTS_DIR; }; - C948814D1CD3EA5500209C09 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - C948814F1CD3EA5500209C09 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - C94881541CD3EA5500209C09 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C9AE59491CD4EAD80090655C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - C9AE594B1CD4F1C70090655C /* SourceController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceController.swift; sourceTree = ""; }; - C9AE594D1CD503850090655C /* CUINamedLayerStack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUINamedLayerStack.h; sourceTree = ""; }; - C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimPlatform.swift; sourceTree = ""; }; - C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimOSVersion.swift; sourceTree = ""; }; - C9ECF8A71CD4CF4000499965 /* SimDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimDevice.swift; sourceTree = ""; }; - C9ECF8A91CD4CF5A00499965 /* SimApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimApp.swift; sourceTree = ""; }; - C9ECF8AB1CD4CF8400499965 /* Support.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Support.swift; sourceTree = ""; }; - C9ECF8AF1CD4E13500499965 /* CUICatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUICatalog.h; sourceTree = ""; }; - C9ECF8B01CD4E14C00499965 /* SimDirs-Bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SimDirs-Bridge.h"; sourceTree = ""; }; - C9ECF8B11CD4E26300499965 /* CoreUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreUI.framework; path = /System/Library/PrivateFrameworks/CoreUI.framework; sourceTree = ""; }; + C982F855283B9F9000D491F4 /* SimDirs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimDirs.app; sourceTree = BUILT_PRODUCTS_DIR; }; + C982F858283B9F9000D491F4 /* SimDirsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDirsApp.swift; sourceTree = ""; }; + C982F85A283B9F9000D491F4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + C982F85C283B9F9200D491F4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + C982F861283B9F9200D491F4 /* SimDirs.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SimDirs.entitlements; sourceTree = ""; }; + C982F86A283BA22100D491F4 /* SimPlatform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimPlatform.swift; sourceTree = ""; }; + C982F870283CE7B800D491F4 /* SimRuntime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimRuntime.swift; sourceTree = ""; }; + C982F872283CE9AD00D491F4 /* SimDeviceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDeviceType.swift; sourceTree = ""; }; + C982F874283CEEBB00D491F4 /* SimDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDevice.swift; sourceTree = ""; }; + C982F876283D020C00D491F4 /* SimProductFamily.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimProductFamily.swift; sourceTree = ""; }; + C982F878283D042E00D491F4 /* SimModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimModel.swift; sourceTree = ""; }; + C982F87A283E40C800D491F4 /* SimCtl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimCtl.swift; sourceTree = ""; }; + C982F87D283E57B200D491F4 /* PresentableModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentableModel.swift; sourceTree = ""; }; + C982F87F283E57E600D491F4 /* PresentationItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationItem.swift; sourceTree = ""; }; + C982F882283E813F00D491F4 /* DeviceTypeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceTypeView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - C94881481CD3EA5500209C09 /* Frameworks */ = { + C982F852283B9F9000D491F4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - C9ECF8B21CD4E26300499965 /* CoreUI.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - C9194D1C19C09A03004178EB = { + C982F84C283B9F9000D491F4 = { isa = PBXGroup; children = ( - C948814C1CD3EA5500209C09 /* SimDirs */, - C9ECF8B31CD4E27B00499965 /* Frameworks */, - C9194D2619C09A03004178EB /* Products */, + C982F857283B9F9000D491F4 /* SimDirs */, + C982F856283B9F9000D491F4 /* Products */, ); sourceTree = ""; }; - C9194D2619C09A03004178EB /* Products */ = { + C982F856283B9F9000D491F4 /* Products */ = { isa = PBXGroup; children = ( - C948814B1CD3EA5500209C09 /* SimDirs.app */, + C982F855283B9F9000D491F4 /* SimDirs.app */, ); name = Products; sourceTree = ""; }; - C948814C1CD3EA5500209C09 /* SimDirs */ = { + C982F857283B9F9000D491F4 /* SimDirs */ = { isa = PBXGroup; children = ( - C9ECF8A21CD4CEC800499965 /* Model */, - C9ECF8AE1CD4E13500499965 /* Support */, - C9ECF8B41CD4E96A00499965 /* UI */, - C948814D1CD3EA5500209C09 /* AppDelegate.swift */, - C9ECF8AB1CD4CF8400499965 /* Support.swift */, - C948814F1CD3EA5500209C09 /* Assets.xcassets */, - C9AE59481CD4EAD80090655C /* Main.storyboard */, - C94881541CD3EA5500209C09 /* Info.plist */, + C982F858283B9F9000D491F4 /* SimDirsApp.swift */, + C982F85A283B9F9000D491F4 /* ContentView.swift */, + C982F867283BA09B00D491F4 /* Model */, + C982F881283E7F0400D491F4 /* Views */, + C982F85C283B9F9200D491F4 /* Assets.xcassets */, + C982F861283B9F9200D491F4 /* SimDirs.entitlements */, + C982F85E283B9F9200D491F4 /* Preview Content */, ); path = SimDirs; sourceTree = ""; }; - C9ECF8A21CD4CEC800499965 /* Model */ = { + C982F85E283B9F9200D491F4 /* Preview Content */ = { isa = PBXGroup; children = ( - C9ECF8A91CD4CF5A00499965 /* SimApp.swift */, - C9ECF8A71CD4CF4000499965 /* SimDevice.swift */, - C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */, - C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */, + C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 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; sourceTree = ""; }; - C9ECF8AE1CD4E13500499965 /* Support */ = { + C982F87C283E579900D491F4 /* Presentation */ = { isa = PBXGroup; children = ( - C9ECF8AF1CD4E13500499965 /* CUICatalog.h */, - C9AE594D1CD503850090655C /* CUINamedLayerStack.h */, - C9ECF8B01CD4E14C00499965 /* SimDirs-Bridge.h */, + C982F87D283E57B200D491F4 /* PresentableModel.swift */, + C982F87F283E57E600D491F4 /* PresentationItem.swift */, ); - path = Support; + path = Presentation; sourceTree = ""; }; - C9ECF8B31CD4E27B00499965 /* Frameworks */ = { + C982F881283E7F0400D491F4 /* Views */ = { isa = PBXGroup; children = ( - C9ECF8B11CD4E26300499965 /* CoreUI.framework */, + C982F882283E813F00D491F4 /* DeviceTypeView.swift */, ); - name = Frameworks; - sourceTree = ""; - }; - C9ECF8B41CD4E96A00499965 /* UI */ = { - isa = PBXGroup; - children = ( - C921B3CB1CD63EF30091C1AD /* ActionCell.swift */, - C921B3C51CD6219F0091C1AD /* DetailController.swift */, - C921B3C91CD629180091C1AD /* DetailTableView.swift */, - C9AE594B1CD4F1C70090655C /* SourceController.swift */, - C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */, - ); - path = UI; + path = Views; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - C948814A1CD3EA5500209C09 /* SimDirs */ = { + C982F854283B9F9000D491F4 /* SimDirs */ = { isa = PBXNativeTarget; - buildConfigurationList = C94881571CD3EA5500209C09 /* Build configuration list for PBXNativeTarget "SimDirs" */; + buildConfigurationList = C982F864283B9F9200D491F4 /* Build configuration list for PBXNativeTarget "SimDirs" */; buildPhases = ( - C94881471CD3EA5500209C09 /* Sources */, - C94881481CD3EA5500209C09 /* Frameworks */, - C94881491CD3EA5500209C09 /* Resources */, + C982F851283B9F9000D491F4 /* Sources */, + C982F852283B9F9000D491F4 /* Frameworks */, + C982F853283B9F9000D491F4 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = SimDirs; - productName = SimDirs2; - productReference = C948814B1CD3EA5500209C09 /* SimDirs.app */; + productName = SimDirs; + productReference = C982F855283B9F9000D491F4 /* SimDirs.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - C9194D1D19C09A03004178EB /* Project object */ = { + C982F84D283B9F9000D491F4 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0600; - ORGANIZATIONNAME = "Quiet Spark"; + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1340; + LastUpgradeCheck = 1340; TargetAttributes = { - C948814A1CD3EA5500209C09 = { - CreatedOnToolsVersion = 7.3; + C982F854283B9F9000D491F4 = { + CreatedOnToolsVersion = 13.4; }; }; }; - buildConfigurationList = C9194D2019C09A03004178EB /* Build configuration list for PBXProject "SimDirs" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + buildConfigurationList = C982F850283B9F9000D491F4 /* Build configuration list for PBXProject "SimDirs" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( - English, en, Base, ); - mainGroup = C9194D1C19C09A03004178EB; - productRefGroup = C9194D2619C09A03004178EB /* Products */; + mainGroup = C982F84C283B9F9000D491F4; + productRefGroup = C982F856283B9F9000D491F4 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - C948814A1CD3EA5500209C09 /* SimDirs */, + C982F854283B9F9000D491F4 /* SimDirs */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - C94881491CD3EA5500209C09 /* Resources */ = { + C982F853283B9F9000D491F4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C9AE594A1CD4EAD80090655C /* Main.storyboard in Resources */, - C94881501CD3EA5500209C09 /* Assets.xcassets in Resources */, + C982F860283B9F9200D491F4 /* Preview Assets.xcassets in Resources */, + C982F85D283B9F9200D491F4 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - C94881471CD3EA5500209C09 /* Sources */ = { + C982F851283B9F9000D491F4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C921B3C71CD6219F0091C1AD /* DetailController.swift in Sources */, - C921B3CC1CD63EF30091C1AD /* ActionCell.swift in Sources */, - C9ECF8A41CD4CEE300499965 /* SimPlatform.swift in Sources */, - C9ECF8A61CD4CF1600499965 /* SimOSVersion.swift in Sources */, - C921B3CA1CD629180091C1AD /* DetailTableView.swift in Sources */, - C9AE594C1CD4F1C70090655C /* SourceController.swift in Sources */, - C9ECF8AA1CD4CF5A00499965 /* SimApp.swift in Sources */, - C9188EE01CD65DCB00F0F8B6 /* WindowController.swift in Sources */, - C948814E1CD3EA5500209C09 /* AppDelegate.swift in Sources */, - C9ECF8A81CD4CF4000499965 /* SimDevice.swift in Sources */, - C9ECF8AC1CD4CF8400499965 /* Support.swift in Sources */, + C982F883283E813F00D491F4 /* DeviceTypeView.swift in Sources */, + C982F85B283B9F9000D491F4 /* ContentView.swift in Sources */, + C982F875283CEEBB00D491F4 /* SimDevice.swift in Sources */, + C982F873283CE9AD00D491F4 /* SimDeviceType.swift in Sources */, + C982F877283D020C00D491F4 /* SimProductFamily.swift in Sources */, + C982F859283B9F9000D491F4 /* SimDirsApp.swift in Sources */, + C982F871283CE7B800D491F4 /* SimRuntime.swift in Sources */, + C982F86B283BA22100D491F4 /* SimPlatform.swift in Sources */, + C982F87E283E57B200D491F4 /* PresentableModel.swift in Sources */, + C982F880283E57E600D491F4 /* PresentationItem.swift in Sources */, + C982F879283D042E00D491F4 /* SimModel.swift in Sources */, + C982F87B283E40C800D491F4 /* SimCtl.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXVariantGroup section */ - C9AE59481CD4EAD80090655C /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - C9AE59491CD4EAD80090655C /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ - C9194D4019C09A03004178EB /* Debug */ = { + C982F862283B9F9200D491F4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; + 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; - CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; 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 = YES; + MACOSX_DEPLOYMENT_TARGET = 12.3; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; - SWIFT_VERSION = 5.0; - }; - 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_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; 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; buildSettings = { 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; - COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( + 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)", - "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + "@executable_path/../Frameworks", ); - 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; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.sgntn.SimDirs; 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; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - C9194D2019C09A03004178EB /* Build configuration list for PBXProject "SimDirs" */ = { + C982F850283B9F9000D491F4 /* Build configuration list for PBXProject "SimDirs" */ = { isa = XCConfigurationList; buildConfigurations = ( - C9194D4019C09A03004178EB /* Debug */, - C9194D4119C09A03004178EB /* Release */, + C982F862283B9F9200D491F4 /* Debug */, + C982F863283B9F9200D491F4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C94881571CD3EA5500209C09 /* Build configuration list for PBXNativeTarget "SimDirs" */ = { + C982F864283B9F9200D491F4 /* Build configuration list for PBXNativeTarget "SimDirs" */ = { isa = XCConfigurationList; buildConfigurations = ( - C94881551CD3EA5500209C09 /* Debug */, - C94881561CD3EA5500209C09 /* Release */, + C982F865283B9F9200D491F4 /* Debug */, + C982F866283B9F9200D491F4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = C9194D1D19C09A03004178EB /* Project object */; + rootObject = C982F84D283B9F9000D491F4 /* Project object */; } diff --git a/SimDirs.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/SimDirs.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 8af9d27..919434a 100644 --- a/SimDirs.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/SimDirs.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/SimDirs/AppDelegate.swift b/SimDirs/AppDelegate.swift deleted file mode 100644 index 0bc087b..0000000 --- a/SimDirs/AppDelegate.swift +++ /dev/null @@ -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 - } -} - diff --git a/SimDirs/Assets.xcassets/AccentColor.colorset/Contents.json b/SimDirs/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/SimDirs/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/Contents.json b/SimDirs/Assets.xcassets/AppIcon.appiconset/Contents.json index 7cd4f8e..3f00db4 100644 --- a/SimDirs/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/SimDirs/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,68 +1,58 @@ { "images" : [ { - "size" : "16x16", "idiom" : "mac", - "filename" : "icon_16x16.png", - "scale" : "1x" + "scale" : "1x", + "size" : "16x16" }, { - "size" : "16x16", "idiom" : "mac", - "filename" : "icon_16x16@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "16x16" }, { - "size" : "32x32", "idiom" : "mac", - "filename" : "icon_32x32.png", - "scale" : "1x" + "scale" : "1x", + "size" : "32x32" }, { - "size" : "32x32", "idiom" : "mac", - "filename" : "icon_32x32@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "32x32" }, { - "size" : "128x128", "idiom" : "mac", - "filename" : "icon_128x128.png", - "scale" : "1x" + "scale" : "1x", + "size" : "128x128" }, { - "size" : "128x128", "idiom" : "mac", - "filename" : "icon_128x128@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "128x128" }, { - "size" : "256x256", "idiom" : "mac", - "filename" : "icon_256x256.png", - "scale" : "1x" + "scale" : "1x", + "size" : "256x256" }, { - "size" : "256x256", "idiom" : "mac", - "filename" : "icon_256x256@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "256x256" }, { - "size" : "512x512", "idiom" : "mac", - "filename" : "icon_512x512.png", - "scale" : "1x" + "scale" : "1x", + "size" : "512x512" }, { - "size" : "512x512", "idiom" : "mac", - "filename" : "icon_512x512@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "512x512" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_128x128.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_128x128.png deleted file mode 100644 index 1a5f5df..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_128x128.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png deleted file mode 100644 index 87819d2..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_16x16.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_16x16.png deleted file mode 100644 index 62a8966..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_16x16.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png deleted file mode 100644 index d2f74db..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_256x256.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_256x256.png deleted file mode 100644 index 87819d2..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_256x256.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png deleted file mode 100644 index d4d7ef9..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_32x32.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_32x32.png deleted file mode 100644 index d2f74db..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_32x32.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png deleted file mode 100644 index 4cab5e2..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_512x512.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_512x512.png deleted file mode 100644 index d4d7ef9..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_512x512.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png b/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png deleted file mode 100644 index 04342ff..0000000 Binary files a/SimDirs/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/Contents.json b/SimDirs/Assets.xcassets/Contents.json index da4a164..73c0059 100644 --- a/SimDirs/Assets.xcassets/Contents.json +++ b/SimDirs/Assets.xcassets/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/SimDirs/Assets.xcassets/default_icon.imageset/Contents.json b/SimDirs/Assets.xcassets/default_icon.imageset/Contents.json deleted file mode 100644 index 1201a35..0000000 --- a/SimDirs/Assets.xcassets/default_icon.imageset/Contents.json +++ /dev/null @@ -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" - } -} \ No newline at end of file diff --git a/SimDirs/Assets.xcassets/default_icon.imageset/default_icon.png b/SimDirs/Assets.xcassets/default_icon.imageset/default_icon.png deleted file mode 100644 index f614703..0000000 Binary files a/SimDirs/Assets.xcassets/default_icon.imageset/default_icon.png and /dev/null differ diff --git a/SimDirs/Assets.xcassets/default_icon.imageset/defaultt_icon@2x.png b/SimDirs/Assets.xcassets/default_icon.imageset/defaultt_icon@2x.png deleted file mode 100644 index 16a0748..0000000 Binary files a/SimDirs/Assets.xcassets/default_icon.imageset/defaultt_icon@2x.png and /dev/null differ diff --git a/SimDirs/Base.lproj/Main.storyboard b/SimDirs/Base.lproj/Main.storyboard deleted file mode 100644 index 41f8a0a..0000000 --- a/SimDirs/Base.lproj/Main.storyboard +++ /dev/null @@ -1,488 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SimDirs/ContentView.swift b/SimDirs/ContentView.swift new file mode 100644 index 0000000..7ce8dd5 --- /dev/null +++ b/SimDirs/ContentView.swift @@ -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()) + } +} diff --git a/SimDirs/Info.plist b/SimDirs/Info.plist deleted file mode 100644 index b65dfc1..0000000 --- a/SimDirs/Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.6 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - Copyright © 2016 Quiet Spark. All rights reserved. - NSMainStoryboardFile - Main - NSPrincipalClass - NSApplication - - diff --git a/SimDirs/Model/Presentation/PresentableModel.swift b/SimDirs/Model/Presentation/PresentableModel.swift new file mode 100644 index 0000000..babc609 --- /dev/null +++ b/SimDirs/Model/Presentation/PresentableModel.swift @@ -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) + } + } + } +} + diff --git a/SimDirs/Model/Presentation/PresentationItem.swift b/SimDirs/Model/Presentation/PresentationItem.swift new file mode 100644 index 0000000..af9f13d --- /dev/null +++ b/SimDirs/Model/Presentation/PresentationItem.swift @@ -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 { + 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 + } +} diff --git a/SimDirs/Model/SimApp.swift b/SimDirs/Model/SimApp.swift deleted file mode 100644 index 2ce8d79..0000000 --- a/SimDirs/Model/SimApp.swift +++ /dev/null @@ -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 - } -} diff --git a/SimDirs/Model/SimCtl.swift b/SimDirs/Model/SimCtl.swift new file mode 100644 index 0000000..1d8a891 --- /dev/null +++ b/SimDirs/Model/SimCtl.swift @@ -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) + } + } +} diff --git a/SimDirs/Model/SimDevice.swift b/SimDirs/Model/SimDevice.swift index cf7ead5..7d906f9 100644 --- a/SimDirs/Model/SimDevice.swift +++ b/SimDirs/Model/SimDevice.swift @@ -2,150 +2,31 @@ // SimDevice.swift // SimDirs // -// Created by Casey Fleser on 4/30/16. -// Copyright © 2016 Quiet Spark. All rights reserved. +// Created by Casey Fleser on 5/24/22. // import Foundation -class SimDevice: OutlineProvider, PropertyProvider { - let name : String - let type : String - let udid : String - let baseURL : URL - var platformName = "Unknown" - var platformVersion = "" - var platformBuild = "" - var apps = [SimApp]() +struct SimDevice: Decodable { + let name : String + let udid : String + let state : String + let dataPath : String + let dataPathSize : Int + let logPath : String + let isAvailable : Bool + let deviceTypeIdentifier : String + let availabilityError : String? - init(name: String, type: String, udid: String, baseURL: URL) { - self.name = name - 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)) - ] - } + func isDeviceOfType(_ deviceType: SimDeviceType) -> Bool { + return deviceTypeIdentifier == deviceType.identifier + } } + +extension SimDevice: PresentableItem { + var title : String { return name } + var id : String { return udid } + + var imageName : String { return "shippingbox" } // FIXME +} + diff --git a/SimDirs/Model/SimDeviceType.swift b/SimDirs/Model/SimDeviceType.swift new file mode 100644 index 0000000..b65754b --- /dev/null +++ b/SimDirs/Model/SimDeviceType.swift @@ -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 } +} diff --git a/SimDirs/Model/SimModel.swift b/SimDirs/Model/SimModel.swift new file mode 100644 index 0000000..6e29426 --- /dev/null +++ b/SimDirs/Model/SimModel.swift @@ -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)") + } + } +} diff --git a/SimDirs/Model/SimOSVersion.swift b/SimDirs/Model/SimOSVersion.swift deleted file mode 100644 index 645f4f5..0000000 --- a/SimDirs/Model/SimOSVersion.swift +++ /dev/null @@ -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] - } -} diff --git a/SimDirs/Model/SimPlatform.swift b/SimDirs/Model/SimPlatform.swift index ef179c3..3251eb6 100644 --- a/SimDirs/Model/SimPlatform.swift +++ b/SimDirs/Model/SimPlatform.swift @@ -2,71 +2,27 @@ // SimPlatform.swift // SimDirs // -// Created by Casey Fleser on 4/30/16. -// Copyright © 2016 Quiet Spark. All rights reserved. +// Created by Casey Fleser on 5/23/22. // import Foundation -class SimPlatform: OutlineProvider { - let name : String - var osVersions = [SimOSVersion]() - - 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) }) +enum SimPlatform: String, Decodable { + case iOS + case tvOS + case watchOS - if let platformName = runtimeComponents.first { - let platform = platforms.match({ $0.name == platformName }, orMake: { SimPlatform(runtimeComponents: runtimeComponents, deviceInfo: deviceInfo) }) - - platform.updateWith(runtimeComponents, deviceInfo: deviceInfo, baseURL: baseURL) - } - } - } - } - - for platform in platforms { - platform.completeScan() - } - - 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] - } + static let presentation : [SimPlatform] = [.iOS, .watchOS, .tvOS] +} + +extension SimPlatform: PresentableItem { + var title : String { return self.rawValue } + var id : String { return self.rawValue } + var imageName : String { + switch self { + case .iOS: return "iphone" + case .tvOS: return "appletv" + case .watchOS: return "applewatch" + } + } } diff --git a/SimDirs/Model/SimProductFamily.swift b/SimDirs/Model/SimProductFamily.swift new file mode 100644 index 0000000..e01e9a1 --- /dev/null +++ b/SimDirs/Model/SimProductFamily.swift @@ -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" + } + } +} diff --git a/SimDirs/Model/SimRuntime.swift b/SimDirs/Model/SimRuntime.swift new file mode 100644 index 0000000..0a6b7a1 --- /dev/null +++ b/SimDirs/Model/SimRuntime.swift @@ -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 + }() + } +} diff --git a/SimDirs/Preview Content/Preview Assets.xcassets/Contents.json b/SimDirs/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/SimDirs/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SimDirs.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/SimDirs/SimDirs.entitlements similarity index 63% rename from SimDirs.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings rename to SimDirs/SimDirs.entitlements index 54782e3..311b32b 100644 --- a/SimDirs.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/SimDirs/SimDirs.entitlements @@ -2,7 +2,9 @@ - IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only diff --git a/SimDirs/SimDirsApp.swift b/SimDirs/SimDirsApp.swift new file mode 100644 index 0000000..b1eb712 --- /dev/null +++ b/SimDirs/SimDirsApp.swift @@ -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]) + } + } +} diff --git a/SimDirs/Support.swift b/SimDirs/Support.swift deleted file mode 100644 index 1772587..0000000 --- a/SimDirs/Support.swift +++ /dev/null @@ -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 - } -} - diff --git a/SimDirs/Support/CUICatalog.h b/SimDirs/Support/CUICatalog.h deleted file mode 100755 index c0fb90c..0000000 --- a/SimDirs/Support/CUICatalog.h +++ /dev/null @@ -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 - -@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 \ No newline at end of file diff --git a/SimDirs/Support/CUINamedLayerStack.h b/SimDirs/Support/CUINamedLayerStack.h deleted file mode 100644 index 0a2d92d..0000000 --- a/SimDirs/Support/CUINamedLayerStack.h +++ /dev/null @@ -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 diff --git a/SimDirs/Support/SimDirs-Bridge.h b/SimDirs/Support/SimDirs-Bridge.h deleted file mode 100644 index a9c3b63..0000000 --- a/SimDirs/Support/SimDirs-Bridge.h +++ /dev/null @@ -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" diff --git a/SimDirs/UI/ActionCell.swift b/SimDirs/UI/ActionCell.swift deleted file mode 100644 index 5fa5396..0000000 --- a/SimDirs/UI/ActionCell.swift +++ /dev/null @@ -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?() - } -} diff --git a/SimDirs/UI/DetailController.swift b/SimDirs/UI/DetailController.swift deleted file mode 100644 index 7c82a25..0000000 --- a/SimDirs/UI/DetailController.swift +++ /dev/null @@ -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 - } -} diff --git a/SimDirs/UI/DetailTableView.swift b/SimDirs/UI/DetailTableView.swift deleted file mode 100644 index 66b0c53..0000000 --- a/SimDirs/UI/DetailTableView.swift +++ /dev/null @@ -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)) - } -} diff --git a/SimDirs/UI/SourceController.swift b/SimDirs/UI/SourceController.swift deleted file mode 100644 index 743cad0..0000000 --- a/SimDirs/UI/SourceController.swift +++ /dev/null @@ -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() - } -} diff --git a/SimDirs/UI/WindowController.swift b/SimDirs/UI/WindowController.swift deleted file mode 100644 index 46a4ee9..0000000 --- a/SimDirs/UI/WindowController.swift +++ /dev/null @@ -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") - } - -} diff --git a/SimDirs/Views/DeviceTypeView.swift b/SimDirs/Views/DeviceTypeView.swift new file mode 100644 index 0000000..679838e --- /dev/null +++ b/SimDirs/Views/DeviceTypeView.swift @@ -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]) + } +}