diff --git a/.github/workflows/build-analyze.yml b/.github/workflows/build-analyze.yml index c564800..717a531 100644 --- a/.github/workflows/build-analyze.yml +++ b/.github/workflows/build-analyze.yml @@ -8,7 +8,7 @@ on: jobs: build: - name: Build and analyse using xcodebuild command + name: Build and Analyse Using xcodebuild Command runs-on: macos-13 steps: @@ -20,6 +20,6 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Build + - name: Build and Analyse Reveil run: | xcodebuild clean build analyze -scheme Reveil -project Reveil.xcodeproj CODE_SIGNING_ALLOWED=NO | xcpretty && exit ${PIPESTATUS[0]} diff --git a/.github/workflows/build-archive-macos.yml b/.github/workflows/build-archive-macos.yml new file mode 100644 index 0000000..bccfd1d --- /dev/null +++ b/.github/workflows/build-archive-macos.yml @@ -0,0 +1,109 @@ +name: Xcode - Build Archive (macOS) + +on: + push: + branches: [ "feat/macos-native-support" ] + +env: + MARKETING_VERSION: 0.0.0 + PATCH_VERSION: 0 + +jobs: + build: + name: Build Notarized macOS Application + runs-on: macos-13 + + steps: + - name: Install Packaging Tools + run: | + HOMEBREW_NO_AUTO_UPDATE=1 brew install graphicsmagick imagemagick + npm install -g create-dmg + + - name: Checkout + uses: actions/checkout@v3 + + - name: Configure Code-Signing Keychain + run: | + KETSTORE_PATH="$PWD/Certificates/Certificates.p12" + KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db" + security create-keychain -p "$KEYSTORE_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" + security unlock-keychain -p "$KEYSTORE_PASSWORD" "$KEYCHAIN_PATH" + security import "$KETSTORE_PATH" -P "$KEYSTORE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" + security list-keychain -d user -s "$KEYCHAIN_PATH" + env: + KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} # Password for the keychain & p12 keystore + + - name: Setup Xcode Version + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: 15.1 + + - name: Read Version Strings + run: | + git fetch --tags + export GIT_TAG=$(git describe --tags --always --abbrev=0) + export PATCH_VERSION=$(echo "${GIT_TAG#v}" | cut -d. -f3) + echo "PATCH_VERSION=${PATCH_VERSION}" >> $GITHUB_ENV + echo "MARKETING_VERSION=${GIT_TAG#v}" >> $GITHUB_ENV + + - name: Build ReveilHelper + run: | + xcodebuild clean build archive -scheme ReveilHelper -project Reveil.xcodeproj -archivePath ReveilHelper.xcarchive CODE_SIGNING_ALLOWED=NO | xcpretty && exit ${PIPESTATUS[0]} + + - name: Build Reveil (macOS) + run: | + PATH=$PWD/ReveilHelper.xcarchive/Products/usr/local/bin:$PATH xcodebuild clean build archive -scheme Reveil -project Reveil.xcodeproj -sdk macosx -destination 'generic/platform=macOS' -archivePath Reveil CODE_SIGN_STYLE='Manual' CODE_SIGN_IDENTITY='$CODE_SIGN_IDENTITY' | xcpretty && exit ${PIPESTATUS[0]} + env: + DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} # Team ID + CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} # Code-Signing Identity, e.g. "Apple Development: John Doe (XXXXXXXXXX)" + + - name: Notarize Reveil + run: | + mkdir -p Distribution + echo "$APPSTORECONNECT_AUTHKEY" > "$PWD/AuthKey_$APPSTORECONNECT_AUTHKEY_ID.p8" + xcodebuild -exportArchive -allowProvisioningUpdates -authenticationKeyID $APPSTORECONNECT_AUTHKEY_ID -authenticationKeyIssuerID $APPSTORECONNECT_AUTHKEY_ISSUER_ID -authenticationKeyPath "$PWD/AuthKey_$APPSTORECONNECT_AUTHKEY_ID.p8" -archivePath Reveil.xcarchive -exportPath Distribution -exportOptionsPlist $PWD/ExportOptions.plist + env: + APPSTORECONNECT_AUTHKEY: ${{ secrets.APPSTORECONNECT_AUTHKEY }} # App Store Connect API Key, begin with "-----BEGIN PRIVATE KEY-----" + APPSTORECONNECT_AUTHKEY_ID: ${{ secrets.APPSTORECONNECT_AUTHKEY_ID }} # App Store Connect API Key ID + APPSTORECONNECT_AUTHKEY_ISSUER_ID: ${{ secrets.APPSTORECONNECT_AUTHKEY_ISSUER_ID }} # App Store Connect API Key Issuer ID + + - name: Export Notarized Application + run: | + until xcodebuild -exportNotarizedApp -authenticationKeyID $APPSTORECONNECT_AUTHKEY_ID -authenticationKeyIssuerID $APPSTORECONNECT_AUTHKEY_ISSUER_ID -authenticationKeyPath "$PWD/AuthKey_$APPSTORECONNECT_AUTHKEY_ID.p8" -archivePath Reveil.xcarchive -exportPath Distribution; + do + echo "Waiting for notarization..." + sleep 10 + done + env: + APPSTORECONNECT_AUTHKEY: ${{ secrets.APPSTORECONNECT_AUTHKEY }} + APPSTORECONNECT_AUTHKEY_ID: ${{ secrets.APPSTORECONNECT_AUTHKEY_ID }} + APPSTORECONNECT_AUTHKEY_ISSUER_ID: ${{ secrets.APPSTORECONNECT_AUTHKEY_ISSUER_ID }} + + - name: Create DMG + run: | + create-dmg --overwrite --identity="$PACKAGING_IDENTITY" Distribution/Reveil.app ./Distribution/ + mv Distribution/*.dmg Reveil_${{ env.MARKETING_VERSION }}.dmg + env: + PACKAGING_IDENTITY: ${{ secrets.PACKAGING_IDENTITY }} # Identity for packaging, e.g. "Developer ID Application: John Doe (XXXXXXXXXX)" + + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: Reveil_${{ env.MARKETING_VERSION }} + path: | + Reveil.xcarchive + ReveilHelper.xcarchive + Distribution/Reveil_${{ env.MARKETING_VERSION }}.dmg + + # - name: Upload Release + # uses: softprops/action-gh-release@v1 + # with: + # token: ${{ secrets.RELEASE_GITHUB_TOKEN }} + # body_path: CHANGELOG.md + # files: Distribution/Reveil_${{ env.MARKETING_VERSION }}.dmg + + - name: Remove Code-Signing Keychain + if: ${{ always() }} + run: | + security delete-keychain "$RUNNER_TEMP/app-signing.keychain-db" diff --git a/.github/workflows/build-archive.yml b/.github/workflows/build-archive.yml index 600df9b..de884ce 100644 --- a/.github/workflows/build-archive.yml +++ b/.github/workflows/build-archive.yml @@ -11,11 +11,11 @@ env: jobs: build: - name: Build sideloading package for TrollStore + name: Build Side-loading Package for TrollStore runs-on: macos-13 steps: - - name: Setup Xcode version + - name: Setup Xcode Version uses: maxim-lobanov/setup-xcode@v1 with: xcode-version: 15.1 @@ -23,23 +23,21 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Update version strings + - name: Read Version Strings run: | export PATCH_VERSION=$(echo "${GITHUB_REF#refs/tags/v}" | cut -d. -f3) echo "PATCH_VERSION=${PATCH_VERSION}" >> $GITHUB_ENV echo "MARKETING_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV - xcrun agvtool new-version -all "${PATCH_VERSION}" - xcrun agvtool new-marketing-version "${GITHUB_REF#refs/tags/v}" - - name: Build helper + - name: Build ReveilHelper run: | xcodebuild clean build archive -scheme ReveilHelper -project Reveil.xcodeproj -archivePath ReveilHelper.xcarchive CODE_SIGNING_ALLOWED=NO | xcpretty && exit ${PIPESTATUS[0]} - - name: Build + - name: Build Reveil run: | PATH=$PWD/ReveilHelper.xcarchive/Products/usr/local/bin:$PATH xcodebuild clean build archive -scheme Reveil -project Reveil.xcodeproj -sdk iphoneos -destination 'generic/platform=iOS' -archivePath Reveil CODE_SIGNING_ALLOWED=NO | xcpretty && exit ${PIPESTATUS[0]} - - name: Package for sideloading + - name: Package for Side-loading run: | cd Reveil.xcarchive/Products/Applications codesign --remove-signature Reveil.app @@ -48,17 +46,22 @@ jobs: mv Applications Payload zip -qr Reveil_${{ env.MARKETING_VERSION }}.tipa Payload cd - - mv Reveil.xcarchive/Products/Reveil_${{ env.MARKETING_VERSION }}.tipa . + mkdir -p Distribution + mv Reveil.xcarchive/Products/Reveil_${{ env.MARKETING_VERSION }}.tipa ./Distribution/ - - name: Upload artifact + - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: Reveil_${{ env.MARKETING_VERSION }} - path: Reveil.xcarchive + path: | + Reveil.xcarchive + ReveilHelper.xcarchive + Distribution/Reveil_${{ env.MARKETING_VERSION }}.tipa - - name: Upload release + - name: Upload Release uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') with: token: ${{ secrets.RELEASE_GITHUB_TOKEN }} body_path: CHANGELOG.md - files: Reveil_${{ env.MARKETING_VERSION }}.tipa + files: Distribution/Reveil_${{ env.MARKETING_VERSION }}.tipa diff --git a/.gitignore b/.gitignore index 25b543a..883cd50 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ DerivedData/ *.dSYM.zip *.dSYM *.xcarchive +Distribution ## Playgrounds timeline.xctimeline diff --git a/Certificates/Certificates.p12 b/Certificates/Certificates.p12 index a19c57b..2fe9711 100644 Binary files a/Certificates/Certificates.p12 and b/Certificates/Certificates.p12 differ diff --git a/ExportOptions.plist b/ExportOptions.plist new file mode 100644 index 0000000..12ae833 --- /dev/null +++ b/ExportOptions.plist @@ -0,0 +1,14 @@ + + + + + destination + upload + method + developer-id + signingStyle + automatic + teamID + GXZ23M5TP2 + + diff --git a/Reveil.xcodeproj/project.pbxproj b/Reveil.xcodeproj/project.pbxproj index 08bbb46..4501403 100644 --- a/Reveil.xcodeproj/project.pbxproj +++ b/Reveil.xcodeproj/project.pbxproj @@ -47,9 +47,10 @@ 0FF1CDBF2AD57109004A6D43 /* NetworkUsage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FF1CDBE2AD57109004A6D43 /* NetworkUsage.swift */; }; 0FF356652AEFEE9D0011033A /* ThreadInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FF356642AEFEE9D0011033A /* ThreadInfo.swift */; }; 0FF356682AEFF6320011033A /* ThreadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FF356672AEFF6320011033A /* ThreadState.swift */; }; - 5024F6EC2B1829EE000CEAB5 /* library_stub.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC7DC28E2AF3EB1300D50EDC /* library_stub.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 5024F6EC2B1829EE000CEAB5 /* library_stub.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC7DC28E2AF3EB1300D50EDC /* library_stub.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 5024F6ED2B1829EE000CEAB5 /* library_stub.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = CC7DC28E2AF3EB1300D50EDC /* library_stub.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 503DF9C32B55934A0034F760 /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 503DF9C22B55934A0034F760 /* ArgumentParser */; }; + 503DF9DF2B5596AD0034F760 /* Color.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 503DF9DE2B5596AD0034F760 /* Color.xcassets */; }; 504B8C632B40243C00AABC12 /* AnimatedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504B8C622B40243C00AABC12 /* AnimatedText.swift */; }; 504B8C652B4033F600AABC12 /* ColorfulBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504B8C642B4033F600AABC12 /* ColorfulBackground.swift */; }; 50E143102B400C6F000A7191 /* View+Brand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E1430F2B400C6F000A7191 /* View+Brand.swift */; }; @@ -135,10 +136,7 @@ CC9D24A92B3D97D200A18513 /* FileIntegrityCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA095FB2AEE22B300F5E55F /* FileIntegrityCheck.swift */; }; CC9D24AA2B3D97E300A18513 /* Explainable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA095FE2AEE22CE00F5E55F /* Explainable.swift */; }; CC9D24AB2B3D97EA00A18513 /* IntegrityCheckerTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA096042AEE239300F5E55F /* IntegrityCheckerTarget.swift */; }; - CCA0954E2AE786CF00F5E55F /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCA0954D2AE786CF00F5E55F /* QuickLook.framework */; }; - CCA0956D2AE8D5E900F5E55F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCA0956C2AE8D5E900F5E55F /* UIKit.framework */; }; - CCA0956F2AE8D5EE00F5E55F /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCA0956E2AE8D5EE00F5E55F /* SwiftUI.framework */; }; - CCA095CC2AE8E6D100F5E55F /* Color+Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA095CB2AE8E6D100F5E55F /* Color+Platform.swift */; }; + CCA095CC2AE8E6D100F5E55F /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA095CB2AE8E6D100F5E55F /* Color.swift */; }; CCA095DF2AED419B00F5E55F /* JailbreakChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA095D32AED419A00F5E55F /* JailbreakChecker.swift */; }; CCA095E12AED419B00F5E55F /* ProxyChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA095D42AED419A00F5E55F /* ProxyChecker.swift */; }; CCA095E32AED419B00F5E55F /* ReverseEngineeringToolsChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA095D52AED419A00F5E55F /* ReverseEngineeringToolsChecker.swift */; }; @@ -237,6 +235,7 @@ 0FF356642AEFEE9D0011033A /* ThreadInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadInfo.swift; sourceTree = ""; }; 0FF356672AEFF6320011033A /* ThreadState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadState.swift; sourceTree = ""; }; 5028D8B22AE7628E008D4294 /* Reveil.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Reveil.entitlements; sourceTree = ""; }; + 503DF9DE2B5596AD0034F760 /* Color.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Color.xcassets; sourceTree = ""; }; 504B8C622B40243C00AABC12 /* AnimatedText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedText.swift; sourceTree = ""; }; 504B8C642B4033F600AABC12 /* ColorfulBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorfulBackground.swift; sourceTree = ""; }; 50E1430F2B400C6F000A7191 /* View+Brand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Brand.swift"; sourceTree = ""; }; @@ -326,7 +325,7 @@ CCA0956E2AE8D5EE00F5E55F /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/System/iOSSupport/System/Library/Frameworks/SwiftUI.framework; sourceTree = DEVELOPER_DIR; }; CCA095702AE8D5F600F5E55F /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; }; CCA095722AE8D5FA00F5E55F /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/System/Library/Frameworks/SwiftUI.framework; sourceTree = DEVELOPER_DIR; }; - CCA095CB2AE8E6D100F5E55F /* Color+Platform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Platform.swift"; sourceTree = ""; }; + CCA095CB2AE8E6D100F5E55F /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; CCA095D32AED419A00F5E55F /* JailbreakChecker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JailbreakChecker.swift; sourceTree = ""; }; CCA095D42AED419A00F5E55F /* ProxyChecker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxyChecker.swift; sourceTree = ""; }; CCA095D52AED419A00F5E55F /* ReverseEngineeringToolsChecker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseEngineeringToolsChecker.swift; sourceTree = ""; }; @@ -369,12 +368,9 @@ files = ( CCD54D2C2AD9047D007ED1AF /* Collections in Frameworks */, CC77C7B62B526EBB00FAB4E3 /* ColorfulX in Frameworks */, - CCA0956D2AE8D5E900F5E55F /* UIKit.framework in Frameworks */, CCD54D2E2AD9047D007ED1AF /* DequeModule in Frameworks */, 5024F6EC2B1829EE000CEAB5 /* library_stub.framework in Frameworks */, - CCA0956F2AE8D5EE00F5E55F /* SwiftUI.framework in Frameworks */, 0F08193D2ADAF1C600BB626C /* DictionaryCoder in Frameworks */, - CCA0954E2AE786CF00F5E55F /* QuickLook.framework in Frameworks */, CCD54D302AD9047D007ED1AF /* OrderedCollections in Frameworks */, CC7DC2A12AF3EEBB00D50EDC /* ZIPFoundation in Frameworks */, ); @@ -470,7 +466,8 @@ children = ( CC3F94232B4C505600E67A19 /* Backports */, CC549EFD2AFA7DB300219CF8 /* Foundation */, - CCA095CB2AE8E6D100F5E55F /* Color+Platform.swift */, + CCA095CB2AE8E6D100F5E55F /* Color.swift */, + 503DF9DE2B5596AD0034F760 /* Color.xcassets */, CC9D249A2B3D954F00A18513 /* URL+Path.swift */, 50E1430F2B400C6F000A7191 /* View+Brand.swift */, ); @@ -907,6 +904,7 @@ CC21B5282ACD4B87003EC114 /* rsc-004-carriers.json in Resources */, CC21B52B2ACD4B87003EC114 /* rsc-006-ipod-models.json in Resources */, CC21B5262ACD4B87003EC114 /* rsc-001-country-mapping.json in Resources */, + 503DF9DF2B5596AD0034F760 /* Color.xcassets in Resources */, CC21B5272ACD4B87003EC114 /* rsc-003-iphone-models.json in Resources */, CC21B4BD2ACAE5E5003EC114 /* Localizable.strings in Resources */, CC21B52A2ACD4B87003EC114 /* rsc-005-ipad-models.json in Resources */, @@ -1068,7 +1066,7 @@ CC21B4F42ACBD004003EC114 /* UsageCell.swift in Sources */, 0F16593A2AF9FD4500268572 /* URLSchemeItem.swift in Sources */, CCA095EB2AED419B00F5E55F /* FileChecker.swift in Sources */, - CCA095CC2AE8E6D100F5E55F /* Color+Platform.swift in Sources */, + CCA095CC2AE8E6D100F5E55F /* Color.swift in Sources */, CC21B4C22ACAE6E6003EC114 /* BartyCrouch.swift in Sources */, CCA095FC2AEE22B300F5E55F /* FileIntegrityCheck.swift in Sources */, CCD54D322AD9385D007ED1AF /* NetworkStatistics.swift in Sources */, @@ -1133,14 +1131,14 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = GXZ23M5TP2; ENABLE_HARDENED_RUNTIME = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 12.0; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_VERSION = 5.0; }; @@ -1152,14 +1150,14 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = GXZ23M5TP2; ENABLE_HARDENED_RUNTIME = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 12.0; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; }; name = Release; @@ -1290,7 +1288,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Reveil/Reveil.entitlements; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = ""; @@ -1300,6 +1298,7 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", "GLES_SILENCE_DEPRECATION=1", + "GL_SILENCE_DEPRECATION=1", ); GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Reveil/Info.plist; @@ -1309,7 +1308,6 @@ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1317,7 +1315,7 @@ MARKETING_VERSION = 2.0; PRODUCT_BUNDLE_IDENTIFIER = com.reveil.app; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; @@ -1333,7 +1331,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Reveil/Reveil.entitlements; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = ""; @@ -1343,6 +1341,7 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", "GLES_SILENCE_DEPRECATION=1", + "GL_SILENCE_DEPRECATION=1", ); GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Reveil/Info.plist; @@ -1352,7 +1351,6 @@ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1360,7 +1358,7 @@ MARKETING_VERSION = 2.0; PRODUCT_BUNDLE_IDENTIFIER = com.reveil.app; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; @@ -1373,12 +1371,13 @@ CC7DC2972AF3EB1300D50EDC /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = GXZ23M5TP2; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -1386,9 +1385,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "@executable_path/Frameworks", "@loader_path/Frameworks", @@ -1398,7 +1395,6 @@ "@loader_path/Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; @@ -1407,7 +1403,7 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = auto; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1421,12 +1417,13 @@ CC7DC2982AF3EB1300D50EDC /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = GXZ23M5TP2; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -1434,9 +1431,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "@executable_path/Frameworks", "@loader_path/Frameworks", @@ -1446,7 +1441,6 @@ "@loader_path/Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; @@ -1455,7 +1449,7 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = auto; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; diff --git a/Reveil.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Reveil.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 789f708..aaca3df 100644 --- a/Reveil.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Reveil.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -3,7 +3,7 @@ { "identity" : "colorfulx", "kind" : "remoteSourceControl", - "location" : "https://github.com/Lakr233/ColorfulX", + "location" : "https://github.com/Lakr233/ColorfulX.git", "state" : { "revision" : "11aae9e92a2f846ed26d275d0d3d6fad85d16837", "version" : "2.3.1" diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/Contents.json b/Reveil/Assets.xcassets/AppIcon.appiconset/Contents.json index d7ab46b..6ce35ce 100644 --- a/Reveil/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Reveil/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -5,6 +5,66 @@ "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" + }, + { + "filename" : "icon_16x16.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "filename" : "icon_16x16@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "filename" : "icon_32x32.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "filename" : "icon_32x32@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "filename" : "icon_128x128.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "filename" : "icon_128x128@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "filename" : "icon_256x256.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "filename" : "icon_256x256@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "filename" : "icon_512x512.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "filename" : "icon_512x512@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" } ], "info" : { diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_128x128.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_128x128.png new file mode 100644 index 0000000..b5d7f8d Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_128x128.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png new file mode 100644 index 0000000..31a2c48 Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_16x16.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_16x16.png new file mode 100644 index 0000000..6a500f7 Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_16x16.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png new file mode 100644 index 0000000..c4ad0a2 Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_256x256.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_256x256.png new file mode 100644 index 0000000..31a2c48 Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_256x256.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png new file mode 100644 index 0000000..0920a70 Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_32x32.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_32x32.png new file mode 100644 index 0000000..c4ad0a2 Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_32x32.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png new file mode 100644 index 0000000..6ea325c Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_512x512.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_512x512.png new file mode 100644 index 0000000..0920a70 Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_512x512.png differ diff --git a/Reveil/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png new file mode 100644 index 0000000..49aaaaf Binary files /dev/null and b/Reveil/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png differ diff --git a/Reveil/ContentView.swift b/Reveil/ContentView.swift index 420390f..f2066d2 100644 --- a/Reveil/ContentView.swift +++ b/Reveil/ContentView.swift @@ -5,7 +5,6 @@ // Created by Lessica on 2023/10/2. // -import UIKit import SwiftUI struct ContentView: View { @@ -15,9 +14,11 @@ struct ContentView: View { if horizontalSizeClass == .compact { return true } + #if canImport(UIKit) if UIDevice.current.userInterfaceIdiom != .pad { return true } + #endif return false } @@ -52,7 +53,9 @@ struct TabsView: View { NavigationView { AboutView() + #if os(iOS) .navigationBarTitleDisplayMode(.inline) + #endif .background(ColorfulBackground()) } .tabItem { @@ -71,9 +74,15 @@ struct SidebarView: View { DashboardView() .navigationTitle(NSLocalizedString("DASHBOARD", comment: "Dashboard")) .background(ColorfulBackground()) + #if os(macOS) + .limitMinSize() + #endif } label: { Label(NSLocalizedString("DASHBOARD", comment: "Dashboard"), systemImage: "square.grid.2x2") } + #if os(macOS) + .buttonStyle(.plain) + #endif } Section(NSLocalizedString("DETAILS", comment: "Details")) { @@ -84,9 +93,15 @@ struct SidebarView: View { NavigationLink { AboutView() .background(ColorfulBackground()) + #if os(macOS) + .limitMinSize() + #endif } label: { Label(NSLocalizedString("ABOUT", comment: "About"), systemImage: "info.circle") } + #if os(macOS) + .buttonStyle(.plain) + #endif } } .navigationTitle(NSLocalizedString("Reveil", comment: "Reveil")) @@ -94,10 +109,33 @@ struct SidebarView: View { DashboardView() .navigationTitle(NSLocalizedString("DASHBOARD", comment: "Dashboard")) .background(ColorfulBackground()) + #if os(macOS) + .limitMinSize() + #endif } .listStyle(SidebarListStyle()) + #if canImport(AppKit) + .toolbar { + ToolbarItem(placement: .navigation) { + Button { + NSApp.sendAction(#selector(NSSplitViewController.toggleSidebar(_:)), to: nil, from: nil) + } label: { + Label("Toggle Sidebar", systemImage: "sidebar.leading") + } + } + } + #endif + } +} + +#if os(macOS) +fileprivate extension View { + @ViewBuilder + func limitMinSize() -> some View { + frame(minWidth: 550, minHeight: 350) } } +#endif // MARK: - Previews diff --git a/Reveil/DataModels/Presets/SecurityPresets.swift b/Reveil/DataModels/Presets/SecurityPresets.swift index 53f5f08..ad95682 100644 --- a/Reveil/DataModels/Presets/SecurityPresets.swift +++ b/Reveil/DataModels/Presets/SecurityPresets.swift @@ -36,32 +36,34 @@ struct SecurityPresets: Codable { private init() {} init(bundleURL: URL) throws { - guard bundleURL.appendingPathComponent("Info.plist").fileExists || - bundleURL.appendingPathComponent("Contents/Info.plist").fileExists, - let bundle = Bundle(url: bundleURL) + let isMobileBundle = bundleURL.appendingPathComponent("Info.plist").fileExists + let isDesktopBundle = bundleURL.appendingPathComponent("Contents/Info.plist").fileExists + + guard isMobileBundle || isDesktopBundle, let bundle = Bundle(url: bundleURL) else { throw ConstructError.invalidBundle(message: String(format: "Failed to initialize bundle at: %@", bundleURL.path)) } - if let bundleExecutableURL = bundle.executableURL, + if isMobileBundle, + let bundleExecutableURL = bundle.executableURL, let executableHashValue = IntegrityChecker.getMachOFileHashValue(.customExecutable(bundleExecutableURL)) { secureMainExecutableMachOHashes.removeAll(keepingCapacity: true) secureMainExecutableMachOHashes.insert(executableHashValue) } - if let bundleProvisioningProfilePath = bundle.path(forResource: "embedded", ofType: "mobileprovision"), + if isMobileBundle, + let bundleProvisioningProfilePath = bundle.path(forResource: "embedded", ofType: "mobileprovision"), let profileHashValue = IntegrityChecker.calculateHashValue(path: bundleProvisioningProfilePath) { secureMobileProvisioningProfileHashes.removeAll(keepingCapacity: true) secureMobileProvisioningProfileHashes.insert(profileHashValue) } - var updatedHashes: Dictionary = secureResourceHashes + var updatedHashes: [String: String] = secureResourceHashes for secureResourceName in secureResourceHashes.keys { let resourcePath = bundle.path(forResource: secureResourceName, ofType: nil) - if let resourcePath, let resourceHashValue = IntegrityChecker.calculateHashValue(path: resourcePath) - { + if let resourcePath, let resourceHashValue = IntegrityChecker.calculateHashValue(path: resourcePath) { updatedHashes.updateValue(resourceHashValue, forKey: secureResourceName) } } @@ -101,7 +103,7 @@ struct SecurityPresets: Codable { "", ] - var secureResourceHashes: Dictionary = [ + var secureResourceHashes: [String: String] = [ "library_stub.zip": "", "rsc-001-country-mapping.json": "", "rsc-002-ios-versions.json": "", diff --git a/Reveil/DataModels/Providers/BatteryActivity.swift b/Reveil/DataModels/Providers/BatteryActivity.swift index 9955c8e..3975b57 100644 --- a/Reveil/DataModels/Providers/BatteryActivity.swift +++ b/Reveil/DataModels/Providers/BatteryActivity.swift @@ -5,11 +5,7 @@ // Created by Lessica on 2023/11/26. // -#if canImport(UIKit) - import UIKit -#else - import Foundation -#endif +import Foundation final class BatteryActivity { static let shared = BatteryActivity() @@ -36,40 +32,40 @@ final class BatteryActivity { private init() { #if canImport(UIKit) - UIDevice.current.isBatteryMonitoringEnabled = true + UIDevice.current.isBatteryMonitoringEnabled = true #endif } deinit { #if canImport(UIKit) - UIDevice.current.isBatteryMonitoringEnabled = false + UIDevice.current.isBatteryMonitoringEnabled = false #endif } func getBatteryLevel() -> Float { #if canImport(UIKit) - return UIDevice.current.batteryLevel + return UIDevice.current.batteryLevel #else - return 1.0 + return 1.0 #endif } func getBatteryState() -> BatteryState { #if canImport(UIKit) - switch UIDevice.current.batteryState { - case .unknown: - return .unknown - case .unplugged: - return .unplugged - case .charging: - return .charging - case .full: - return .full - @unknown default: - return .unknown - } - #else + switch UIDevice.current.batteryState { + case .unknown: + return .unknown + case .unplugged: + return .unplugged + case .charging: + return .charging + case .full: + return .full + @unknown default: return .unknown + } + #else + return .unknown #endif } } diff --git a/Reveil/Extensions/Backports/View+ListSectionSeparator.swift b/Reveil/Extensions/Backports/View+ListSectionSeparator.swift index 37aa6c5..3afc241 100644 --- a/Reveil/Extensions/Backports/View+ListSectionSeparator.swift +++ b/Reveil/Extensions/Backports/View+ListSectionSeparator.swift @@ -10,7 +10,7 @@ import SwiftUI extension View { @ViewBuilder func listSectionSeparator(hidden: Bool = true) -> some View { - if #available(iOS 15.0, *) { + if #available(iOS 15.0, macOS 13.0, *) { self.listSectionSeparator(hidden ? .hidden : .visible, edges: .all) } else { self @@ -19,7 +19,7 @@ extension View { @ViewBuilder func listSectionSeparator(topHidden: Bool = true) -> some View { - if #available(iOS 15.0, *) { + if #available(iOS 15.0, macOS 13.0, *) { self.listSectionSeparator(topHidden ? .hidden : .visible, edges: .top) } else { self @@ -28,7 +28,7 @@ extension View { @ViewBuilder func listSectionSeparator(bottomHidden: Bool = true) -> some View { - if #available(iOS 15.0, *) { + if #available(iOS 15.0, macOS 13.0, *) { self.listSectionSeparator(bottomHidden ? .hidden : .visible, edges: .bottom) } else { self diff --git a/Reveil/Extensions/Color+Platform.swift b/Reveil/Extensions/Color+Platform.swift deleted file mode 100644 index 211fb21..0000000 --- a/Reveil/Extensions/Color+Platform.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// Color+Platform.swift -// Reveil -// -// Created by Lessica on 2023/10/25. -// - -import UIKit - -typealias PlatformColor = UIColor -extension PlatformColor { - static let labelAlias = PlatformColor.label - static let secondaryLabelAlias = PlatformColor.secondaryLabel - static let tertiaryLabelAlias = PlatformColor.tertiaryLabel - static let secondarySystemBackgroundAlias = PlatformColor.secondarySystemBackground - static let secondarySystemFillAlias = PlatformColor.secondarySystemFill - static let separatorAlias = PlatformColor.separator - static let systemGray4Alias = PlatformColor.systemGray4 -} diff --git a/Reveil/Extensions/Color.swift b/Reveil/Extensions/Color.swift new file mode 100644 index 0000000..69d96fc --- /dev/null +++ b/Reveil/Extensions/Color.swift @@ -0,0 +1,32 @@ +// +// Color.swift +// Reveil +// +// Created by Lessica on 2023/10/25. +// + +import SwiftUI + +extension Color { + #if os(iOS) + static let labelAlias = Color(UIColor.label) + static let secondaryLabelAlias = Color(UIColor.secondaryLabel) + static let tertiaryLabelAlias = Color(UIColor.tertiaryLabel) + static let secondarySystemBackgroundAlias = Color(UIColor.secondarySystemBackground) + static let secondarySystemFillAlias = Color(UIColor.secondarySystemFill) + static let separatorAlias = Color(UIColor.separator) + static let systemGray4Alias = Color(UIColor.systemGray4) + static let systemBackground = Color(UIColor.systemBackground) + #endif + + #if os(macOS) + static let labelAlias = Color("COLOR_LABEL") + static let secondaryLabelAlias = Color("COLOR_SECONDARYLABEL") + static let tertiaryLabelAlias = Color("COLOR_TERTIARYLABEL") + static let secondarySystemBackgroundAlias = Color("COLOR_SECONDARYSYSTEMBACKGROUND") + static let secondarySystemFillAlias = Color("COLOR_SECONDARYSYSTEMFILL") + static let separatorAlias = Color("COLOR_SEPARATOR") + static let systemGray4Alias = Color("COLOR_SYSTEMGRAY4") + static let systemBackground = Color("COLOR_SYSTEMBACKGROUND") + #endif +} diff --git a/Reveil/Extensions/Color.xcassets/COLOR_LABEL.colorset/Contents.json b/Reveil/Extensions/Color.xcassets/COLOR_LABEL.colorset/Contents.json new file mode 100644 index 0000000..0c600f9 --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/COLOR_LABEL.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYLABEL.colorset/Contents.json b/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYLABEL.colorset/Contents.json new file mode 100644 index 0000000..0e43788 --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYLABEL.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x43", + "green" : "0x3C", + "red" : "0x3C" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF5", + "green" : "0xEB", + "red" : "0xEB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYSYSTEMBACKGROUND.colorset/Contents.json b/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYSYSTEMBACKGROUND.colorset/Contents.json new file mode 100644 index 0000000..0e43788 --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYSYSTEMBACKGROUND.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x43", + "green" : "0x3C", + "red" : "0x3C" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF5", + "green" : "0xEB", + "red" : "0xEB" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYSYSTEMFILL.colorset/Contents.json b/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYSYSTEMFILL.colorset/Contents.json new file mode 100644 index 0000000..4c8ef69 --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/COLOR_SECONDARYSYSTEMFILL.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF7", + "green" : "0xF2", + "red" : "0xF2" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x1E", + "green" : "0x1C", + "red" : "0x1C" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/Color.xcassets/COLOR_SEPARATOR.colorset/Contents.json b/Reveil/Extensions/Color.xcassets/COLOR_SEPARATOR.colorset/Contents.json new file mode 100644 index 0000000..2334534 --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/COLOR_SEPARATOR.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x80", + "green" : "0x78", + "red" : "0x78" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x80", + "green" : "0x78", + "red" : "0x78" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/Color.xcassets/COLOR_SYSTEMBACKGROUND.colorset/Contents.json b/Reveil/Extensions/Color.xcassets/COLOR_SYSTEMBACKGROUND.colorset/Contents.json new file mode 100644 index 0000000..9c0e331 --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/COLOR_SYSTEMBACKGROUND.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/Color.xcassets/COLOR_SYSTEMGRAY4.colorset/Contents.json b/Reveil/Extensions/Color.xcassets/COLOR_SYSTEMGRAY4.colorset/Contents.json new file mode 100644 index 0000000..700bf50 --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/COLOR_SYSTEMGRAY4.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x43", + "green" : "0x3C", + "red" : "0x3C" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x58", + "green" : "0x54", + "red" : "0x54" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/Color.xcassets/COLOR_TERTIARYLABEL.colorset/Contents.json b/Reveil/Extensions/Color.xcassets/COLOR_TERTIARYLABEL.colorset/Contents.json new file mode 100644 index 0000000..1290f0a --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/COLOR_TERTIARYLABEL.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD6", + "green" : "0xD1", + "red" : "0xD1" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x3C", + "green" : "0x3A", + "red" : "0x3A" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/Color.xcassets/Contents.json b/Reveil/Extensions/Color.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Reveil/Extensions/Color.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Reveil/Extensions/View+Brand.swift b/Reveil/Extensions/View+Brand.swift index 98e041d..f37d840 100644 --- a/Reveil/Extensions/View+Brand.swift +++ b/Reveil/Extensions/View+Brand.swift @@ -11,7 +11,9 @@ import SwiftUI extension View { func navigationBarAttachBrand() -> some View { navigationTitle(NSLocalizedString("Reveil", comment: "Reveil")) + #if os(iOS) .navigationBarTitleDisplayMode(.inline) + #endif .toolbar { ToolbarItem(placement: .principal) { Image("IconShape") diff --git a/Reveil/GlobalTimer.swift b/Reveil/GlobalTimer.swift index f6218ba..4315884 100644 --- a/Reveil/GlobalTimer.swift +++ b/Reveil/GlobalTimer.swift @@ -26,7 +26,7 @@ final class GlobalTimer: ObservableObject { if observers.isEmpty { return } - observers.forEach { [unowned self] (key: ModuleName, observer: Observer) in + observers.forEach { [unowned self] (_: ModuleName, observer: Observer) in observer.value.eventOccurred(globalTimer: self) } } @@ -35,7 +35,7 @@ final class GlobalTimer: ObservableObject { timer.fire() } - func addObserver(_ observer: T) where T: GlobalTimerObserver { + func addObserver(_ observer: some GlobalTimerObserver) { let globalName = observer.globalName if observers[globalName] != nil { observers[globalName]?.registeredCount += 1 @@ -43,8 +43,8 @@ final class GlobalTimer: ObservableObject { } observers[globalName] = Observer(value: observer, registeredCount: 1) } - - func removeObserver(_ observer: T) where T: GlobalTimerObserver { + + func removeObserver(_ observer: some GlobalTimerObserver) { let globalName = observer.globalName guard observers[globalName] != nil else { return diff --git a/Reveil/Pages/AboutView.swift b/Reveil/Pages/AboutView.swift index e36ed80..50b8ee2 100644 --- a/Reveil/Pages/AboutView.swift +++ b/Reveil/Pages/AboutView.swift @@ -101,7 +101,7 @@ struct AboutView: View { } footer: { Text(NSLocalizedString("COPYRIGHT_STRING", comment: "Copyright © 2023-2024 Lessica & Lakr Aream.\nAll rights reserved.")) .font(Font.system(.footnote)) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .multilineTextAlignment(.center) .padding() } @@ -116,6 +116,9 @@ struct AboutView: View { } .foregroundStyle(accent: true) .quickLookPreview($quickLookExport) + #if os(macOS) + .buttonStyle(.plain) + #endif } .padding() } @@ -176,14 +179,14 @@ private struct LinkCell: View { .resizable() .renderingMode(.template) .scaledToFill() - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .frame(width: 18, height: 18) } if let description { Text(description) .font(Font.system(.body)) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .lineLimit(1) } @@ -192,7 +195,7 @@ private struct LinkCell: View { Image(systemName: "chevron.right") .font(Font.system(.body).weight(.bold)) - .foregroundColor(Color(PlatformColor.tertiaryLabelAlias)) + .foregroundColor(Color.tertiaryLabelAlias) } } } diff --git a/Reveil/Pages/DashboardView.swift b/Reveil/Pages/DashboardView.swift index e638841..2525ba8 100644 --- a/Reveil/Pages/DashboardView.swift +++ b/Reveil/Pages/DashboardView.swift @@ -9,7 +9,7 @@ import SwiftUI struct DashboardView: View, GlobalTimerObserver { let id = UUID() - let globalName: String = String(describing: Dashboard.self) + let globalName: String = .init(describing: Dashboard.self) @ObservedObject private var viewModel = Dashboard.shared @ObservedObject private var securityModel = Security.shared @@ -18,9 +18,11 @@ struct DashboardView: View, GlobalTimerObserver { var body: some View { ScrollView(.vertical) { VStack { + #if os(iOS) if PinStorage.shared.isPinned(forKey: .Security) { Section { CheckmarkWidget() } } + #endif ForEach(viewModel.entries, id: \.key) { entry in Section { @@ -28,12 +30,12 @@ struct DashboardView: View, GlobalTimerObserver { .padding(.all, 12) .background( RoundedRectangle(cornerRadius: 4) - .foregroundColor(Color(PlatformColor.secondarySystemBackgroundAlias)) - .opacity(0.25) + .foregroundColor(Color.secondarySystemBackgroundAlias) + .opacity(0.2) ) .overlay { RoundedRectangle(cornerRadius: 4) - .stroke(Color(PlatformColor.separatorAlias), lineWidth: 1) + .stroke(Color.separatorAlias, lineWidth: 1) } .overlay { navigationLinkBuilder(entry) } } @@ -91,9 +93,12 @@ struct DashboardView: View, GlobalTimerObserver { .environmentObject(HighlightedEntryKey(object: entry.key)) }, label: { Color.clear }) .contentShape(Rectangle()) + #if os(macOS) + .buttonStyle(.plain) + #endif } - func eventOccurred(globalTimer timer: GlobalTimer) { + func eventOccurred(globalTimer _: GlobalTimer) { viewModel.updateEntries() } } diff --git a/Reveil/Pages/Details/BatteryInformationListView.swift b/Reveil/Pages/Details/BatteryInformationListView.swift index 5a3fe7b..6a0b9fc 100644 --- a/Reveil/Pages/Details/BatteryInformationListView.swift +++ b/Reveil/Pages/Details/BatteryInformationListView.swift @@ -10,7 +10,7 @@ import SwiftUI struct BatteryInformationListView: View, Identifiable, ModuleListView, GlobalTimerObserver { let id = UUID() let module: Module = BatteryInformation.shared - let globalName: String = String(describing: BatteryInformation.self) + let globalName: String = .init(describing: BatteryInformation.self) init() {} @@ -27,10 +27,15 @@ struct BatteryInformationListView: View, Identifiable, ModuleListView, GlobalTim usageStyle: .compat ) .navigationTitle(module.moduleName) - .navigationBarItems(trailing: PinButton(pin: AppCodableStorage( - wrappedValue: Pin(false), .BatteryInformation, - store: PinStorage.shared.userDefaults - ))) + + .toolbar { + ToolbarItem { + PinButton(pin: AppCodableStorage( + wrappedValue: Pin(false), .BatteryInformation, + store: PinStorage.shared.userDefaults + )) + } + } .onAppear { GlobalTimer.shared.addObserver(self) } @@ -39,7 +44,7 @@ struct BatteryInformationListView: View, Identifiable, ModuleListView, GlobalTim } } - func eventOccurred(globalTimer timer: GlobalTimer) { + func eventOccurred(globalTimer _: GlobalTimer) { module.updateEntries() } } diff --git a/Reveil/Pages/Details/CPUInformationListView.swift b/Reveil/Pages/Details/CPUInformationListView.swift index 3c10871..965fc07 100644 --- a/Reveil/Pages/Details/CPUInformationListView.swift +++ b/Reveil/Pages/Details/CPUInformationListView.swift @@ -10,7 +10,7 @@ import SwiftUI struct CPUInformationListView: View, Identifiable, ModuleListView, GlobalTimerObserver { let id = UUID() let module: Module = CPUInformation.shared - let globalName: String = String(describing: CPUInformation.self) + let globalName: String = .init(describing: CPUInformation.self) init() {} @@ -27,10 +27,14 @@ struct CPUInformationListView: View, Identifiable, ModuleListView, GlobalTimerOb usageStyle: .compat ) .navigationTitle(module.moduleName) - .navigationBarItems(trailing: PinButton(pin: AppCodableStorage( - wrappedValue: Pin(true), EntryKey.CPUInformation, - store: PinStorage.shared.userDefaults - ))) + .toolbar { + ToolbarItem { + PinButton(pin: AppCodableStorage( + wrappedValue: Pin(true), EntryKey.CPUInformation, + store: PinStorage.shared.userDefaults + )) + } + } .onAppear { GlobalTimer.shared.addObserver(self) } @@ -39,7 +43,7 @@ struct CPUInformationListView: View, Identifiable, ModuleListView, GlobalTimerOb } } - func eventOccurred(globalTimer timer: GlobalTimer) { + func eventOccurred(globalTimer _: GlobalTimer) { module.updateEntries() } } diff --git a/Reveil/Pages/Details/DeviceInformationListView.swift b/Reveil/Pages/Details/DeviceInformationListView.swift index 63ff6be..a433ac1 100644 --- a/Reveil/Pages/Details/DeviceInformationListView.swift +++ b/Reveil/Pages/Details/DeviceInformationListView.swift @@ -9,7 +9,7 @@ import SwiftUI struct DeviceInformationListView: View, ModuleListView { let module: Module = DeviceInformation.shared - let globalName: String = String(describing: DeviceInformation.self) + let globalName: String = .init(describing: DeviceInformation.self) init() {} @@ -24,7 +24,7 @@ struct DeviceInformationListView: View, ModuleListView { .navigationTitle(module.moduleName) } - func eventOccurred(globalTimer timer: GlobalTimer) { } + func eventOccurred(globalTimer _: GlobalTimer) {} } // MARK: - Previews diff --git a/Reveil/Pages/Details/DiskSpaceListView.swift b/Reveil/Pages/Details/DiskSpaceListView.swift index f44b8da..38dda45 100644 --- a/Reveil/Pages/Details/DiskSpaceListView.swift +++ b/Reveil/Pages/Details/DiskSpaceListView.swift @@ -10,7 +10,7 @@ import SwiftUI struct DiskSpaceListView: View, Identifiable, ModuleListView, GlobalTimerObserver { let id = UUID() let module: Module = DiskSpace.shared - let globalName: String = String(describing: DiskSpace.self) + let globalName: String = .init(describing: DiskSpace.self) init() {} @@ -27,10 +27,14 @@ struct DiskSpaceListView: View, Identifiable, ModuleListView, GlobalTimerObserve usageStyle: .compat ) .navigationTitle(module.moduleName) - .navigationBarItems(trailing: PinButton(pin: AppCodableStorage( - wrappedValue: Pin(true), .DiskSpace, - store: PinStorage.shared.userDefaults - ))) + .toolbar { + ToolbarItem { + PinButton(pin: AppCodableStorage( + wrappedValue: Pin(true), .DiskSpace, + store: PinStorage.shared.userDefaults + )) + } + } .onAppear { GlobalTimer.shared.addObserver(self) } @@ -39,7 +43,7 @@ struct DiskSpaceListView: View, Identifiable, ModuleListView, GlobalTimerObserve } } - func eventOccurred(globalTimer timer: GlobalTimer) { + func eventOccurred(globalTimer _: GlobalTimer) { module.updateEntries() } } diff --git a/Reveil/Pages/Details/FileSystemListView.swift b/Reveil/Pages/Details/FileSystemListView.swift index cfcd5c5..04257a8 100644 --- a/Reveil/Pages/Details/FileSystemListView.swift +++ b/Reveil/Pages/Details/FileSystemListView.swift @@ -9,7 +9,7 @@ import SwiftUI struct FileSystemListView: View, ModuleListView { let module: Module = FileSystems.shared - let globalName: String = String(describing: FileSystems.self) + let globalName: String = .init(describing: FileSystems.self) init?(entryKey _: EntryKey) { nil } @@ -29,7 +29,7 @@ struct FileSystemListView: View, ModuleListView { } } - func eventOccurred(globalTimer timer: GlobalTimer) { } + func eventOccurred(globalTimer _: GlobalTimer) {} } // MARK: - Previews diff --git a/Reveil/Pages/Details/FileSystemsListView.swift b/Reveil/Pages/Details/FileSystemsListView.swift index dca1304..5838043 100644 --- a/Reveil/Pages/Details/FileSystemsListView.swift +++ b/Reveil/Pages/Details/FileSystemsListView.swift @@ -9,7 +9,7 @@ import SwiftUI struct FileSystemsListView: View, ModuleListView { let module: Module = FileSystems.shared - let globalName: String = String(describing: FileSystems.self) + let globalName: String = .init(describing: FileSystems.self) init() {} @@ -31,6 +31,7 @@ struct FileSystemsListView: View, ModuleListView { FileSystemListView(item: entry) .environmentObject(HighlightedEntryKey()) } + .buttonStyle(.plain) } } .listSectionSeparator(hidden: true) @@ -38,19 +39,21 @@ struct FileSystemsListView: View, ModuleListView { .listStyle(.plain) .frame(maxWidth: .infinity) .navigationTitle(module.moduleName) - .navigationBarItems( - trailing: PinButton(pin: AppCodableStorage( - wrappedValue: Pin(false), .FileSystems, - store: PinStorage.shared.userDefaults - )) - ) + .toolbar { + ToolbarItem { + PinButton(pin: AppCodableStorage( + wrappedValue: Pin(false), .FileSystems, + store: PinStorage.shared.userDefaults + )) + } + } .onAppear { FileSystems.shared.reloadData() items = FileSystems.shared.items } } - func eventOccurred(globalTimer timer: GlobalTimer) { } + func eventOccurred(globalTimer _: GlobalTimer) {} } // MARK: - Previews diff --git a/Reveil/Pages/Details/MemoryInformationListView.swift b/Reveil/Pages/Details/MemoryInformationListView.swift index eb10281..f504fc2 100644 --- a/Reveil/Pages/Details/MemoryInformationListView.swift +++ b/Reveil/Pages/Details/MemoryInformationListView.swift @@ -10,7 +10,7 @@ import SwiftUI struct MemoryInformationListView: View, Identifiable, ModuleListView, GlobalTimerObserver { let id = UUID() let module: Module = MemoryInformation.shared - let globalName: String = String(describing: MemoryInformation.self) + let globalName: String = .init(describing: MemoryInformation.self) init() {} @@ -27,10 +27,14 @@ struct MemoryInformationListView: View, Identifiable, ModuleListView, GlobalTime usageStyle: .regular ) .navigationTitle(module.moduleName) - .navigationBarItems(trailing: PinButton(pin: AppCodableStorage( - wrappedValue: Pin(true), .MemoryInformation, - store: PinStorage.shared.userDefaults - ))) + .toolbar { + ToolbarItem { + PinButton(pin: AppCodableStorage( + wrappedValue: Pin(true), .MemoryInformation, + store: PinStorage.shared.userDefaults + )) + } + } .onAppear { GlobalTimer.shared.addObserver(self) } @@ -39,7 +43,7 @@ struct MemoryInformationListView: View, Identifiable, ModuleListView, GlobalTime } } - func eventOccurred(globalTimer timer: GlobalTimer) { + func eventOccurred(globalTimer _: GlobalTimer) { module.updateEntries() } } diff --git a/Reveil/Pages/Details/NetworkDetailListView.swift b/Reveil/Pages/Details/NetworkDetailListView.swift index 01270f3..5f502b9 100644 --- a/Reveil/Pages/Details/NetworkDetailListView.swift +++ b/Reveil/Pages/Details/NetworkDetailListView.swift @@ -10,7 +10,7 @@ import SwiftUI struct NetworkDetailListView: View, Identifiable, ModuleListView, GlobalTimerObserver { let id = UUID() let module: Module = NetworkDetails.shared - let globalName: String = String(describing: NetworkDetails.self) + let globalName: String = .init(describing: NetworkDetails.self) init?(entryKey: EntryKey) { switch entryKey { @@ -19,7 +19,7 @@ struct NetworkDetailListView: View, Identifiable, ModuleListView, GlobalTimerObs guard let pfx = NetworkPrefix(rawValue: prefix) else { return nil } - self.item = pfx + item = pfx default: return nil } @@ -53,7 +53,7 @@ struct NetworkDetailListView: View, Identifiable, ModuleListView, GlobalTimerObs } } - func eventOccurred(globalTimer timer: GlobalTimer) { + func eventOccurred(globalTimer _: GlobalTimer) { if let module = module as? NetworkDetails { module.update(prefix: item) } diff --git a/Reveil/Pages/Details/NetworkDetailsListView.swift b/Reveil/Pages/Details/NetworkDetailsListView.swift index 9e88a51..fc958dc 100644 --- a/Reveil/Pages/Details/NetworkDetailsListView.swift +++ b/Reveil/Pages/Details/NetworkDetailsListView.swift @@ -9,7 +9,7 @@ import SwiftUI struct NetworkDetailsListView: View, ModuleListView { let module: Module = NetworkDetails.shared - let globalName: String = String(describing: NetworkDetails.self) + let globalName: String = .init(describing: NetworkDetails.self) init() {} @@ -25,6 +25,9 @@ struct NetworkDetailsListView: View, ModuleListView { NetworkDetailListView(item: prefix) .environmentObject(HighlightedEntryKey()) } + #if os(macOS) + .buttonStyle(.plain) + #endif } var body: some View { @@ -44,7 +47,7 @@ struct NetworkDetailsListView: View, ModuleListView { } } - func eventOccurred(globalTimer timer: GlobalTimer) { } + func eventOccurred(globalTimer _: GlobalTimer) {} } // MARK: - Previews diff --git a/Reveil/Pages/Details/NetworkInterfaceListView.swift b/Reveil/Pages/Details/NetworkInterfaceListView.swift index f92cccb..68d49f9 100644 --- a/Reveil/Pages/Details/NetworkInterfaceListView.swift +++ b/Reveil/Pages/Details/NetworkInterfaceListView.swift @@ -9,7 +9,7 @@ import SwiftUI struct NetworkInterfaceListView: View, ModuleListView { let module: Module = NetworkInterfaces.shared - let globalName: String = String(describing: NetworkInterfaces.self) + let globalName: String = .init(describing: NetworkInterfaces.self) init?(entryKey _: EntryKey) { nil } @@ -29,7 +29,7 @@ struct NetworkInterfaceListView: View, ModuleListView { } } - func eventOccurred(globalTimer timer: GlobalTimer) { } + func eventOccurred(globalTimer _: GlobalTimer) {} } // MARK: - Previews diff --git a/Reveil/Pages/Details/NetworkInterfacesListView.swift b/Reveil/Pages/Details/NetworkInterfacesListView.swift index 02cd78e..3288072 100644 --- a/Reveil/Pages/Details/NetworkInterfacesListView.swift +++ b/Reveil/Pages/Details/NetworkInterfacesListView.swift @@ -9,7 +9,7 @@ import SwiftUI struct NetworkInterfacesListView: View, ModuleListView { let module: Module = NetworkInterfaces.shared - let globalName: String = String(describing: NetworkInterfaces.self) + let globalName: String = .init(describing: NetworkInterfaces.self) init() {} @@ -31,6 +31,9 @@ struct NetworkInterfacesListView: View, ModuleListView { NetworkInterfaceListView(item: entry) .environmentObject(HighlightedEntryKey()) } + #if os(macOS) + .buttonStyle(.plain) + #endif } } .listSectionSeparator(hidden: true) @@ -38,19 +41,21 @@ struct NetworkInterfacesListView: View, ModuleListView { .listStyle(.plain) .frame(maxWidth: .infinity) .navigationTitle(module.moduleName) - .navigationBarItems( - trailing: PinButton(pin: AppCodableStorage( - wrappedValue: Pin(false), .NetworkInterfaces, - store: PinStorage.shared.userDefaults - )) - ) + .toolbar { + ToolbarItem { + PinButton(pin: AppCodableStorage( + wrappedValue: Pin(false), .NetworkInterfaces, + store: PinStorage.shared.userDefaults + )) + } + } .onAppear { NetworkInterfaces.shared.reloadData() items = NetworkInterfaces.shared.items } } - func eventOccurred(globalTimer timer: GlobalTimer) { } + func eventOccurred(globalTimer _: GlobalTimer) {} } // MARK: - Previews diff --git a/Reveil/Pages/Details/NetworkUsageListView.swift b/Reveil/Pages/Details/NetworkUsageListView.swift index 259d6cf..7818ca8 100644 --- a/Reveil/Pages/Details/NetworkUsageListView.swift +++ b/Reveil/Pages/Details/NetworkUsageListView.swift @@ -10,7 +10,7 @@ import SwiftUI struct NetworkUsageListView: View, Identifiable, ModuleListView, GlobalTimerObserver { let id = UUID() let module: Module = NetworkUsage.shared - let globalName: String = String(describing: NetworkUsage.self) + let globalName: String = .init(describing: NetworkUsage.self) init() {} @@ -27,10 +27,14 @@ struct NetworkUsageListView: View, Identifiable, ModuleListView, GlobalTimerObse usageStyle: .regular ) .navigationTitle(module.moduleName) - .navigationBarItems(trailing: PinButton(pin: AppCodableStorage( - wrappedValue: Pin(false), .NetworkUsage, - store: PinStorage.shared.userDefaults - ))) + .toolbar { + ToolbarItem { + PinButton(pin: AppCodableStorage( + wrappedValue: Pin(false), .NetworkUsage, + store: PinStorage.shared.userDefaults + )) + } + } .onAppear { GlobalTimer.shared.addObserver(self) } @@ -39,7 +43,7 @@ struct NetworkUsageListView: View, Identifiable, ModuleListView, GlobalTimerObse } } - func eventOccurred(globalTimer timer: GlobalTimer) { + func eventOccurred(globalTimer _: GlobalTimer) { module.updateEntries() } } diff --git a/Reveil/Pages/Details/OperatingSystemListView.swift b/Reveil/Pages/Details/OperatingSystemListView.swift index 8931e52..7489ac1 100644 --- a/Reveil/Pages/Details/OperatingSystemListView.swift +++ b/Reveil/Pages/Details/OperatingSystemListView.swift @@ -10,7 +10,7 @@ import SwiftUI struct OperatingSystemListView: View, Identifiable, ModuleListView, GlobalTimerObserver { let id = UUID() let module: Module = OperatingSystem.shared - let globalName: String = String(describing: OperatingSystem.self) + let globalName: String = .init(describing: OperatingSystem.self) init() {} @@ -31,7 +31,7 @@ struct OperatingSystemListView: View, Identifiable, ModuleListView, GlobalTimerO } } - func eventOccurred(globalTimer timer: GlobalTimer) { + func eventOccurred(globalTimer _: GlobalTimer) { module.updateEntries() } } diff --git a/Reveil/Pages/DetailsListView.swift b/Reveil/Pages/DetailsListView.swift index 829c544..b307d65 100644 --- a/Reveil/Pages/DetailsListView.swift +++ b/Reveil/Pages/DetailsListView.swift @@ -13,8 +13,6 @@ struct DetailsListView: View, FieldCellDelegate { var usageEntry: UsageEntry? = nil var usageStyle: UsageCell.Style = .regular - private let pasteboard = UIPasteboard.general - @Environment(\.dismiss) private var dismissAction @EnvironmentObject private var highlightedEntryKey: HighlightedEntryKey @@ -145,6 +143,9 @@ struct DetailsListView: View, FieldCellDelegate { } label: { FieldCell(entry: entry, delegate: self) } + #if os(macOS) + .buttonStyle(.plain) + #endif } else { Button { var valueToCopy: String? @@ -154,19 +155,31 @@ struct DetailsListView: View, FieldCellDelegate { valueToCopy = entry.name } if let valueToCopy { - pasteboard.string = valueToCopy + #if canImport(UIKit) + UIPasteboard.general.string = valueToCopy + #endif + #if canImport(AppKit) + NSPasteboard.general.prepareForNewContents() + NSPasteboard.general.setString(valueToCopy, forType: .string) + #endif + showToast( message: NSLocalizedString("COPIED_TO_CLIPBOARD", comment: "Copied to clipboard"), icon: "info.circle.fill" ) + #if canImport(UIKit) let generator = UIImpactFeedbackGenerator(style: .medium) generator.impactOccurred() + #endif } } label: { FieldCell(entry: entry, delegate: self) } - .listRowBackground(selectedEntryKey == entry.key ? Color(PlatformColor.systemGray4Alias) : nil) + .listRowBackground(selectedEntryKey == entry.key ? Color.systemGray4Alias : nil) + #if os(macOS) + .buttonStyle(.plain) + #endif } } diff --git a/Reveil/Pages/DetailsView.swift b/Reveil/Pages/DetailsView.swift index 84f4e3e..507574a 100644 --- a/Reveil/Pages/DetailsView.swift +++ b/Reveil/Pages/DetailsView.swift @@ -15,55 +15,97 @@ struct DetailsView: View { } label: { Label(title, systemImage: icon) } + #if os(macOS) + .buttonStyle(.plain) + #endif } static func createDetailsList() -> some View { Group { Group { createEntry(title: DeviceInformation.shared.moduleName, icon: "desktopcomputer") { - DeviceInformationListView() + prepareContent { + DeviceInformationListView() + } } createEntry(title: Security.shared.moduleName, icon: "lock.shield") { - SecurityView() + prepareContent { + SecurityView() + } } createEntry(title: OperatingSystem.shared.moduleName, icon: "gearshape") { - OperatingSystemListView() + prepareContent { + OperatingSystemListView() + } } createEntry(title: CPUInformation.shared.moduleName, icon: "cpu") { - CPUInformationListView() + prepareContent { + CPUInformationListView() + } } } Group { createEntry(title: MemoryInformation.shared.moduleName, icon: "memorychip") { - MemoryInformationListView() + prepareContent { + MemoryInformationListView() + } } createEntry(title: DiskSpace.shared.moduleName, icon: "externaldrive") { - DiskSpaceListView() + prepareContent { + DiskSpaceListView() + } } createEntry(title: FileSystems.shared.moduleName, icon: "folder") { - FileSystemsListView() + prepareContent { + FileSystemsListView() + } } } Group { createEntry(title: NetworkInterfaces.shared.moduleName, icon: "network") { - NetworkInterfacesListView() + prepareContent { + NetworkInterfacesListView() + } } createEntry(title: NetworkDetails.shared.moduleName, icon: "antenna.radiowaves.left.and.right") { - NetworkDetailsListView() + prepareContent { + NetworkDetailsListView() + } } createEntry(title: NetworkUsage.shared.moduleName, icon: "waveform.path.ecg") { - NetworkUsageListView() + prepareContent { + NetworkUsageListView() + } } } Group { createEntry(title: BatteryInformation.shared.moduleName, icon: "battery.100") { - BatteryInformationListView() + prepareContent { + BatteryInformationListView() + } } } } .listSectionSeparator(topHidden: true) } + private static func prepareContent(_ input: @escaping () -> some View) -> some View { + #if canImport(AppKit) + return GeometryReader { r in + NavigationView { + input() + .frame(width: r.size.width / 2) + Text(NSLocalizedString("Reveil", comment: "Reveil")) + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + } + .limitMinSize() + #endif + #if canImport(UIKit) + return input() + #endif + } + var body: some View { List { Self.createDetailsList() @@ -73,6 +115,15 @@ struct DetailsView: View { } } +#if os(macOS) +fileprivate extension View { + @ViewBuilder + func limitMinSize() -> some View { + frame(minWidth: 550, minHeight: 350) + } +} +#endif + // MARK: - Previews struct DetailsView_Previews: PreviewProvider { diff --git a/Reveil/Pages/SecurityView.swift b/Reveil/Pages/SecurityView.swift index aef7c43..96e7204 100644 --- a/Reveil/Pages/SecurityView.swift +++ b/Reveil/Pages/SecurityView.swift @@ -15,9 +15,15 @@ struct SecurityView: View { var body: some View { DetailsListView(basicEntries: securityModel.basicEntries) .navigationTitle(NSLocalizedString("SECURITY", comment: "Security")) - .navigationBarItems(trailing: PinButton(pin: AppCodableStorage( - wrappedValue: Pin(true), .Security, - store: PinStorage.shared.userDefaults - ))) + #if os(iOS) + .toolbar { + ToolbarItem { + PinButton(pin: AppCodableStorage( + wrappedValue: Pin(true), .Security, + store: PinStorage.shared.userDefaults + )) + } + } + #endif } } diff --git a/Reveil/ReveilApp.swift b/Reveil/ReveilApp.swift index 0cdde0b..3b73352 100644 --- a/Reveil/ReveilApp.swift +++ b/Reveil/ReveilApp.swift @@ -7,6 +7,14 @@ import SwiftUI +#if canImport(UIKit) +@_exported import UIKit +#endif + +#if canImport(AppKit) +@_exported import AppKit +#endif + @main struct ReveilApp: App { init() { _ = PinStorage.shared } @@ -15,5 +23,11 @@ struct ReveilApp: App { WindowGroup { ContentView() } + #if canImport(AppKit) + .commands { + SidebarCommands() + } + .windowToolbarStyle(.unifiedCompact) + #endif } } diff --git a/Reveil/SecuritySuite/JailbreakChecker.swift b/Reveil/SecuritySuite/JailbreakChecker.swift index 9de4e46..b0ee9b9 100644 --- a/Reveil/SecuritySuite/JailbreakChecker.swift +++ b/Reveil/SecuritySuite/JailbreakChecker.swift @@ -11,7 +11,6 @@ import Darwin // fork import Foundation import MachO // dyld import ObjectiveC // NSObject and Selector -import UIKit enum JailbreakChecker { struct JailbreakStatus: Codable { @@ -81,22 +80,28 @@ enum JailbreakChecker { private static func canOpenURLFromList(urlSchemes: [String]) -> CheckResult { for urlScheme in urlSchemes { if let url = URL(string: urlScheme) { + #if canImport(UIKit) if UIApplication.shared.canOpenURL(url) { return CheckResult(passed: false, failMessage: "\(urlScheme) URL scheme detected") } + #endif } } return CheckResult(passed: true, failMessage: "") } static func getSuspiciousURLSchemes() -> [URLSchemeItem] { - SecurityPresets.default.suspiciousURLSchemes + #if canImport(UIKit) + return SecurityPresets.default.suspiciousURLSchemes .filter { item in if let url = URL(string: item.scheme) { return UIApplication.shared.canOpenURL(url) } return false } + #else + return [] + #endif } // "cydia://" URL scheme has been removed. Turns out there is app in the official App Store diff --git a/Reveil/Storage/PinStorage.swift b/Reveil/Storage/PinStorage.swift index d7c5966..e6d5ffd 100644 --- a/Reveil/Storage/PinStorage.swift +++ b/Reveil/Storage/PinStorage.swift @@ -34,7 +34,7 @@ final class PinStorage: ObservableObject { @Published var pinnedEntryKeys: [EntryKey] func isPinned(forKey key: EntryKey) -> Bool { - return pinnedEntryKeys.contains(key) + pinnedEntryKeys.contains(key) } func reloadData() { diff --git a/Reveil/Storage/StandardUserDefaults.swift b/Reveil/Storage/StandardUserDefaults.swift index f5e3765..a94a65c 100644 --- a/Reveil/Storage/StandardUserDefaults.swift +++ b/Reveil/Storage/StandardUserDefaults.swift @@ -26,25 +26,15 @@ class StandardUserDefaults { ]) } - lazy var isLegacyUIEnabled: Bool = { - UserDefaults.standard.bool(forKey: gDefaultsKeyLegacyUI) - }() + lazy var isLegacyUIEnabled: Bool = UserDefaults.standard.bool(forKey: gDefaultsKeyLegacyUI) - lazy var isAnimatedTextEnabled: Bool = { - UserDefaults.standard.bool(forKey: gDefaultsKeyAnimatedText) - }() + lazy var isAnimatedTextEnabled: Bool = UserDefaults.standard.bool(forKey: gDefaultsKeyAnimatedText) - lazy var isAnimatedBackgroundEnabled: Bool = { - UserDefaults.standard.bool(forKey: gDefaultsKeyAnimatedBackground) - }() + lazy var isAnimatedBackgroundEnabled: Bool = UserDefaults.standard.bool(forKey: gDefaultsKeyAnimatedBackground) - lazy var isLowFrameRateEnabled: Bool = { - UserDefaults.standard.bool(forKey: gDefaultsKeyLowFrameRate) - }() + lazy var isLowFrameRateEnabled: Bool = UserDefaults.standard.bool(forKey: gDefaultsKeyLowFrameRate) - lazy var shouldResetLayouts: Bool = { - UserDefaults.standard.bool(forKey: gDefaultsKeyResetLayouts) - }() + lazy var shouldResetLayouts: Bool = UserDefaults.standard.bool(forKey: gDefaultsKeyResetLayouts) func didResetLayouts() { UserDefaults.standard.removeObject(forKey: gDefaultsKeyResetLayouts) diff --git a/Reveil/ViewModels/Modules/BatteryInformation.swift b/Reveil/ViewModels/Modules/BatteryInformation.swift index b86713a..62142de 100644 --- a/Reveil/ViewModels/Modules/BatteryInformation.swift +++ b/Reveil/ViewModels/Modules/BatteryInformation.swift @@ -86,7 +86,7 @@ final class BatteryInformation: Module { key: .BatteryUsed, name: style == .detailed ? NSLocalizedString("BATTERY_USED", comment: "Used") : NSLocalizedString("BATTERY_USED_FULL", comment: "Battery Used"), value: String(format: "%d%%", Int(round(batteryUsed * 100.0))), - color: Color(PlatformColor.secondarySystemFillAlias) + color: Color.secondarySystemFillAlias ) case .BatteryState: return BasicEntry( diff --git a/Reveil/ViewModels/Modules/CPUInformation.swift b/Reveil/ViewModels/Modules/CPUInformation.swift index 71386b8..585ecaf 100644 --- a/Reveil/ViewModels/Modules/CPUInformation.swift +++ b/Reveil/ViewModels/Modules/CPUInformation.swift @@ -178,7 +178,7 @@ final class CPUInformation: Module { key: .CPUUsageIdle, name: NSLocalizedString("USAGE_IDLE", comment: "Idle"), value: String(format: "%.2f%%", cpuUsage.idle * 100.0), - color: Color(PlatformColor.secondarySystemFillAlias) + color: Color.secondarySystemFillAlias ) case .CPUUsageLoad: return BasicEntry( diff --git a/Reveil/ViewModels/Modules/DeviceInformation.swift b/Reveil/ViewModels/Modules/DeviceInformation.swift index d295e62..e46a07c 100644 --- a/Reveil/ViewModels/Modules/DeviceInformation.swift +++ b/Reveil/ViewModels/Modules/DeviceInformation.swift @@ -6,7 +6,6 @@ // import CoreTelephony -import UIKit final class DeviceInformation: Module { static let shared = DeviceInformation() @@ -33,6 +32,7 @@ final class DeviceInformation: Module { return dictionary.first { $0["machine"] as? String == deviceName } }() + #if canImport(UIKit) private func currentRadioTechName() -> String? { guard let currentRadioTech = CTTelephonyNetworkInfo().serviceCurrentRadioAccessTechnology, let firstKey = currentRadioTech.keys.sorted().first, @@ -80,10 +80,21 @@ final class DeviceInformation: Module { return techName } + #endif private var displaySizeDescription: String { + #if canImport(UIKit) let mainScreen = UIScreen.main return "\(Int(mainScreen.fixedCoordinateSpace.bounds.height * mainScreen.scale))×\(Int(mainScreen.fixedCoordinateSpace.bounds.width * mainScreen.scale))" + #elseif canImport(AppKit) + guard let mainScreen = NSScreen.main else { + return NSLocalizedString("NOT_AVAILABLE", comment: "Not Available") + } + let scale = mainScreen.backingScaleFactor + return "\(Int(mainScreen.frame.height * scale))×\(Int(mainScreen.frame.width * scale))" + #else + return NSLocalizedString("NOT_AVAILABLE", comment: "Not Available") + #endif } lazy var basicEntries: [BasicEntry] = updatableEntryKeys.compactMap { basicEntry(key: $0) } @@ -133,6 +144,7 @@ final class DeviceInformation: Module { value: gModelDictionary?["bootrom"] as? String ?? BasicEntry.unknownValue ) case .RadioTech: + #if canImport(UIKit) if let techName = currentRadioTechName() { return BasicEntry( key: .RadioTech, @@ -140,6 +152,13 @@ final class DeviceInformation: Module { value: techName ) } + #else + return BasicEntry( + key: .RadioTech, + name: NSLocalizedString("RADIO_TECH", comment: "Radio Tech"), + value: NSLocalizedString("NOT_AVAILABLE", comment: "Not Available") + ) + #endif case .HostName: return BasicEntry( key: .HostName, diff --git a/Reveil/ViewModels/Modules/MemoryInformation.swift b/Reveil/ViewModels/Modules/MemoryInformation.swift index 0144a99..fd383c4 100644 --- a/Reveil/ViewModels/Modules/MemoryInformation.swift +++ b/Reveil/ViewModels/Modules/MemoryInformation.swift @@ -227,7 +227,7 @@ final class MemoryInformation: Module { key: .MemoryBytesFree, name: style == .dashboard ? NSLocalizedString("MEMORY_FREE_LONG", comment: "Free Memory") : NSLocalizedString("MEMORY_FREE", comment: "Free"), value: getMemoryDescription(memoryInfo, name: .free, style: style), - color: Color(PlatformColor.secondarySystemFillAlias) + color: Color.secondarySystemFillAlias ) case .MemoryPageReactivations: return BasicEntry( diff --git a/Reveil/ViewModels/Modules/NetworkUsage.swift b/Reveil/ViewModels/Modules/NetworkUsage.swift index bb723c3..0708d25 100644 --- a/Reveil/ViewModels/Modules/NetworkUsage.swift +++ b/Reveil/ViewModels/Modules/NetworkUsage.swift @@ -59,7 +59,7 @@ final class NetworkUsage: Module { key: key, name: pfx.description, value: netStats.entryValue(prefix: pfx, style: style), - color: pfx.color ?? Color(PlatformColor.secondarySystemFillAlias) + color: pfx.color ?? Color.secondarySystemFillAlias ) } default: diff --git a/Reveil/ViewModels/Security.swift b/Reveil/ViewModels/Security.swift index 10b34b7..ce5b31a 100644 --- a/Reveil/ViewModels/Security.swift +++ b/Reveil/ViewModels/Security.swift @@ -60,8 +60,9 @@ final class Security: ObservableObject, StaticEntryProvider, Explainable { isLoading = true #if os(iOS) - _ = suspiciousURLSchemes + _ = suspiciousURLSchemes #endif + DispatchQueue.global(qos: .utility).async { let performedCases = SecurityCheck.allCases.map { $0.perform() } let groupedCases = Dictionary(grouping: performedCases) { $0.status } diff --git a/Reveil/ViewModels/SecurityCheck.swift b/Reveil/ViewModels/SecurityCheck.swift index 74d0836..ffaed6e 100644 --- a/Reveil/ViewModels/SecurityCheck.swift +++ b/Reveil/ViewModels/SecurityCheck.swift @@ -225,6 +225,7 @@ enum SecurityCheck: CaseIterable, Codable, Equatable, Hashable, RawRepresentable } } + #if os(iOS) static let allCases: [SecurityCheck] = [ .noSuspiciousFile(.unchanged), .noSuspiciousLibrary(.unchanged), @@ -261,6 +262,29 @@ enum SecurityCheck: CaseIterable, Codable, Equatable, Hashable, RawRepresentable .noExceptionPort(.unchanged), .noSignalHandler(.unchanged), ] + #endif + + #if os(macOS) + static let allCases: [SecurityCheck] = [ + .noSuspiciousLibrary(.unchanged), + .noSuspiciousSymbolicLink(.unchanged), + .noSuspiciousObjCClass(.unchanged), + .noSuspiciousEnvironmentVariables(.unchanged), + .notInSimulator(.unchanged), + .noDebuggerAttached(.unchanged), + .noUnsignedExecutablePage(.unchanged), + .unavailableSeatbeltSpecialPort(.unchanged), + .noPSelectFlag(.unchanged), + .unprivilegedHostPort(.unchanged), + .enabledLibraryValidation(.unchanged), + .stockDynamicLinker(.unchanged), + .unmodifiedExecutionState(.unchanged), + .untouchedProcessTaskPort(.unchanged), + .notInTrustCache(.unchanged), + .noExceptionPort(.unchanged), + .noSignalHandler(.unchanged), + ] + #endif var isFailed: Bool { switch self { @@ -683,7 +707,7 @@ enum SecurityCheck: CaseIterable, Codable, Equatable, Hashable, RawRepresentable private func csOpsStatusColor(_ status: CsOpsStatus) -> Color { status.isPresented ? (status.isInsecure ? Color("SecurityLeaks") : Color.accentColor) - : (status.isRequired ? Color("SecurityLeaks") : Color(PlatformColor.secondarySystemFillAlias)) + : (status.isRequired ? Color("SecurityLeaks") : Color.secondarySystemFillAlias) } func entry() -> BasicEntry { @@ -783,7 +807,7 @@ enum SecurityCheck: CaseIterable, Codable, Equatable, Hashable, RawRepresentable return BasicEntry( key: .Custom(name: rawValue), name: description, - color: isPassed ? Color.accentColor : (isFailed ? Color("SecurityLeaks") : Color(PlatformColor.secondarySystemFillAlias)), + color: isPassed ? Color.accentColor : (isFailed ? Color("SecurityLeaks") : Color.secondarySystemFillAlias), children: entryChildren ) } diff --git a/Reveil/Views/AnimatedText.swift b/Reveil/Views/AnimatedText.swift index c8a46fa..d3ae732 100644 --- a/Reveil/Views/AnimatedText.swift +++ b/Reveil/Views/AnimatedText.swift @@ -20,8 +20,8 @@ struct AnimatedText: View { var isLegacyUIEnabled: Bool = StandardUserDefaults.shared.isLegacyUIEnabled var body: some View { - if !isLegacyUIEnabled && isAnimatedTextEnabled { - if #available(iOS 17.0, *) { + if !isLegacyUIEnabled, isAnimatedTextEnabled { + if #available(iOS 17.0, macOS 13.0, *) { Text(text) .contentTransition(.numericText()) .animation(.spring(duration: 0.2), value: text) diff --git a/Reveil/Views/ColorfulBackground.swift b/Reveil/Views/ColorfulBackground.swift index a408289..5339543 100644 --- a/Reveil/Views/ColorfulBackground.swift +++ b/Reveil/Views/ColorfulBackground.swift @@ -8,7 +8,6 @@ import ColorfulX import SwiftUI - struct ColorfulBackground: View { @State var isPaused: Bool = false @Environment(\.colorScheme) var colorScheme @@ -41,10 +40,10 @@ struct ColorfulBackground: View { var body: some View { Group { if !isLegacyUIEnabled { - self.colorfulView + colorfulView } } - .background(Color(PlatformColor.systemBackground)) + .background(Color.systemBackground) .ignoresSafeArea() .onAppear { isPaused = false diff --git a/Reveil/Views/Dashboard/ActivityWidget.swift b/Reveil/Views/Dashboard/ActivityWidget.swift index fb073f2..40eeb5f 100644 --- a/Reveil/Views/Dashboard/ActivityWidget.swift +++ b/Reveil/Views/Dashboard/ActivityWidget.swift @@ -31,12 +31,12 @@ struct ActivityWidget: View { Text(entry.name.uppercased()) .font(Font.system(.body)) .fontWeight(.bold) - .foregroundColor(Color(PlatformColor.labelAlias)) + .foregroundColor(Color.labelAlias) .lineLimit(1) Spacer() Image(systemName: "chevron.right") .font(Font.system(.body).weight(.regular)) - .foregroundColor(Color(PlatformColor.tertiaryLabelAlias)) + .foregroundColor(Color.tertiaryLabelAlias) } Spacer(minLength: 2) diff --git a/Reveil/Views/Dashboard/CheckmarkWidget.swift b/Reveil/Views/Dashboard/CheckmarkWidget.swift index 4074cfc..63b7ec2 100644 --- a/Reveil/Views/Dashboard/CheckmarkWidget.swift +++ b/Reveil/Views/Dashboard/CheckmarkWidget.swift @@ -53,7 +53,7 @@ struct CheckmarkWidget: View { var backgroundColor: Color { if isInsecure { return Color("SecurityLeaks") } - return Color(PlatformColor.secondarySystemBackgroundAlias) + return Color.secondarySystemBackgroundAlias } var animatedBackgroundColors: [Color] { @@ -104,28 +104,31 @@ struct CheckmarkWidget: View { .foregroundColor(backgroundColor) .opacity(isInsecure ? 0.75 : 0.25) } else { - self.colorfulBackground + colorfulBackground .opacity(0.75) .clipShape(RoundedRectangle(cornerRadius: 4)) } } .overlay { - if usesLegacyStyle && !isInsecure { + if usesLegacyStyle, !isInsecure { RoundedRectangle(cornerRadius: 4) - .stroke(Color(PlatformColor.separatorAlias), lineWidth: 1) + .stroke(Color.separatorAlias, lineWidth: 1) .opacity(isInsecure ? 0 : 1) } } .onChange(of: isLoading) { _ in if isLoading { openDetail = false } } - .background( + .background { NavigationLink( "", destination: SecurityView().environmentObject(HighlightedEntryKey()), isActive: $openDetail ) - ) + #if os(macOS) + .buttonStyle(.plain) + #endif + } .contentShape(Rectangle()) .onTapGesture { if isLoading { return } diff --git a/Reveil/Views/Dashboard/FieldWidget.swift b/Reveil/Views/Dashboard/FieldWidget.swift index 8236198..cab0a0c 100644 --- a/Reveil/Views/Dashboard/FieldWidget.swift +++ b/Reveil/Views/Dashboard/FieldWidget.swift @@ -16,18 +16,18 @@ struct FieldWidget: View { Text(entry.name.uppercased()) .font(Font.system(.body)) .fontWeight(.bold) - .foregroundColor(Color(PlatformColor.labelAlias)) + .foregroundColor(Color.labelAlias) .lineLimit(1) Spacer() Image(systemName: "chevron.right") .font(Font.system(.body).weight(.regular)) - .foregroundColor(Color(PlatformColor.tertiaryLabelAlias)) + .foregroundColor(Color.tertiaryLabelAlias) } HStack { Text(entry.value) .font(Font.system(.body).weight(.regular).monospacedDigit()) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .multilineTextAlignment(.leading) .lineLimit(3) Spacer() diff --git a/Reveil/Views/Dashboard/TrafficWidget.swift b/Reveil/Views/Dashboard/TrafficWidget.swift index 315e51d..d8f19fc 100644 --- a/Reveil/Views/Dashboard/TrafficWidget.swift +++ b/Reveil/Views/Dashboard/TrafficWidget.swift @@ -117,12 +117,12 @@ struct TrafficWidget: View { Text(label.uppercased()) .font(Font.system(.body)) .fontWeight(.bold) - .foregroundColor(Color(PlatformColor.labelAlias)) + .foregroundColor(Color.labelAlias) .lineLimit(1) Spacer() Image(systemName: "chevron.right") .font(Font.system(.body).weight(.regular)) - .foregroundColor(Color(PlatformColor.tertiaryLabelAlias)) + .foregroundColor(Color.tertiaryLabelAlias) } GeometryReader { metrics in @@ -130,11 +130,11 @@ struct TrafficWidget: View { HStack { Image(systemName: "arrow.down.backward") .font(Font.system(.body).weight(.regular)) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) Text(receivedDescription) .font(Font.system(.body).weight(.regular).monospacedDigit()) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .lineLimit(1) } @@ -162,11 +162,11 @@ struct TrafficWidget: View { HStack { Image(systemName: "arrow.up.forward") .font(Font.system(.body).weight(.regular)) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) Text(sentDescription) .font(Font.system(.body).weight(.regular).monospacedDigit()) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .lineLimit(1) } diff --git a/Reveil/Views/Dashboard/UsageWidget.swift b/Reveil/Views/Dashboard/UsageWidget.swift index 9bf8b55..7b25f62 100644 --- a/Reveil/Views/Dashboard/UsageWidget.swift +++ b/Reveil/Views/Dashboard/UsageWidget.swift @@ -18,12 +18,12 @@ struct UsageWidget: View { Text(entry.name.uppercased()) .font(Font.system(.body)) .fontWeight(.bold) - .foregroundColor(Color(PlatformColor.labelAlias)) + .foregroundColor(Color.labelAlias) .lineLimit(1) Spacer() Image(systemName: "chevron.right") .font(Font.system(.body).weight(.regular)) - .foregroundColor(Color(PlatformColor.tertiaryLabelAlias)) + .foregroundColor(Color.tertiaryLabelAlias) } Spacer(minLength: 2) @@ -39,7 +39,7 @@ struct UsageWidget: View { if let lastDescription = entry.lastDescription { Text(lastDescription) .font(Font.system(.body).weight(.regular).monospacedDigit()) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .lineLimit(1) } } @@ -49,7 +49,7 @@ struct UsageWidget: View { GeometryReader { metrics in ZStack(alignment: .leading) { - Color(PlatformColor.secondarySystemFillAlias) + Color.secondarySystemFillAlias Color.accentColor .frame(width: metrics.size.width * (entry.firstRatio ?? 0.0)) diff --git a/Reveil/Views/Details/FieldCell.swift b/Reveil/Views/Details/FieldCell.swift index e877a76..53ebdbd 100644 --- a/Reveil/Views/Details/FieldCell.swift +++ b/Reveil/Views/Details/FieldCell.swift @@ -44,17 +44,23 @@ private struct FieldCell_Internal: View { } label: { Label(NSLocalizedString("UNPIN", comment: "Unpin"), systemImage: "pin") } + #if os(macOS) + .buttonStyle(.plain) + #endif } else { Button { pin = Pin(true) } label: { Label(NSLocalizedString("PIN", comment: "Pin"), systemImage: "pin.fill") } + #if os(macOS) + .buttonStyle(.plain) + #endif } } label: { Image(systemName: pin.isPinned ? "pin.fill" : "pin") .font(Font.system(.footnote)) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .rotationEffect(.degrees(45)) } primaryAction: { pin = Pin(negate: pin) @@ -68,7 +74,7 @@ private struct FieldCell_Internal: View { Text(description) .font(.system(.body).monospacedDigit()) - .foregroundColor(Color(PlatformColor.secondaryLabelAlias)) + .foregroundColor(Color.secondaryLabelAlias) .multilineTextAlignment(.trailing) } } diff --git a/Reveil/Views/Details/UsageCell.swift b/Reveil/Views/Details/UsageCell.swift index a68b2ff..48da52e 100644 --- a/Reveil/Views/Details/UsageCell.swift +++ b/Reveil/Views/Details/UsageCell.swift @@ -58,7 +58,7 @@ struct UsageCell: View { var body: some View { GeometryReader { metrics in ZStack(alignment: .leading) { - Color(PlatformColor.secondarySystemFillAlias) + Color.secondarySystemFillAlias HStack(spacing: 0) { ForEach(ratioItem, id: \.id) { item in diff --git a/Reveil/Views/PinButton.swift b/Reveil/Views/PinButton.swift index b5e7bf9..29f34c7 100644 --- a/Reveil/Views/PinButton.swift +++ b/Reveil/Views/PinButton.swift @@ -16,9 +16,12 @@ struct PinButton: View { } label: { Image(systemName: pin.isPinned ? "pin.fill" : "pin") .font(Font.system(.body)) - .foregroundColor(Color(PlatformColor.labelAlias)) + .foregroundColor(Color.labelAlias) .rotationEffect(.degrees(45)) } + #if os(macOS) + .buttonStyle(.plain) + #endif } } diff --git a/Reveil/en.lproj/Localizable.strings b/Reveil/en.lproj/Localizable.strings index 7d31c4b..f2f9b37 100644 --- a/Reveil/en.lproj/Localizable.strings +++ b/Reveil/en.lproj/Localizable.strings @@ -712,6 +712,9 @@ /* Nodes */ "NODES" = "Nodes"; +/* Not Available */ +"NOT_AVAILABLE" = "Not Available"; + /* Run on a hardware device */ "NOT_IN_SIMULATOR" = "Run on a hardware device"; diff --git a/Reveil/zh-Hans.lproj/Localizable.strings b/Reveil/zh-Hans.lproj/Localizable.strings index 6b5fbc2..6d18d91 100644 --- a/Reveil/zh-Hans.lproj/Localizable.strings +++ b/Reveil/zh-Hans.lproj/Localizable.strings @@ -712,6 +712,9 @@ /* Nodes */ "NODES" = "节点"; +/* Not Available */ +"NOT_AVAILABLE" = "不可用"; + /* Run on a hardware device */ "NOT_IN_SIMULATOR" = "运行在硬件设备上"; diff --git a/library-stub/library_stub.m b/library-stub/library_stub.m index b456780..c72e813 100644 --- a/library-stub/library_stub.m +++ b/library-stub/library_stub.m @@ -20,7 +20,7 @@ int evaluateSignature(NSURL* fileURL, NSData **cdHashOut, BOOL *isAdhocSignedOut FILE *machoFile = fopen(fileURL.fileSystemRepresentation, "rb"); if (!machoFile) return 3; - BOOL isMacho = NO; + bool isMacho = NO; machoGetInfo(machoFile, &isMacho, NULL); if (!isMacho) { @@ -62,8 +62,8 @@ BOOL isCdHashInTrustCache(NSData *cdHash) CFMutableDictionaryRef amfiServiceDict = IOServiceMatching("AppleMobileFileIntegrity"); if (amfiServiceDict) { - io_connect_t connect; - if (@available(iOS 15.0, *)) { + io_connect_t connect = 0; + if (@available(iOS 15.0, macOS 12.0, *)) { io_service_t amfiService = IOServiceGetMatchingService(kIOMainPortDefault, amfiServiceDict); kr = IOServiceOpen(amfiService, mach_task_self(), 0, &connect); } else { @@ -71,7 +71,7 @@ BOOL isCdHashInTrustCache(NSData *cdHash) io_service_t amfiService = IOServiceGetMatchingService(0 /* kIOMasterPortDefault */, amfiServiceDict); kr = IOServiceOpen(amfiService, mach_task_self(), 0, &connect); } - if (kr != KERN_SUCCESS) + if (kr != KERN_SUCCESS || connect == 0) { NSLog(@"Failed to open amfi service %d %s", kr, mach_error_string(kr)); return NO; diff --git a/library-stub/macho.m b/library-stub/macho.m index 1e9ac23..49132bc 100644 --- a/library-stub/macho.m +++ b/library-stub/macho.m @@ -209,7 +209,7 @@ void _machoEnumerateDependencies(FILE *machoFile, uint32_t archOffset, NSString NSLog(@"[_machoEnumerateDependencies] Found depdendency %s, recursively enumerating over it...", resolvedPath.UTF8String); FILE *nextFile = fopen(resolvedPath.fileSystemRepresentation, "rb"); if (nextFile) { - BOOL nextFileIsMacho = NO; + bool nextFileIsMacho = NO; machoGetInfo(nextFile, &nextFileIsMacho, NULL); if (nextFileIsMacho) { int64_t nextBestArchCandidate = machoFindBestArch(nextFile);