mirror of
https://github.com/ninxsoft/Mist.git
synced 2025-06-01 07:48:24 -04:00
Merge pull request #20 from ninxsoft/feature-custom-seed-preferences
Feature custom seed preferences
This commit is contained in:
commit
19e528c693
24 changed files with 589 additions and 115 deletions
36
.github/workflows/build.yml
vendored
Normal file
36
.github/workflows/build.yml
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
name: Build
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: macos-12
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: swift-actions/setup-swift@v1
|
||||||
|
- name: Install Apple Developer Application Certificate
|
||||||
|
env:
|
||||||
|
APPLE_DEVELOPER_CERTIFICATE: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE }}
|
||||||
|
APPLE_DEVELOPER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }}
|
||||||
|
APPLE_DEVELOPER_CERTIFICATE_AUTHORITY: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_AUTHORITY }}
|
||||||
|
APPLE_DEVELOPER_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_DEVELOPER_KEYCHAIN_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
CERTIFICATE_PATH="$RUNNER_TEMP/apple-developer-application-certificate.p12"
|
||||||
|
CERTIFICATE_AUTHORITY_PATH="$RUNNER_TEMP/apple-developer-certificate-authority.cer"
|
||||||
|
KEYCHAIN_PATH="$RUNNER_TEMP/apple-developer.keychain-db"
|
||||||
|
echo -n "$APPLE_DEVELOPER_CERTIFICATE" | base64 --decode --output "$CERTIFICATE_PATH"
|
||||||
|
echo -n "$APPLE_DEVELOPER_CERTIFICATE_AUTHORITY" | base64 --decode --output "$CERTIFICATE_AUTHORITY_PATH"
|
||||||
|
security create-keychain -p "$APPLE_DEVELOPER_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||||
|
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
|
||||||
|
security unlock-keychain -p "$APPLE_DEVELOPER_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||||
|
security import "$CERTIFICATE_PATH" -P "$APPLE_DEVELOPER_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
|
||||||
|
security import "$CERTIFICATE_AUTHORITY_PATH" -P "$APPLE_DEVELOPER_CERTIFICATE_PASSWORD" -A -t cert -f pkcs7 -k "$KEYCHAIN_PATH"
|
||||||
|
security list-keychain -d user -s "$KEYCHAIN_PATH"
|
||||||
|
- name: Archive Mist
|
||||||
|
run: xcodebuild -scheme Mist clean archive -configuration release -archivePath Mist -quiet
|
||||||
|
- name: Export Mist
|
||||||
|
run: xcodebuild -exportArchive -archivePath Mist.xcarchive -exportPath Export -exportOptionsPlist ExportOptions.plist
|
||||||
|
- name: Print Mist version
|
||||||
|
run: defaults read "$GITHUB_WORKSPACE/Export/Mist.app/Contents/Info.plist" CFBundleShortVersionString
|
||||||
|
- name: Remove Apple Developer Keychain
|
||||||
|
if: ${{ always() }}
|
||||||
|
run: security delete-keychain $RUNNER_TEMP/apple-developer.keychain-db
|
24
.github/workflows/linting.yml
vendored
Normal file
24
.github/workflows/linting.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
name: Linting
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
linting:
|
||||||
|
name: Linting
|
||||||
|
runs-on: macos-12
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Print SwiftLint version
|
||||||
|
run: swiftlint --version
|
||||||
|
- name: Run SwiftLint
|
||||||
|
run: swiftlint --strict
|
||||||
|
- name: Download DrString
|
||||||
|
run: curl --location --remote-name https://github.com/dduan/DrString/releases/latest/download/drstring-x86_64-apple-darwin.tar.gz
|
||||||
|
- name: Extract DrString
|
||||||
|
run: |
|
||||||
|
mkdir drstring-x86_64-apple-darwin
|
||||||
|
tar --extract --file drstring-x86_64-apple-darwin.tar.gz --directory drstring-x86_64-apple-darwin
|
||||||
|
- name: Add DrString to $PATH
|
||||||
|
run: echo "$GITHUB_WORKSPACE/drstring-x86_64-apple-darwin" >> $GITHUB_PATH
|
||||||
|
- name: Print DrString version
|
||||||
|
run: drstring --version
|
||||||
|
- name: Run DrString
|
||||||
|
run: drstring check --config-file .drstring.toml
|
10
.github/workflows/unit_tests.yml
vendored
Normal file
10
.github/workflows/unit_tests.yml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
name: Unit Tests
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
unit_tests:
|
||||||
|
name: Unit Tests
|
||||||
|
runs-on: macos-12
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Run Unit Tests
|
||||||
|
run: xcodebuild -scheme MistTests clean test -quiet || true
|
|
@ -1,9 +1,9 @@
|
||||||
excluded:
|
excluded:
|
||||||
- .build
|
- .build
|
||||||
|
|
||||||
closure_body_length:
|
large_tuple:
|
||||||
warning: 20
|
warning: 3
|
||||||
error: 40
|
error: 5
|
||||||
|
|
||||||
line_length:
|
line_length:
|
||||||
warning: 200
|
warning: 200
|
||||||
|
|
8
ExportOptions.plist
Normal file
8
ExportOptions.plist
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?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>method</key>
|
||||||
|
<string>developer-id</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -26,7 +26,7 @@
|
||||||
390451DC28573F1000E0B563 /* Dictionary+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451DB28573F1000E0B563 /* Dictionary+Extension.swift */; };
|
390451DC28573F1000E0B563 /* Dictionary+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451DB28573F1000E0B563 /* Dictionary+Extension.swift */; };
|
||||||
390451DF28573FAA00E0B563 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = 390451DE28573FAA00E0B563 /* Yams */; };
|
390451DF28573FAA00E0B563 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = 390451DE28573FAA00E0B563 /* Yams */; };
|
||||||
390451E1285740E800E0B563 /* Sequence+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E0285740E800E0B563 /* Sequence+Extension.swift */; };
|
390451E1285740E800E0B563 /* Sequence+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E0285740E800E0B563 /* Sequence+Extension.swift */; };
|
||||||
390451E528574F0000E0B563 /* Catalog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E428574F0000E0B563 /* Catalog.swift */; };
|
390451E528574F0000E0B563 /* CatalogType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E428574F0000E0B563 /* CatalogType.swift */; };
|
||||||
390451E72857510C00E0B563 /* TextTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E62857510B00E0B563 /* TextTag.swift */; };
|
390451E72857510C00E0B563 /* TextTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E62857510B00E0B563 /* TextTag.swift */; };
|
||||||
39148CFC28DD55B300011FF5 /* PathControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39148CFB28DD55B300011FF5 /* PathControl.swift */; };
|
39148CFC28DD55B300011FF5 /* PathControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39148CFB28DD55B300011FF5 /* PathControl.swift */; };
|
||||||
39252A77285A849F00956C74 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39252A76285A849F00956C74 /* AppDelegate.swift */; };
|
39252A77285A849F00956C74 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39252A76285A849F00956C74 /* AppDelegate.swift */; };
|
||||||
|
@ -94,7 +94,9 @@
|
||||||
398734D028603D9E00B4C357 /* UInt8+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398734CF28603D9E00B4C357 /* UInt8+Extension.swift */; };
|
398734D028603D9E00B4C357 /* UInt8+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398734CF28603D9E00B4C357 /* UInt8+Extension.swift */; };
|
||||||
398734D228603DE700B4C357 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398734D128603DE700B4C357 /* Array+Extension.swift */; };
|
398734D228603DE700B4C357 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398734D128603DE700B4C357 /* Array+Extension.swift */; };
|
||||||
398734D4286046B000B4C357 /* UInt32+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398734D3286046B000B4C357 /* UInt32+Extension.swift */; };
|
398734D4286046B000B4C357 /* UInt32+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398734D3286046B000B4C357 /* UInt32+Extension.swift */; };
|
||||||
39CF4E732859C03D009E708C /* CatalogRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CF4E722859C03D009E708C /* CatalogRow.swift */; };
|
39CB5E3D293F5C2E00CFDBB8 /* Catalog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CB5E3C293F5C2E00CFDBB8 /* Catalog.swift */; };
|
||||||
|
39CB5E3F2941486D00CFDBB8 /* CatalogSeedType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CB5E3E2941486D00CFDBB8 /* CatalogSeedType.swift */; };
|
||||||
|
39CB5E5429418A2900CFDBB8 /* MistTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CB5E5329418A2900CFDBB8 /* MistTests.swift */; };
|
||||||
39CF55A028614DD8006FB5D2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CF559F28614DD8006FB5D2 /* main.swift */; };
|
39CF55A028614DD8006FB5D2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CF559F28614DD8006FB5D2 /* main.swift */; };
|
||||||
39CF55AA286154A5006FB5D2 /* Blessed in Frameworks */ = {isa = PBXBuildFile; productRef = 39CF55A9286154A5006FB5D2 /* Blessed */; };
|
39CF55AA286154A5006FB5D2 /* Blessed in Frameworks */ = {isa = PBXBuildFile; productRef = 39CF55A9286154A5006FB5D2 /* Blessed */; };
|
||||||
39CF55AB286154D1006FB5D2 /* com.ninxsoft.mist.helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 39CF559D28614DD8006FB5D2 /* com.ninxsoft.mist.helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
39CF55AB286154D1006FB5D2 /* com.ninxsoft.mist.helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 39CF559D28614DD8006FB5D2 /* com.ninxsoft.mist.helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
|
@ -173,7 +175,7 @@
|
||||||
390451D928573ADC00E0B563 /* ExportListType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportListType.swift; sourceTree = "<group>"; };
|
390451D928573ADC00E0B563 /* ExportListType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportListType.swift; sourceTree = "<group>"; };
|
||||||
390451DB28573F1000E0B563 /* Dictionary+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Extension.swift"; sourceTree = "<group>"; };
|
390451DB28573F1000E0B563 /* Dictionary+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Extension.swift"; sourceTree = "<group>"; };
|
||||||
390451E0285740E800E0B563 /* Sequence+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Extension.swift"; sourceTree = "<group>"; };
|
390451E0285740E800E0B563 /* Sequence+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Extension.swift"; sourceTree = "<group>"; };
|
||||||
390451E428574F0000E0B563 /* Catalog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Catalog.swift; sourceTree = "<group>"; };
|
390451E428574F0000E0B563 /* CatalogType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CatalogType.swift; sourceTree = "<group>"; };
|
||||||
390451E62857510B00E0B563 /* TextTag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextTag.swift; sourceTree = "<group>"; };
|
390451E62857510B00E0B563 /* TextTag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextTag.swift; sourceTree = "<group>"; };
|
||||||
39148CFB28DD55B300011FF5 /* PathControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PathControl.swift; sourceTree = "<group>"; };
|
39148CFB28DD55B300011FF5 /* PathControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PathControl.swift; sourceTree = "<group>"; };
|
||||||
39252A76285A849F00956C74 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
39252A76285A849F00956C74 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
@ -237,7 +239,10 @@
|
||||||
398734CF28603D9E00B4C357 /* UInt8+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt8+Extension.swift"; sourceTree = "<group>"; };
|
398734CF28603D9E00B4C357 /* UInt8+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt8+Extension.swift"; sourceTree = "<group>"; };
|
||||||
398734D128603DE700B4C357 /* Array+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Extension.swift"; sourceTree = "<group>"; };
|
398734D128603DE700B4C357 /* Array+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Extension.swift"; sourceTree = "<group>"; };
|
||||||
398734D3286046B000B4C357 /* UInt32+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt32+Extension.swift"; sourceTree = "<group>"; };
|
398734D3286046B000B4C357 /* UInt32+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt32+Extension.swift"; sourceTree = "<group>"; };
|
||||||
39CF4E722859C03D009E708C /* CatalogRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CatalogRow.swift; sourceTree = "<group>"; };
|
39CB5E3C293F5C2E00CFDBB8 /* Catalog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Catalog.swift; sourceTree = "<group>"; };
|
||||||
|
39CB5E3E2941486D00CFDBB8 /* CatalogSeedType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CatalogSeedType.swift; sourceTree = "<group>"; };
|
||||||
|
39CB5E5129418A2900CFDBB8 /* MistTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MistTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
39CB5E5329418A2900CFDBB8 /* MistTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MistTests.swift; sourceTree = "<group>"; };
|
||||||
39CF559D28614DD8006FB5D2 /* com.ninxsoft.mist.helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = com.ninxsoft.mist.helper; sourceTree = BUILT_PRODUCTS_DIR; };
|
39CF559D28614DD8006FB5D2 /* com.ninxsoft.mist.helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = com.ninxsoft.mist.helper; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
39CF559F28614DD8006FB5D2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
39CF559F28614DD8006FB5D2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||||
39CF55A528614E66006FB5D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
39CF55A528614E66006FB5D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
@ -281,6 +286,13 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
39CB5E4E29418A2900CFDBB8 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
39CF559A28614DD8006FB5D2 /* Frameworks */ = {
|
39CF559A28614DD8006FB5D2 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -299,6 +311,7 @@
|
||||||
390451A82856E1D900E0B563 /* Mist */,
|
390451A82856E1D900E0B563 /* Mist */,
|
||||||
39CF559E28614DD8006FB5D2 /* MistHelperTool */,
|
39CF559E28614DD8006FB5D2 /* MistHelperTool */,
|
||||||
39CF55D4286162DC006FB5D2 /* Shared */,
|
39CF55D4286162DC006FB5D2 /* Shared */,
|
||||||
|
39CB5E5229418A2900CFDBB8 /* MistTests */,
|
||||||
390451A72856E1D900E0B563 /* Products */,
|
390451A72856E1D900E0B563 /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -308,6 +321,7 @@
|
||||||
children = (
|
children = (
|
||||||
390451A62856E1D900E0B563 /* Mist.app */,
|
390451A62856E1D900E0B563 /* Mist.app */,
|
||||||
39CF559D28614DD8006FB5D2 /* com.ninxsoft.mist.helper */,
|
39CF559D28614DD8006FB5D2 /* com.ninxsoft.mist.helper */,
|
||||||
|
39CB5E5129418A2900CFDBB8 /* MistTests.xctest */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -379,8 +393,9 @@
|
||||||
390451C32856E4A500E0B563 /* Model */ = {
|
390451C32856E4A500E0B563 /* Model */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
390451E428574F0000E0B563 /* Catalog.swift */,
|
39CB5E3C293F5C2E00CFDBB8 /* Catalog.swift */,
|
||||||
39CF4E722859C03D009E708C /* CatalogRow.swift */,
|
390451E428574F0000E0B563 /* CatalogType.swift */,
|
||||||
|
39CB5E3E2941486D00CFDBB8 /* CatalogSeedType.swift */,
|
||||||
398734CB28603D5F00B4C357 /* Chunklist.swift */,
|
398734CB28603D5F00B4C357 /* Chunklist.swift */,
|
||||||
398734CD28603D7F00B4C357 /* Chunk.swift */,
|
398734CD28603D7F00B4C357 /* Chunk.swift */,
|
||||||
395DCD15287FE36E00C411CE /* DownloadAlertType.swift */,
|
395DCD15287FE36E00C411CE /* DownloadAlertType.swift */,
|
||||||
|
@ -452,6 +467,14 @@
|
||||||
path = Refresh;
|
path = Refresh;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
39CB5E5229418A2900CFDBB8 /* MistTests */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
39CB5E5329418A2900CFDBB8 /* MistTests.swift */,
|
||||||
|
);
|
||||||
|
path = MistTests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
39CF559E28614DD8006FB5D2 /* MistHelperTool */ = {
|
39CF559E28614DD8006FB5D2 /* MistHelperTool */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -545,6 +568,23 @@
|
||||||
productReference = 390451A62856E1D900E0B563 /* Mist.app */;
|
productReference = 390451A62856E1D900E0B563 /* Mist.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
|
39CB5E5029418A2900CFDBB8 /* MistTests */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 39CB5E5529418A2900CFDBB8 /* Build configuration list for PBXNativeTarget "MistTests" */;
|
||||||
|
buildPhases = (
|
||||||
|
39CB5E4D29418A2900CFDBB8 /* Sources */,
|
||||||
|
39CB5E4E29418A2900CFDBB8 /* Frameworks */,
|
||||||
|
39CB5E4F29418A2900CFDBB8 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = MistTests;
|
||||||
|
productName = MistTests;
|
||||||
|
productReference = 39CB5E5129418A2900CFDBB8 /* MistTests.xctest */;
|
||||||
|
productType = "com.apple.product-type.bundle.unit-test";
|
||||||
|
};
|
||||||
39CF559C28614DD8006FB5D2 /* MistHelperTool */ = {
|
39CF559C28614DD8006FB5D2 /* MistHelperTool */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 39CF55A128614DD8006FB5D2 /* Build configuration list for PBXNativeTarget "MistHelperTool" */;
|
buildConfigurationList = 39CF55A128614DD8006FB5D2 /* Build configuration list for PBXNativeTarget "MistHelperTool" */;
|
||||||
|
@ -574,12 +614,15 @@
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = 1;
|
BuildIndependentTargetsInParallel = 1;
|
||||||
LastSwiftUpdateCheck = 1400;
|
LastSwiftUpdateCheck = 1410;
|
||||||
LastUpgradeCheck = 1410;
|
LastUpgradeCheck = 1410;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
390451A52856E1D900E0B563 = {
|
390451A52856E1D900E0B563 = {
|
||||||
CreatedOnToolsVersion = 14.0;
|
CreatedOnToolsVersion = 14.0;
|
||||||
};
|
};
|
||||||
|
39CB5E5029418A2900CFDBB8 = {
|
||||||
|
CreatedOnToolsVersion = 14.1;
|
||||||
|
};
|
||||||
39CF559C28614DD8006FB5D2 = {
|
39CF559C28614DD8006FB5D2 = {
|
||||||
CreatedOnToolsVersion = 14.0;
|
CreatedOnToolsVersion = 14.0;
|
||||||
};
|
};
|
||||||
|
@ -606,6 +649,7 @@
|
||||||
targets = (
|
targets = (
|
||||||
390451A52856E1D900E0B563 /* Mist */,
|
390451A52856E1D900E0B563 /* Mist */,
|
||||||
39CF559C28614DD8006FB5D2 /* MistHelperTool */,
|
39CF559C28614DD8006FB5D2 /* MistHelperTool */,
|
||||||
|
39CB5E5029418A2900CFDBB8 /* MistTests */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
@ -619,6 +663,13 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
39CB5E4F29418A2900CFDBB8 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
@ -740,6 +791,7 @@
|
||||||
398734C428600E6E00B4C357 /* TaskManager.swift in Sources */,
|
398734C428600E6E00B4C357 /* TaskManager.swift in Sources */,
|
||||||
390451D62856F7FE00E0B563 /* UInt64+Extension.swift in Sources */,
|
390451D62856F7FE00E0B563 /* UInt64+Extension.swift in Sources */,
|
||||||
3935F47E2864813B00760AB0 /* DownloadManager.swift in Sources */,
|
3935F47E2864813B00760AB0 /* DownloadManager.swift in Sources */,
|
||||||
|
39CB5E3D293F5C2E00CFDBB8 /* Catalog.swift in Sources */,
|
||||||
39252AA1285C2A1600956C74 /* PaddedDivider.swift in Sources */,
|
39252AA1285C2A1600956C74 /* PaddedDivider.swift in Sources */,
|
||||||
39CF560C2861AE93006FB5D2 /* HelperToolCommandResponse.swift in Sources */,
|
39CF560C2861AE93006FB5D2 /* HelperToolCommandResponse.swift in Sources */,
|
||||||
39252A99285BFE2C00956C74 /* MistTaskState.swift in Sources */,
|
39252A99285BFE2C00956C74 /* MistTaskState.swift in Sources */,
|
||||||
|
@ -767,14 +819,14 @@
|
||||||
390451C22856E3F500E0B563 /* Hardware.swift in Sources */,
|
390451C22856E3F500E0B563 /* Hardware.swift in Sources */,
|
||||||
39CF56092861AE7F006FB5D2 /* HelperToolCommandRequest.swift in Sources */,
|
39CF56092861AE7F006FB5D2 /* HelperToolCommandRequest.swift in Sources */,
|
||||||
390451C82856E94900E0B563 /* FirmwareListRow.swift in Sources */,
|
390451C82856E94900E0B563 /* FirmwareListRow.swift in Sources */,
|
||||||
39CF4E732859C03D009E708C /* CatalogRow.swift in Sources */,
|
390451E528574F0000E0B563 /* CatalogType.swift in Sources */,
|
||||||
390451E528574F0000E0B563 /* Catalog.swift in Sources */,
|
|
||||||
3935F4852866B64900760AB0 /* MistTaskSection.swift in Sources */,
|
3935F4852866B64900760AB0 /* MistTaskSection.swift in Sources */,
|
||||||
390451AC2856E1D900E0B563 /* ContentView.swift in Sources */,
|
390451AC2856E1D900E0B563 /* ContentView.swift in Sources */,
|
||||||
3935F4A4286AD21000760AB0 /* DownloadProgressView.swift in Sources */,
|
3935F4A4286AD21000760AB0 /* DownloadProgressView.swift in Sources */,
|
||||||
39252A89285AD0AB00956C74 /* SettingsHeaderView.swift in Sources */,
|
39252A89285AD0AB00956C74 /* SettingsHeaderView.swift in Sources */,
|
||||||
39252A85285ACDC800956C74 /* ResetToDefaultButton.swift in Sources */,
|
39252A85285ACDC800956C74 /* ResetToDefaultButton.swift in Sources */,
|
||||||
39CF560F2861B857006FB5D2 /* XPCRoute+Extension.swift in Sources */,
|
39CF560F2861B857006FB5D2 /* XPCRoute+Extension.swift in Sources */,
|
||||||
|
39CB5E3F2941486D00CFDBB8 /* CatalogSeedType.swift in Sources */,
|
||||||
39252A7F285AC6F600956C74 /* SettingsPackagesView.swift in Sources */,
|
39252A7F285AC6F600956C74 /* SettingsPackagesView.swift in Sources */,
|
||||||
39CF562F2862A797006FB5D2 /* ISOConverter.swift in Sources */,
|
39CF562F2862A797006FB5D2 /* ISOConverter.swift in Sources */,
|
||||||
39CF56392862D75D006FB5D2 /* FileCreator.swift in Sources */,
|
39CF56392862D75D006FB5D2 /* FileCreator.swift in Sources */,
|
||||||
|
@ -795,6 +847,14 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
39CB5E4D29418A2900CFDBB8 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
39CB5E5429418A2900CFDBB8 /* MistTests.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
39CF559928614DD8006FB5D2 /* Sources */ = {
|
39CF559928614DD8006FB5D2 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -996,6 +1056,46 @@
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
39CB5E5629418A2900CFDBB8 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=macosx*]" = 7K3HVCLV7Z;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.ninxsoft.mist.tests;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
39CB5E5729418A2900CFDBB8 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=macosx*]" = 7K3HVCLV7Z;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.ninxsoft.mist.tests;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
39CF55A228614DD8006FB5D2 /* Debug */ = {
|
39CF55A228614DD8006FB5D2 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -1085,6 +1185,15 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
39CB5E5529418A2900CFDBB8 /* Build configuration list for PBXNativeTarget "MistTests" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
39CB5E5629418A2900CFDBB8 /* Debug */,
|
||||||
|
39CB5E5729418A2900CFDBB8 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
39CF55A128614DD8006FB5D2 /* Build configuration list for PBXNativeTarget "MistHelperTool" */ = {
|
39CF55A128614DD8006FB5D2 /* Build configuration list for PBXNativeTarget "MistHelperTool" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES"
|
||||||
|
viewDebuggingEnabled = "No">
|
||||||
<BuildableProductRunnable
|
<BuildableProductRunnable
|
||||||
runnableDebuggingMode = "0">
|
runnableDebuggingMode = "0">
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
|
|
78
Mist.xcodeproj/xcshareddata/xcschemes/MistTests.xcscheme
Normal file
78
Mist.xcodeproj/xcshareddata/xcschemes/MistTests.xcscheme
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1410"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "NO"
|
||||||
|
buildForArchiving = "NO"
|
||||||
|
buildForAnalyzing = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "39CB5E5029418A2900CFDBB8"
|
||||||
|
BuildableName = "MistTests.xctest"
|
||||||
|
BlueprintName = "MistTests"
|
||||||
|
ReferencedContainer = "container:Mist.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO"
|
||||||
|
parallelizable = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "39CB5E5029418A2900CFDBB8"
|
||||||
|
BuildableName = "MistTests.xctest"
|
||||||
|
BlueprintName = "MistTests"
|
||||||
|
ReferencedContainer = "container:Mist.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "39CB5E5029418A2900CFDBB8"
|
||||||
|
BuildableName = "MistTests.xctest"
|
||||||
|
BlueprintName = "MistTests"
|
||||||
|
ReferencedContainer = "container:Mist.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
|
@ -16,6 +16,7 @@ class DownloadManager: NSObject, ObservableObject {
|
||||||
progress.fractionCompleted
|
progress.fractionCompleted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable:next cyclomatic_complexity function_body_length
|
||||||
func download(_ url: URL, to destination: URL, retries retriesMaximum: Int, delay retryDelay: Int) async throws {
|
func download(_ url: URL, to destination: URL, retries retriesMaximum: Int, delay retryDelay: Int) async throws {
|
||||||
|
|
||||||
guard !FileManager.default.fileExists(atPath: destination.path) else {
|
guard !FileManager.default.fileExists(atPath: destination.path) else {
|
||||||
|
@ -27,6 +28,7 @@ class DownloadManager: NSObject, ObservableObject {
|
||||||
var urlError: URLError?
|
var urlError: URLError?
|
||||||
var retries: Int = 0
|
var retries: Int = 0
|
||||||
var completed: Bool = false
|
var completed: Bool = false
|
||||||
|
// swiftlint:disable:next closure_body_length
|
||||||
let completionHandler: (URL?, URLResponse?, Error?) -> Void = { url, _, error in
|
let completionHandler: (URL?, URLResponse?, Error?) -> Void = { url, _, error in
|
||||||
|
|
||||||
if let error: URLError = error as? URLError {
|
if let error: URLError = error as? URLError {
|
||||||
|
|
|
@ -87,8 +87,7 @@ class TaskManager: ObservableObject {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:disable function_parameter_count
|
// swiftlint:disable:next function_parameter_count
|
||||||
|
|
||||||
private static func firmwareDownloadTasks(
|
private static func firmwareDownloadTasks(
|
||||||
firmware: Firmware,
|
firmware: Firmware,
|
||||||
firmwareURL: URL,
|
firmwareURL: URL,
|
||||||
|
@ -120,8 +119,6 @@ class TaskManager: ObservableObject {
|
||||||
return tasks
|
return tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:enable function_parameter_count
|
|
||||||
|
|
||||||
private static func firmwareCleanupTasks(temporaryDirectory temporaryDirectoryURL: URL) -> [MistTask] {
|
private static func firmwareCleanupTasks(temporaryDirectory temporaryDirectoryURL: URL) -> [MistTask] {
|
||||||
[
|
[
|
||||||
MistTask(type: .remove, description: "temporary directory") {
|
MistTask(type: .remove, description: "temporary directory") {
|
||||||
|
@ -130,8 +127,7 @@ class TaskManager: ObservableObject {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:disable function_parameter_count
|
// swiftlint:disable:next function_body_length function_parameter_count
|
||||||
|
|
||||||
static func taskGroups(
|
static func taskGroups(
|
||||||
for installer: Installer,
|
for installer: Installer,
|
||||||
destination destinationURL: URL?,
|
destination destinationURL: URL?,
|
||||||
|
@ -225,8 +221,6 @@ class TaskManager: ObservableObject {
|
||||||
return taskGroups
|
return taskGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:enable function_parameter_count
|
|
||||||
|
|
||||||
private static func downloadTasks(for installer: Installer, cacheDirectory cacheDirectoryURL: URL, retries: Int, delay retryDelay: Int) throws -> [MistTask] {
|
private static func downloadTasks(for installer: Installer, cacheDirectory cacheDirectoryURL: URL, retries: Int, delay retryDelay: Int) throws -> [MistTask] {
|
||||||
|
|
||||||
var tasks: [MistTask] = []
|
var tasks: [MistTask] = []
|
||||||
|
@ -292,8 +286,7 @@ class TaskManager: ObservableObject {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:disable function_parameter_count
|
// swiftlint:disable:next function_parameter_count
|
||||||
|
|
||||||
private static func diskImageTasks(
|
private static func diskImageTasks(
|
||||||
for installer: Installer,
|
for installer: Installer,
|
||||||
filename: String,
|
filename: String,
|
||||||
|
@ -338,8 +331,6 @@ class TaskManager: ObservableObject {
|
||||||
return tasks
|
return tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:enable function_parameter_count
|
|
||||||
|
|
||||||
private static func isoTasks(for installer: Installer, filename: String, destination destinationURL: URL, temporaryDirectory temporaryDirectoryURL: URL) -> [MistTask] {
|
private static func isoTasks(for installer: Installer, filename: String, destination destinationURL: URL, temporaryDirectory temporaryDirectoryURL: URL) -> [MistTask] {
|
||||||
|
|
||||||
let temporaryImageURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id).dmg")
|
let temporaryImageURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id).dmg")
|
||||||
|
@ -369,8 +360,7 @@ class TaskManager: ObservableObject {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:disable function_parameter_count
|
// swiftlint:disable:next function_parameter_count
|
||||||
|
|
||||||
private static func packageTasks(
|
private static func packageTasks(
|
||||||
for installer: Installer,
|
for installer: Installer,
|
||||||
filename: String,
|
filename: String,
|
||||||
|
@ -411,8 +401,6 @@ class TaskManager: ObservableObject {
|
||||||
return tasks
|
return tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:enable function_parameter_count
|
|
||||||
|
|
||||||
private static func cleanupTasks(mountPoint mountPointURL: URL, temporaryDirectory temporaryDirectoryURL: URL, cacheDownloads: Bool, cacheDirectory cacheDirectoryURL: URL) -> [MistTask] {
|
private static func cleanupTasks(mountPoint mountPointURL: URL, temporaryDirectory temporaryDirectoryURL: URL, cacheDownloads: Bool, cacheDirectory cacheDirectoryURL: URL) -> [MistTask] {
|
||||||
|
|
||||||
var tasks: [MistTask] = [
|
var tasks: [MistTask] = [
|
||||||
|
|
|
@ -2,32 +2,61 @@
|
||||||
// Catalog.swift
|
// Catalog.swift
|
||||||
// Mist
|
// Mist
|
||||||
//
|
//
|
||||||
// Created by Nindi Gill on 13/6/2022.
|
// Created by Nindi Gill on 6/12/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum Catalog: String, CaseIterable {
|
struct Catalog: Identifiable, Decodable, Equatable {
|
||||||
// swiftlint:disable redundant_string_enum_value
|
|
||||||
case standard = "standard"
|
|
||||||
case customer = "customer"
|
|
||||||
case developer = "developer"
|
|
||||||
case `public` = "public"
|
|
||||||
|
|
||||||
static var urls: [String] {
|
enum CodingKeys: String, CodingKey {
|
||||||
self.allCases.map { $0.url }
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
|
case type = "type"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
|
case standard = "standard"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
|
case customerSeed = "customerSeed"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
|
case developerSeed = "developerSeed"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
|
case publicSeed = "publicSeed"
|
||||||
}
|
}
|
||||||
|
|
||||||
var url: String {
|
static var example: Catalog {
|
||||||
switch self {
|
Catalog(type: .ventura, standard: true, customerSeed: false, developerSeed: false, publicSeed: false)
|
||||||
case .standard:
|
}
|
||||||
return "https://swscan.apple.com/content/catalogs/others/index-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
|
||||||
case .customer:
|
var id: UUID = UUID()
|
||||||
return "https://swscan.apple.com/content/catalogs/others/index-12customerseed-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
var type: CatalogType
|
||||||
case .developer:
|
var standard: Bool
|
||||||
return "https://swscan.apple.com/content/catalogs/others/index-12seed-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
var customerSeed: Bool
|
||||||
case .`public`:
|
var developerSeed: Bool
|
||||||
return "https://swscan.apple.com/content/catalogs/others/index-12beta-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
var publicSeed: Bool
|
||||||
}
|
|
||||||
|
init(type: CatalogType, standard: Bool, customerSeed: Bool, developerSeed: Bool, publicSeed: Bool) {
|
||||||
|
self.type = type
|
||||||
|
self.standard = standard
|
||||||
|
self.customerSeed = customerSeed
|
||||||
|
self.developerSeed = developerSeed
|
||||||
|
self.publicSeed = publicSeed
|
||||||
|
}
|
||||||
|
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let container: KeyedDecodingContainer<Catalog.CodingKeys> = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
type = try container.decode(CatalogType.self, forKey: .type)
|
||||||
|
standard = try container.decode(Bool.self, forKey: .standard)
|
||||||
|
customerSeed = try container.decode(Bool.self, forKey: .customerSeed)
|
||||||
|
developerSeed = try container.decode(Bool.self, forKey: .developerSeed)
|
||||||
|
publicSeed = try container.decode(Bool.self, forKey: .publicSeed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dictionary() -> [String: Any] {
|
||||||
|
[
|
||||||
|
"type": type.description,
|
||||||
|
"standard": standard,
|
||||||
|
"customerSeed": customerSeed,
|
||||||
|
"developerSeed": developerSeed,
|
||||||
|
"publicSeed": publicSeed
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
//
|
|
||||||
// CatalogRow.swift
|
|
||||||
// Mist
|
|
||||||
//
|
|
||||||
// Created by Nindi Gill on 15/6/2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
struct CatalogRow: Identifiable, Hashable {
|
|
||||||
|
|
||||||
static var example: CatalogRow {
|
|
||||||
CatalogRow(url: Catalog.standard.url)
|
|
||||||
}
|
|
||||||
|
|
||||||
var id: UUID = UUID()
|
|
||||||
var url: String
|
|
||||||
}
|
|
19
Mist/Model/CatalogSeedType.swift
Normal file
19
Mist/Model/CatalogSeedType.swift
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// CatalogSeedType.swift
|
||||||
|
// Mist
|
||||||
|
//
|
||||||
|
// Created by Nindi Gill on 8/12/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum CatalogSeedType: String {
|
||||||
|
case standard = "Standard"
|
||||||
|
case customer = "Customer"
|
||||||
|
case developer = "Developer"
|
||||||
|
case `public` = "Public"
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
rawValue
|
||||||
|
}
|
||||||
|
}
|
80
Mist/Model/CatalogType.swift
Normal file
80
Mist/Model/CatalogType.swift
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
//
|
||||||
|
// CatalogType.swift
|
||||||
|
// Mist
|
||||||
|
//
|
||||||
|
// Created by Nindi Gill on 13/6/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum CatalogType: String, CaseIterable, Comparable, Decodable {
|
||||||
|
case ventura = "macOS Ventura"
|
||||||
|
case monterey = "macOS Monterey"
|
||||||
|
case bigSur = "macOS Big Sur"
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
rawValue
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageName: String {
|
||||||
|
rawValue
|
||||||
|
}
|
||||||
|
|
||||||
|
private var sortOrder: Int {
|
||||||
|
switch self {
|
||||||
|
case .ventura:
|
||||||
|
return 0
|
||||||
|
case .monterey:
|
||||||
|
return 1
|
||||||
|
case .bigSur:
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func < (lhs: CatalogType, rhs: CatalogType) -> Bool {
|
||||||
|
lhs.sortOrder < rhs.sortOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable:next cyclomatic_complexity
|
||||||
|
func url(for seedType: CatalogSeedType) -> String {
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
case .ventura:
|
||||||
|
switch seedType {
|
||||||
|
case .standard:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .customer:
|
||||||
|
// swiftlint:disable:next line_length
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-13customerseed-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .developer:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-13seed-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .public:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-13beta-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
}
|
||||||
|
case .monterey:
|
||||||
|
switch seedType {
|
||||||
|
case .standard:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .customer:
|
||||||
|
// swiftlint:disable:next line_length
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-12customerseed-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .developer:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-12seed-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .public:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-12beta-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
}
|
||||||
|
case .bigSur:
|
||||||
|
switch seedType {
|
||||||
|
case .standard:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .customer:
|
||||||
|
// swiftlint:disable:next line_length
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-10.16customerseed-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .developer:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-10.16seed-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
case .public:
|
||||||
|
return "https://swscan.apple.com/content/catalogs/others/index-10.16beta-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,10 +9,13 @@ import Foundation
|
||||||
import UniformTypeIdentifiers
|
import UniformTypeIdentifiers
|
||||||
|
|
||||||
enum ExportListType: String, CaseIterable, Identifiable {
|
enum ExportListType: String, CaseIterable, Identifiable {
|
||||||
// swiftlint:disable redundant_string_enum_value
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case csv = "csv"
|
case csv = "csv"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case json = "json"
|
case json = "json"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case plist = "plist"
|
case plist = "plist"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case yaml = "yaml"
|
case yaml = "yaml"
|
||||||
|
|
||||||
var id: String {
|
var id: String {
|
||||||
|
|
|
@ -140,7 +140,7 @@ struct DownloadView: View {
|
||||||
|
|
||||||
private func checkForUserCancellation(_ failure: Error) -> Bool {
|
private func checkForUserCancellation(_ failure: Error) -> Bool {
|
||||||
|
|
||||||
if let _: CancellationError = failure as? CancellationError {
|
if failure as? CancellationError != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,6 @@ struct InstallerListRow: View {
|
||||||
openPanel.accessoryView = NSHostingView(rootView: InstallerExportView(exports: $exports))
|
openPanel.accessoryView = NSHostingView(rootView: InstallerExportView(exports: $exports))
|
||||||
openPanel.isAccessoryViewDisclosed = true
|
openPanel.isAccessoryViewDisclosed = true
|
||||||
|
|
||||||
// swiftlint:disable:next closure_body_length
|
|
||||||
Task {
|
Task {
|
||||||
let response: NSApplication.ModalResponse = openPanel.runModal()
|
let response: NSApplication.ModalResponse = openPanel.runModal()
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
// swiftlint:disable:next type_body_length
|
||||||
struct RefreshView: View {
|
struct RefreshView: View {
|
||||||
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
|
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
|
||||||
@Binding var firmwares: [Firmware]
|
@Binding var firmwares: [Firmware]
|
||||||
|
@ -124,11 +125,11 @@ struct RefreshView: View {
|
||||||
|
|
||||||
private func retrieveInstallers() throws -> [Installer] {
|
private func retrieveInstallers() throws -> [Installer] {
|
||||||
var installers: [Installer] = []
|
var installers: [Installer] = []
|
||||||
let catalogs: [String] = UserDefaults.standard.array(forKey: "catalogURLs") as? [String] ?? Catalog.urls
|
let catalogURLs: [String] = getCatalogURLs()
|
||||||
|
|
||||||
for catalog in catalogs {
|
for catalogURL in catalogURLs {
|
||||||
|
|
||||||
guard let url: URL = URL(string: catalog) else {
|
guard let url: URL = URL(string: catalogURL) else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +162,49 @@ struct RefreshView: View {
|
||||||
return installers
|
return installers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func getCatalogURLs() -> [String] {
|
||||||
|
|
||||||
|
var catalogURLs: [String] = []
|
||||||
|
var catalogs: [Catalog] = []
|
||||||
|
let defaultCatalogs: [Catalog] = CatalogType.allCases.map { Catalog(type: $0, standard: true, customerSeed: false, developerSeed: false, publicSeed: false) }
|
||||||
|
|
||||||
|
if let array: [[String: Any]] = UserDefaults.standard.array(forKey: "catalogs") as? [[String: Any]] {
|
||||||
|
do {
|
||||||
|
catalogs = try JSONDecoder().decode([Catalog].self, from: JSONSerialization.data(withJSONObject: array))
|
||||||
|
let catalogTypes: [CatalogType] = catalogs.map { $0.type }
|
||||||
|
|
||||||
|
for catalogType in CatalogType.allCases where !catalogTypes.contains(catalogType) {
|
||||||
|
let catalog: Catalog = Catalog(type: catalogType, standard: true, customerSeed: false, developerSeed: false, publicSeed: false)
|
||||||
|
catalogs.append(catalog)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
catalogs = defaultCatalogs
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
catalogs = defaultCatalogs
|
||||||
|
}
|
||||||
|
|
||||||
|
for catalog in catalogs {
|
||||||
|
if catalog.standard {
|
||||||
|
catalogURLs.append(catalog.type.url(for: .standard))
|
||||||
|
}
|
||||||
|
|
||||||
|
if catalog.customerSeed {
|
||||||
|
catalogURLs.append(catalog.type.url(for: .customer))
|
||||||
|
}
|
||||||
|
|
||||||
|
if catalog.developerSeed {
|
||||||
|
catalogURLs.append(catalog.type.url(for: .developer))
|
||||||
|
}
|
||||||
|
|
||||||
|
if catalog.publicSeed {
|
||||||
|
catalogURLs.append(catalog.type.url(for: .public))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return catalogURLs
|
||||||
|
}
|
||||||
|
|
||||||
private func getInstallers(from dictionary: [String: Any]) -> [Installer] {
|
private func getInstallers(from dictionary: [String: Any]) -> [Installer] {
|
||||||
|
|
||||||
var installers: [Installer] = []
|
var installers: [Installer] = []
|
||||||
|
|
|
@ -8,47 +8,81 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct SettingsInstallersCatalogsView: View {
|
struct SettingsInstallersCatalogsView: View {
|
||||||
@Binding var catalogRows: [CatalogRow]
|
@Binding var catalogs: [Catalog]
|
||||||
@Binding var selectedCatalogRow: CatalogRow?
|
// swiftlint:disable:next line_length
|
||||||
|
private let description: String = "Apple Software Update Catalogs are used to determine available macOS Installers.\n\n- **Standard:** The default catalog that ships with macOS\n- **Customer Seed:** The catalog available as part of the [AppleSeed Program](https://appleseed.apple.com/)\n- **Developer Seed:** The catalog available as part of the [Apple Developer Program](https://developer.apple.com/programs/)\n- **Public Seed:** The catalog available as part of the [Apple Beta Software Program](https://beta.apple.com/)\n\n**Note:** Catalogs from the Seed Programs may contain beta / unreleased versions of macOS. Ensure you are a member of these programs before proceeding."
|
||||||
|
private let height: CGFloat = 120
|
||||||
|
private let width: CGFloat = 150
|
||||||
private let length: CGFloat = 16
|
private let length: CGFloat = 16
|
||||||
private let height: CGFloat = 200
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text("Catalog URLs:")
|
Text("Software Update Catalogs:")
|
||||||
FooterText("Apple Software Update Catalogs are used to determine all available macOS Installers.")
|
FooterText(description)
|
||||||
List(selection: $selectedCatalogRow) {
|
Table(catalogs) {
|
||||||
ForEach($catalogRows) { catalogRow in
|
TableColumn("") { catalog in
|
||||||
HStack {
|
ScaledImage(name: catalog.type.imageName, length: length)
|
||||||
ScaledSystemImage(systemName: "line.3.horizontal", length: length)
|
|
||||||
.foregroundColor(.secondary)
|
|
||||||
TextEditor(text: catalogRow.url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.onMove { indexSet, offset in
|
.width(length)
|
||||||
catalogRows.move(fromOffsets: indexSet, toOffset: offset)
|
TableColumn("Catalog Type") { catalog in
|
||||||
|
Text(catalog.type.description)
|
||||||
}
|
}
|
||||||
.onDelete { indexSet in
|
.width(width)
|
||||||
catalogRows.remove(atOffsets: indexSet)
|
TableColumn(CatalogSeedType.standard.description) { catalog in
|
||||||
}
|
toggle(.standard, using: catalog)
|
||||||
}
|
}
|
||||||
.frame(minHeight: height)
|
TableColumn(CatalogSeedType.customer.description) { catalog in
|
||||||
HStack {
|
toggle(.customer, using: catalog)
|
||||||
Spacer()
|
}
|
||||||
Button("Add") {
|
TableColumn(CatalogSeedType.developer.description) { catalog in
|
||||||
addCatalog()
|
toggle(.developer, using: catalog)
|
||||||
|
}
|
||||||
|
TableColumn(CatalogSeedType.public.description) { catalog in
|
||||||
|
toggle(.public, using: catalog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tableStyle(.bordered)
|
||||||
|
.frame(minHeight: height, maxHeight: height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addCatalog() {
|
private func toggle(_ catalogSeedType: CatalogSeedType, using catalog: Catalog) -> some View {
|
||||||
catalogRows.append(CatalogRow(url: "https://"))
|
Toggle(catalogSeedType.description, isOn: Binding<Bool>(
|
||||||
|
get: {
|
||||||
|
switch catalogSeedType {
|
||||||
|
case .standard:
|
||||||
|
return catalog.standard
|
||||||
|
case .customer:
|
||||||
|
return catalog.customerSeed
|
||||||
|
case .developer:
|
||||||
|
return catalog.developerSeed
|
||||||
|
case .public:
|
||||||
|
return catalog.publicSeed
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: {
|
||||||
|
guard let index: Int = catalogs.firstIndex(where: { $0.id == catalog.id }) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch catalogSeedType {
|
||||||
|
case .standard:
|
||||||
|
catalogs[index].standard = $0
|
||||||
|
case .customer:
|
||||||
|
catalogs[index].customerSeed = $0
|
||||||
|
case .developer:
|
||||||
|
catalogs[index].developerSeed = $0
|
||||||
|
case .public:
|
||||||
|
catalogs[index].publicSeed = $0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.labelsHidden()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SettingsInstallersCatalogsView_Previews: PreviewProvider {
|
struct SettingsInstallersCatalogsView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
SettingsInstallersCatalogsView(catalogRows: .constant([.example]), selectedCatalogRow: .constant(.example))
|
SettingsInstallersCatalogsView(catalogs: .constant([.example]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,10 @@ import SwiftUI
|
||||||
struct SettingsInstallersView: View {
|
struct SettingsInstallersView: View {
|
||||||
@AppStorage("cacheDownloads") private var cacheDownloads: Bool = false
|
@AppStorage("cacheDownloads") private var cacheDownloads: Bool = false
|
||||||
@AppStorage("cacheDirectory") private var cacheDirectory: String = .cacheDirectory
|
@AppStorage("cacheDirectory") private var cacheDirectory: String = .cacheDirectory
|
||||||
@State private var catalogRows: [CatalogRow] = []
|
@State private var catalogs: [Catalog] = []
|
||||||
@State private var selectedCatalogRow: CatalogRow?
|
|
||||||
private let cacheDownloadsDefault: Bool = false
|
private let cacheDownloadsDefault: Bool = false
|
||||||
private let cacheDirectoryDefault: String = .cacheDirectory
|
private let cacheDirectoryDefault: String = .cacheDirectory
|
||||||
private var defaultCatalogRows: [CatalogRow] = Catalog.urls.map { CatalogRow(url: $0) }
|
private let defaultCatalogs: [Catalog] = CatalogType.allCases.map { Catalog(type: $0, standard: true, customerSeed: false, developerSeed: false, publicSeed: false) }
|
||||||
private let imageName: String = "Installer"
|
private let imageName: String = "Installer"
|
||||||
private let title: String = "Installers"
|
private let title: String = "Installers"
|
||||||
private let description: String = "macOS Installers are a collection of files that can be used to build macOS Installer **Applications**, **Disk Images**, **ISOs** and **Packages**."
|
private let description: String = "macOS Installers are a collection of files that can be used to build macOS Installer **Applications**, **Disk Images**, **ISOs** and **Packages**."
|
||||||
|
@ -25,7 +24,7 @@ struct SettingsInstallersView: View {
|
||||||
PaddedDivider()
|
PaddedDivider()
|
||||||
SettingsInstallersCacheView(cacheDownloads: $cacheDownloads, cacheDirectory: $cacheDirectory)
|
SettingsInstallersCacheView(cacheDownloads: $cacheDownloads, cacheDirectory: $cacheDirectory)
|
||||||
PaddedDivider()
|
PaddedDivider()
|
||||||
SettingsInstallersCatalogsView(catalogRows: $catalogRows, selectedCatalogRow: $selectedCatalogRow)
|
SettingsInstallersCatalogsView(catalogs: $catalogs)
|
||||||
PaddedDivider()
|
PaddedDivider()
|
||||||
ResetToDefaultButton {
|
ResetToDefaultButton {
|
||||||
reset()
|
reset()
|
||||||
|
@ -33,27 +32,38 @@ struct SettingsInstallersView: View {
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
.onAppear {
|
.onAppear {
|
||||||
populateCatalogURLs()
|
catalogs = getCatalogs()
|
||||||
}
|
}
|
||||||
.onChange(of: catalogRows) { catalogRows in
|
.onChange(of: catalogs) { catalogs in
|
||||||
UserDefaults.standard.setValue(catalogRows.map { $0.url }, forKey: "catalogURLs")
|
UserDefaults.standard.setValue(catalogs.map { $0.dictionary() }, forKey: "catalogs")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func populateCatalogURLs() {
|
private func getCatalogs() -> [Catalog] {
|
||||||
|
|
||||||
guard let urls: [String] = UserDefaults.standard.array(forKey: "catalogURLs") as? [String] else {
|
guard let array: [[String: Any]] = UserDefaults.standard.array(forKey: "catalogs") as? [[String: Any]] else {
|
||||||
catalogRows = defaultCatalogRows
|
return defaultCatalogs
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catalogRows = urls.map { CatalogRow(url: $0) }
|
do {
|
||||||
|
var catalogs: [Catalog] = try JSONDecoder().decode([Catalog].self, from: JSONSerialization.data(withJSONObject: array))
|
||||||
|
let catalogTypes: [CatalogType] = catalogs.map { $0.type }
|
||||||
|
|
||||||
|
for catalogType in CatalogType.allCases where !catalogTypes.contains(catalogType) {
|
||||||
|
let catalog: Catalog = Catalog(type: catalogType, standard: true, customerSeed: false, developerSeed: false, publicSeed: false)
|
||||||
|
catalogs.append(catalog)
|
||||||
|
}
|
||||||
|
|
||||||
|
return catalogs.sorted { $0.type < $1.type }
|
||||||
|
} catch {
|
||||||
|
return defaultCatalogs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func reset() {
|
private func reset() {
|
||||||
cacheDownloads = cacheDownloadsDefault
|
cacheDownloads = cacheDownloadsDefault
|
||||||
cacheDirectory = cacheDirectoryDefault
|
cacheDirectory = cacheDirectoryDefault
|
||||||
catalogRows = defaultCatalogRows
|
catalogs = defaultCatalogs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
MistTests/MistTests.swift
Normal file
15
MistTests/MistTests.swift
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// MistTests.swift
|
||||||
|
// MistTests
|
||||||
|
//
|
||||||
|
// Created by Nindi Gill on 8/12/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class MistTests: XCTestCase {
|
||||||
|
|
||||||
|
func test() throws {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
# MIST - macOS Installer Super Tool
|
# MIST - macOS Installer Super Tool
|
||||||
|
|
||||||
|
 [](https://github.com/ninxsoft/Mist/actions/workflows/linting.yml) [](https://github.com/ninxsoft/Mist/actions/workflows/unit_tests.yml) [](https://github.com/ninxsoft/Mist/actions/workflows/build.yml)
|
||||||
|
|
||||||
A Mac utility that automatically downloads macOS Firmwares / Installers:
|
A Mac utility that automatically downloads macOS Firmwares / Installers:
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -8,9 +8,12 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum HelperToolCommandType: String, Codable {
|
enum HelperToolCommandType: String, Codable {
|
||||||
// swiftlint:disable redundant_string_enum_value
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case remove = "remove"
|
case remove = "remove"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case installer = "installer"
|
case installer = "installer"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case createinstallmedia = "createinstallmedia"
|
case createinstallmedia = "createinstallmedia"
|
||||||
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case kill = "kill"
|
case kill = "kill"
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,6 @@ class ShellExecutor: NSObject {
|
||||||
static var shared: ShellExecutor = ShellExecutor()
|
static var shared: ShellExecutor = ShellExecutor()
|
||||||
private var process: Process = Process()
|
private var process: Process = Process()
|
||||||
|
|
||||||
// swiftlint:disable large_tuple
|
|
||||||
|
|
||||||
/// Executes custom shell commands.
|
/// Executes custom shell commands.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue