diff --git a/Data/comparison-bezelkit.jpg b/.github/data/comparison-bezelkit.jpg similarity index 100% rename from Data/comparison-bezelkit.jpg rename to .github/data/comparison-bezelkit.jpg diff --git a/Data/comparison-static.jpg b/.github/data/comparison-static.jpg similarity index 100% rename from Data/comparison-static.jpg rename to .github/data/comparison-static.jpg diff --git a/Data/kit-icon.png b/.github/data/kit-icon.png similarity index 100% rename from Data/kit-icon.png rename to .github/data/kit-icon.png diff --git a/Data/ratio.jpg b/.github/data/ratio.jpg similarity index 100% rename from Data/ratio.jpg rename to .github/data/ratio.jpg diff --git a/Data/simulator.jpg b/.github/data/simulator.jpg similarity index 100% rename from Data/simulator.jpg rename to .github/data/simulator.jpg diff --git a/Data/zoomed-bezelkit.jpg b/.github/data/zoomed-bezelkit.jpg similarity index 100% rename from Data/zoomed-bezelkit.jpg rename to .github/data/zoomed-bezelkit.jpg diff --git a/Data/zoomed-static.jpg b/.github/data/zoomed-static.jpg similarity index 100% rename from Data/zoomed-static.jpg rename to .github/data/zoomed-static.jpg diff --git a/.gitignore b/.gitignore index 6d98236..6d2a51e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ .DS_Store .swiftpm -.swiftpm/* .vscode .markdownlint.json .build -logs diff --git a/CHANGELOG.md b/CHANGELOG.md index e84f7e3..4cc7e66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## 2.0.1 + +### What's Changed + +- 2023-10-08 - removed the "Generator" from repo, and moved it into its own repo [#28](https://github.com/markbattistella/BezelKit/issues/28) + ## 2.0.0 ### What's Changed diff --git a/Generator/FetchBezel/FetchBezel.xcodeproj/project.pbxproj b/Generator/FetchBezel/FetchBezel.xcodeproj/project.pbxproj deleted file mode 100644 index daaf485..0000000 --- a/Generator/FetchBezel/FetchBezel.xcodeproj/project.pbxproj +++ /dev/null @@ -1,361 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 56; - objects = { - -/* Begin PBXBuildFile section */ - 2C47D0192A8B3665008F0320 /* MainApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C47D0182A8B3665008F0320 /* MainApp.swift */; }; - 2C47D01D2A8B3667008F0320 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2C47D01C2A8B3667008F0320 /* Assets.xcassets */; }; - 2C47D0202A8B3667008F0320 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2C47D01F2A8B3667008F0320 /* Preview Assets.xcassets */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 2C47D0152A8B3664008F0320 /* FetchBezel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FetchBezel.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 2C47D0182A8B3665008F0320 /* MainApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainApp.swift; sourceTree = ""; }; - 2C47D01C2A8B3667008F0320 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 2C47D01F2A8B3667008F0320 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2C47D0122A8B3664008F0320 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 2C47D00C2A8B3664008F0320 = { - isa = PBXGroup; - children = ( - 2C47D0172A8B3664008F0320 /* FetchBezel */, - 2C47D0162A8B3664008F0320 /* Products */, - ); - sourceTree = ""; - }; - 2C47D0162A8B3664008F0320 /* Products */ = { - isa = PBXGroup; - children = ( - 2C47D0152A8B3664008F0320 /* FetchBezel.app */, - ); - name = Products; - sourceTree = ""; - }; - 2C47D0172A8B3664008F0320 /* FetchBezel */ = { - isa = PBXGroup; - children = ( - 2C47D0182A8B3665008F0320 /* MainApp.swift */, - 2C47D01C2A8B3667008F0320 /* Assets.xcassets */, - 2C47D01E2A8B3667008F0320 /* Preview Content */, - ); - path = FetchBezel; - sourceTree = ""; - }; - 2C47D01E2A8B3667008F0320 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 2C47D01F2A8B3667008F0320 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 2C47D0142A8B3664008F0320 /* FetchBezel */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2C47D0232A8B3667008F0320 /* Build configuration list for PBXNativeTarget "FetchBezel" */; - buildPhases = ( - 2C47D0112A8B3664008F0320 /* Sources */, - 2C47D0122A8B3664008F0320 /* Frameworks */, - 2C47D0132A8B3664008F0320 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = FetchBezel; - productName = test; - productReference = 2C47D0152A8B3664008F0320 /* FetchBezel.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 2C47D00D2A8B3664008F0320 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1500; - LastUpgradeCheck = 1500; - TargetAttributes = { - 2C47D0142A8B3664008F0320 = { - CreatedOnToolsVersion = 15.0; - }; - }; - }; - buildConfigurationList = 2C47D0102A8B3664008F0320 /* Build configuration list for PBXProject "FetchBezel" */; - compatibilityVersion = "Xcode 14.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 2C47D00C2A8B3664008F0320; - productRefGroup = 2C47D0162A8B3664008F0320 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 2C47D0142A8B3664008F0320 /* FetchBezel */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 2C47D0132A8B3664008F0320 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2C47D0202A8B3667008F0320 /* Preview Assets.xcassets in Resources */, - 2C47D01D2A8B3667008F0320 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 2C47D0112A8B3664008F0320 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2C47D0192A8B3665008F0320 /* MainApp.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 2C47D0212A8B3667008F0320 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 2C47D0222A8B3667008F0320 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 2C47D0242A8B3667008F0320 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"FetchBezel/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_CFBundleDisplayName = "Fetch Bezel Size"; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UIStatusBarHidden = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.mb.FetchBezel; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 2C47D0252A8B3667008F0320 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"FetchBezel/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_CFBundleDisplayName = "Fetch Bezel Size"; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UIStatusBarHidden = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.mb.FetchBezel; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 2C47D0102A8B3664008F0320 /* Build configuration list for PBXProject "FetchBezel" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2C47D0212A8B3667008F0320 /* Debug */, - 2C47D0222A8B3667008F0320 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2C47D0232A8B3667008F0320 /* Build configuration list for PBXNativeTarget "FetchBezel" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2C47D0242A8B3667008F0320 /* Debug */, - 2C47D0252A8B3667008F0320 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 2C47D00D2A8B3664008F0320 /* Project object */; -} diff --git a/Generator/FetchBezel/FetchBezel.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Generator/FetchBezel/FetchBezel.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 6498793..0000000 --- a/Generator/FetchBezel/FetchBezel.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Generator/FetchBezel/FetchBezel.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Generator/FetchBezel/FetchBezel.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/Generator/FetchBezel/FetchBezel.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Generator/FetchBezel/FetchBezel.xcodeproj/xcshareddata/xcschemes/FetchBezel.xcscheme b/Generator/FetchBezel/FetchBezel.xcodeproj/xcshareddata/xcschemes/FetchBezel.xcscheme deleted file mode 100644 index 0c99ae6..0000000 --- a/Generator/FetchBezel/FetchBezel.xcodeproj/xcshareddata/xcschemes/FetchBezel.xcscheme +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Generator/FetchBezel/FetchBezel/Assets.xcassets/AccentColor.colorset/Contents.json b/Generator/FetchBezel/FetchBezel/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index eb87897..0000000 --- a/Generator/FetchBezel/FetchBezel/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Generator/FetchBezel/FetchBezel/Assets.xcassets/AppIcon.appiconset/Contents.json b/Generator/FetchBezel/FetchBezel/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 13613e3..0000000 --- a/Generator/FetchBezel/FetchBezel/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Generator/FetchBezel/FetchBezel/Assets.xcassets/Contents.json b/Generator/FetchBezel/FetchBezel/Assets.xcassets/Contents.json deleted file mode 100644 index 73c0059..0000000 --- a/Generator/FetchBezel/FetchBezel/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Generator/FetchBezel/FetchBezel/MainApp.swift b/Generator/FetchBezel/FetchBezel/MainApp.swift deleted file mode 100644 index d69a727..0000000 --- a/Generator/FetchBezel/FetchBezel/MainApp.swift +++ /dev/null @@ -1,151 +0,0 @@ -// -// FetchBezel for BezelKit -// Created by Mark Battistella -// - -import SwiftUI - -@main -struct MainApp: App { - var body: some Scene { - WindowGroup { - MainView().onAppear { logMetrics() } - } - } - - /// Logs device-specific metrics such as the model name and screen radius to a text file. - /// - /// This function gathers device metrics including the device model name and the screen's corner radius, - /// and saves this information in a JSON-formatted string to a file named `output.txt` in the app's document directory. - /// - /// If the function encounters any errors during the JSON serialization or file writing operations, it logs those errors - /// to the console and terminates the operation. - private func logMetrics() { - - // Retrieve the device model name and screen corner radius. - let deviceModelName = UIDevice.current.modelName - let deviceRadius = UIScreen.main.radius - - // Create a dictionary to hold the device metrics. - let metrics: [String: Any] = [ - "identifiers": deviceModelName, - "bezel": deviceRadius - ] - - // Serialize the metrics dictionary to JSON data. - let jsonData: Data - do { - jsonData = try JSONSerialization.data(withJSONObject: metrics, options: .prettyPrinted) - } catch { - print("Failed to create JSON: \(error)") - return - } - - // Convert the JSON data to a string. - let jsonString = String(data: jsonData, encoding: .utf8)! - - // Create the path where the log file will be saved. - let path = FileManager - .default - .urls(for: .documentDirectory, in: .userDomainMask)[0] - .appendingPathComponent("output.json") - - // Attempt to write the JSON string to the file at the specified path. - do { - try jsonString.write(to: path, atomically: true, encoding: .utf8) - } catch { - print("Failed to write logs: \(error)") - } - } -} - -/// `MainView` provides a detailed view of the device's properties. -/// -/// This view presents a list of device-specific details such as the device's name, -/// model name, system version, and more. It utilizes the `TableRowView` to structure -/// and present each pair of title and value. -fileprivate struct MainView: View { - var body: some View { - VStack(alignment: .leading) { - Text("FetchBezel") - .font(.largeTitle) - .fontWeight(.heavy) - .padding(.bottom) - TableRowView("Name", value: UIDevice.current.name) - TableRowView("Model Name", value: UIDevice.current.modelName) - TableRowView("Model", value: UIDevice.current.model) - TableRowView("System Version", value: UIDevice.current.systemVersion) - TableRowView("System name", value: UIDevice.current.systemName) - TableRowView("Localized Model", value: UIDevice.current.localizedModel) - TableRowView("Debug Description", value: UIDevice.current.debugDescription) - TableRowView("Description", value: UIDevice.current.description) - } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) - .padding() - } - - /// A helper view function that creates a table row with a title and its associated value. - /// - /// - Parameters: - /// - title: The title or label for the row. - /// - value: The value associated with the title. - /// - Returns: A `View` representing the table row. - private func TableRowView(_ title: String, value: String) -> some View { - VStack(alignment: .leading) { - Text(title) - .fontWeight(.bold) - Text(value) - } - .frame(maxWidth: .infinity, alignment: .leading) - .padding(.bottom) - } -} - -/// An extension to `UIScreen` for retrieving the corner radius of the device's display. -fileprivate extension UIScreen { - - /// The radius of the corners of the device's display. - /// This value is accessed through Key-Value Coding, using a private key. - /// - /// - Returns: A `CGFloat` value representing the corner radius. - /// If the corner radius cannot be accessed, this property returns `0`. - var radius: CGFloat { - let radiusKey = "_displayCornerRadius" - guard let corner = self.value(forKey: radiusKey) as? CGFloat else { - return 0 - } - return corner - } -} - -/// An extension to `UIDevice` for retrieving the model name identifier of the device. -fileprivate extension UIDevice { - - /// The model name identifier of the device. - /// - /// For real devices, this identifier is obtained by calling `uname()` function. - /// For simulators, the identifier is read from the environment variable `SIMULATOR_MODEL_IDENTIFIER`. - /// - /// - Returns: A `String` representing the model name identifier of the device. - var modelName: String { - - #if targetEnvironment(simulator) - - // In the case of a simulator, read the identifier from environment variables - let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"]! - - #else - - // In the case of a real device, get the identifier using `uname()` - var systemInfo = utsname() - uname(&systemInfo) - let machineMirror = Mirror(reflecting: systemInfo.machine) - let identifier = machineMirror.children.reduce("") { identifier, element in - guard let value = element.value as? Int8, value != 0 else { return identifier } - return identifier + String(UnicodeScalar(UInt8(value))) - } - #endif - - return identifier - } -} diff --git a/Generator/FetchBezel/FetchBezel/Preview Content/Preview Assets.xcassets/Contents.json b/Generator/FetchBezel/FetchBezel/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 73c0059..0000000 --- a/Generator/FetchBezel/FetchBezel/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Generator/apple-device-database.json b/Generator/apple-device-database.json deleted file mode 100644 index 5c4ba29..0000000 --- a/Generator/apple-device-database.json +++ /dev/null @@ -1,489 +0,0 @@ -{ - "_metadata": { - "Author": "Mark Battistella", - "Project": "BezelKit - BezelGenerator", - "Website": "https://markbattistella.com" - }, - "devices": { - "iPad": { - "iPad1,1": { - "bezel": 0, - "name": "iPad" - }, - "iPad2,1": { - "bezel": 0, - "name": "iPad 2" - }, - "iPad2,2": { - "bezel": 0, - "name": "iPad 2" - }, - "iPad2,3": { - "bezel": 0, - "name": "iPad 2" - }, - "iPad2,4": { - "bezel": 0, - "name": "iPad 2" - }, - "iPad2,5": { - "bezel": 0, - "name": "iPad mini" - }, - "iPad2,6": { - "bezel": 0, - "name": "iPad mini" - }, - "iPad2,7": { - "bezel": 0, - "name": "iPad mini" - }, - "iPad3,1": { - "bezel": 0, - "name": "iPad (3rd generation)" - }, - "iPad3,2": { - "bezel": 0, - "name": "iPad (3rd generation)" - }, - "iPad3,3": { - "bezel": 0, - "name": "iPad (3rd generation)" - }, - "iPad3,4": { - "bezel": 0, - "name": "iPad (4th generation)" - }, - "iPad3,5": { - "bezel": 0, - "name": "iPad (4th generation)" - }, - "iPad3,6": { - "bezel": 0, - "name": "iPad (4th generation)" - }, - "iPad4,1": { - "bezel": 0, - "name": "iPad Air" - }, - "iPad4,2": { - "bezel": 0, - "name": "iPad Air" - }, - "iPad4,3": { - "bezel": 0, - "name": "iPad Air" - }, - "iPad4,4": { - "bezel": 0, - "name": "iPad mini 2" - }, - "iPad4,5": { - "bezel": 0, - "name": "iPad mini 2" - }, - "iPad4,6": { - "bezel": 0, - "name": "iPad mini 2" - }, - "iPad4,7": { - "bezel": 0, - "name": "iPad mini 3" - }, - "iPad4,8": { - "bezel": 0, - "name": "iPad mini 3" - }, - "iPad4,9": { - "bezel": 0, - "name": "iPad mini 3" - }, - "iPad5,1": { - "bezel": 0, - "name": "iPad mini 4" - }, - "iPad5,2": { - "bezel": 0, - "name": "iPad mini 4" - }, - "iPad5,3": { - "bezel": 0, - "name": "iPad Air 2" - }, - "iPad5,4": { - "bezel": 0, - "name": "iPad Air 2" - }, - "iPad6,11": { - "bezel": 0, - "name": "iPad (5th generation)" - }, - "iPad6,12": { - "bezel": 0, - "name": "iPad (5th generation)" - }, - "iPad6,3": { - "bezel": 0, - "name": "iPad Pro (9.7-inch)" - }, - "iPad6,4": { - "bezel": 0, - "name": "iPad Pro (9.7-inch)" - }, - "iPad7,1": { - "bezel": 0, - "name": "iPad Pro (12.9-inch) (2nd generation)" - }, - "iPad7,11": { - "bezel": 0, - "name": "iPad (7th generation)" - }, - "iPad7,12": { - "bezel": 0, - "name": "iPad (7th generation)" - }, - "iPad7,2": { - "bezel": 0, - "name": "iPad Pro (12.9-inch) (2nd generation)" - }, - "iPad7,3": { - "bezel": 0, - "name": "iPad Pro (10.5-inch)" - }, - "iPad7,4": { - "bezel": 0, - "name": "iPad Pro (10.5-inch)" - }, - "iPad7,5": { - "bezel": 0, - "name": "iPad (6th generation)" - }, - "iPad7,6": { - "bezel": 0, - "name": "iPad (6th generation)" - }, - "iPad11,1": { - "bezel": 0, - "name": "iPad mini (5th generation)" - }, - "iPad11,2": { - "bezel": 0, - "name": "iPad mini (5th generation)" - }, - "iPad11,3": { - "bezel": 0, - "name": "iPad Air (3rd generation)" - }, - "iPad11,4": { - "bezel": 0, - "name": "iPad Air (3rd generation)" - }, - "iPad11,6": { - "bezel": 0, - "name": "iPad (8th generation)" - }, - "iPad11,7": { - "bezel": 0, - "name": "iPad (8th generation)" - }, - "iPad12,1": { - "bezel": 0, - "name": "iPad (9th generation)" - }, - "iPad12,2": { - "bezel": 0, - "name": "iPad (9th generation)" - }, - "iPad13,1": { - "bezel": 18, - "name": "iPad Air (4th generation)" - }, - "iPad13,10": { - "bezel": 18, - "name": "iPad Pro (12.9-inch) (5th generation)" - }, - "iPad13,11": { - "bezel": 18, - "name": "iPad Pro (12.9-inch) (5th generation)" - }, - "iPad13,12": { - "bezel": 18, - "name": "iPad mini (6th generation)" - }, - "iPad13,2": { - "bezel": 18, - "name": "iPad Air (4th generation)" - }, - "iPad13,4": { - "bezel": 18, - "name": "iPad Pro (11-inch) (3rd generation)" - }, - "iPad13,5": { - "bezel": 18, - "name": "iPad Pro (11-inch) (3rd generation)" - }, - "iPad13,6": { - "bezel": 18, - "name": "iPad Pro (11-inch) (3rd generation)" - }, - "iPad13,7": { - "bezel": 18, - "name": "iPad Pro (11-inch) (3rd generation)" - }, - "iPad13,8": { - "bezel": 18, - "name": "iPad Pro (12.9-inch) (5th generation)" - }, - "iPad13,9": { - "bezel": 18, - "name": "iPad Pro (12.9-inch) (5th generation)" - } - }, - "iPhone": { - "iPhone1,1": { - "bezel": 0, - "name": "iPhone" - }, - "iPhone1,2": { - "bezel": 0, - "name": "iPhone 3G" - }, - "iPhone2,1": { - "bezel": 0, - "name": "iPhone 3GS" - }, - "iPhone3,1": { - "bezel": 0, - "name": "iPhone 4" - }, - "iPhone3,2": { - "bezel": 0, - "name": "iPhone 4" - }, - "iPhone3,3": { - "bezel": 0, - "name": "iPhone 4" - }, - "iPhone4,1": { - "bezel": 0, - "name": "iPhone 4S" - }, - "iPhone5,1": { - "bezel": 0, - "name": "iPhone 5" - }, - "iPhone5,2": { - "bezel": 0, - "name": "iPhone 5" - }, - "iPhone5,3": { - "bezel": 0, - "name": "iPhone 5c" - }, - "iPhone5,4": { - "bezel": 0, - "name": "iPhone 5c" - }, - "iPhone6,1": { - "bezel": 0, - "name": "iPhone 5s" - }, - "iPhone6,2": { - "bezel": 0, - "name": "iPhone 5s" - }, - "iPhone7,1": { - "bezel": 0, - "name": "iPhone 6 Plus" - }, - "iPhone7,2": { - "bezel": 0, - "name": "iPhone 6" - }, - "iPhone8,1": { - "bezel": 0, - "name": "iPhone 6s" - }, - "iPhone8,2": { - "bezel": 0, - "name": "iPhone 6s Plus" - }, - "iPhone8,4": { - "bezel": 0, - "name": "iPhone SE (1st generation)" - }, - "iPhone9,1": { - "bezel": 0, - "name": "iPhone 7" - }, - "iPhone9,2": { - "bezel": 0, - "name": "iPhone 7 Plus" - }, - "iPhone9,3": { - "bezel": 0, - "name": "iPhone 7" - }, - "iPhone9,4": { - "bezel": 0, - "name": "iPhone 7 Plus" - }, - "iPhone10,1": { - "bezel": 0, - "name": "iPhone 8" - }, - "iPhone10,2": { - "bezel": 0, - "name": "iPhone 8 Plus" - }, - "iPhone10,3": { - "bezel": 39, - "name": "iPhone X" - }, - "iPhone10,4": { - "bezel": 0, - "name": "iPhone 8" - }, - "iPhone10,5": { - "bezel": 0, - "name": "iPhone 8 Plus" - }, - "iPhone10,6": { - "bezel": 39, - "name": "iPhone X" - }, - "iPhone11,2": { - "bezel": 39, - "name": "iPhone Xs" - }, - "iPhone11,4": { - "bezel": 39, - "name": "iPhone Xs Max" - }, - "iPhone11,6": { - "bezel": 39, - "name": "iPhone Xs Max" - }, - "iPhone11,8": { - "bezel": 41.5, - "name": "iPhone Xʀ" - }, - "iPhone12,1": { - "bezel": 41.5, - "name": "iPhone 11" - }, - "iPhone12,3": { - "bezel": 39, - "name": "iPhone 11 Pro" - }, - "iPhone12,5": { - "bezel": 39, - "name": "iPhone 11 Pro Max" - }, - "iPhone12,8": { - "bezel": 0, - "name": "iPhone SE (2nd generation)" - }, - "iPhone13,1": { - "bezel": 44, - "name": "iPhone 12 mini" - }, - "iPhone13,2": { - "bezel": 47.33, - "name": "iPhone 12" - }, - "iPhone13,3": { - "bezel": 47.33, - "name": "iPhone 12 Pro" - }, - "iPhone13,4": { - "bezel": 53.33, - "name": "iPhone 12 Pro Max" - }, - "iPhone14,2": { - "bezel": 47.33, - "name": "iPhone 13 Pro" - }, - "iPhone14,3": { - "bezel": 53.33, - "name": "iPhone 13 Pro Max" - }, - "iPhone14,4": { - "bezel": 44, - "name": "iPhone 13 mini" - }, - "iPhone14,5": { - "bezel": 47.33, - "name": "iPhone 13" - }, - "iPhone14,6": { - "bezel": 0, - "name": "iPhone SE (3rd generation)" - }, - "iPhone14,7": { - "bezel": 47.33, - "name": "iPhone 14" - }, - "iPhone14,8": { - "bezel": 53.33, - "name": "iPhone 14 Plus" - }, - "iPhone15,2": { - "bezel": 55, - "name": "iPhone 14 Pro" - }, - "iPhone15,3": { - "bezel": 55, - "name": "iPhone 14 Pro Max" - }, - "iPhone15,4": { - "bezel": 55, - "name": "iPhone 15" - }, - "iPhone15,5": { - "bezel": 55, - "name": "iPhone 15 Plus" - }, - "iPhone16,1": { - "bezel": 55, - "name": "iPhone 15 Pro" - }, - "iPhone16,2": { - "bezel": 55, - "name": "iPhone 15 Pro Max" - } - }, - "iPod": { - "iPod1,1": { - "bezel": 0, - "name": "iPod touch (1st generation)" - }, - "iPod2,1": { - "bezel": 0, - "name": "iPod touch (2nd generation)" - }, - "iPod3,1": { - "bezel": 0, - "name": "iPod touch (3rd generation)" - }, - "iPod4,1": { - "bezel": 0, - "name": "iPod touch (4th generation)" - }, - "iPod5,1": { - "bezel": 0, - "name": "iPod touch (5th generation)" - }, - "iPod7,1": { - "bezel": 0, - "name": "iPod touch (6th generation)" - }, - "iPod9,1": { - "bezel": 0, - "name": "iPod touch (7th generation)" - } - } - }, - "pending": {}, - "problematic": {} -} \ No newline at end of file diff --git a/Generator/index.js b/Generator/index.js deleted file mode 100644 index 91ae4a0..0000000 --- a/Generator/index.js +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Fetch Bezel Data Script - * ----------------------- - * This script extracts bezel data from simulators and merges it into a device database. - * - * Author: Mark Battistella - * Version: 2.0.0 - * Licence: MIT - * Contact: @markbattistella - * Website: https://markbattistella.com - * Copyright (c) 2023 Mark Battistella - * - * Description: - * This script automates the process of extracting bezel data from iOS simulators - * and merging it into a device database. It requires Node.js and Xcode to be installed. - */ - -/** - * Importing internal modules required for the operation. - */ -import * as logger from './modules/logger.mjs'; -import * as util from './modules/utilities.mjs'; -import * as defaults from './modules/defaults.mjs'; - -/** - * Get the default variables or those provided via command line arguments. - * @constant - * @type {Object} - */ -const VARIABLE = defaults.getVariables(process.argv); - -/** - * Set up the logging mechanism based on whether 'debug' mode is active or not. - */ -logger.setup(VARIABLE.debug); - -/** - * Initializes the process of data extraction. - * - * The flow involves: - * 1. Displaying onscreen help. - * 2. Reading and processing device data from a JSON database. - * 3. Identifying simulators based on the data. - * 4. Generating related data for these simulators. - * 5. Saving the updated information to a database. - * - * @async - * @function - */ -const init = async () => { - try { - - /** Display the onscreen help menu. */ - defaults.displayHelp(); - - /** - * Extract device data from the provided JSON database. - * @constant - * @type {Object} - */ - const { - pendingDevices, - originalDatabase - } = await util.extractDeviceDataFromFile(VARIABLE.databaseJson); - - /** - * Derive simulator-specific information based on the extracted devices. - * @constant - * @type {Object} - */ - const { - foundDevices, - unfoundDevices - } = util.getSimulatorObjectData(pendingDevices); - - /** - * Get simulator details, especially the bezel radius data. - * @constant - * @type {Array} - */ - const bezelSimulators = await util.generateData( - foundDevices, - VARIABLE.xCodeData.project, - VARIABLE.xCodeData.scheme, - VARIABLE.xCodeData.bundleId - ); - - /** - * Save the newly derived information to a database, - * while also making necessary updates and removals. - */ - await util.saveNewDatabase( - originalDatabase, - bezelSimulators, - unfoundDevices, - VARIABLE.databaseJson, - VARIABLE.output - ); - - } catch (error) { - /** Log the error and halt the process if any unexpected issues arise. */ - logger.error('An error occurred during the init process', error); - process.exit(1); - } -}; - -/** - * Start the data extraction process by initializing the script. - */ -await init(); diff --git a/Generator/modules/args.mjs b/Generator/modules/args.mjs deleted file mode 100644 index f824730..0000000 --- a/Generator/modules/args.mjs +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Module: args - * Description: This module provides a utility to parse command line arguments. - * - * Author: Mark Battistella - * Licence: MIT - */ - -/** - * Parses command line arguments into an object. - * - * @function - * @param {string[]} argv - Array of command line arguments. - * @returns {Object} - An object with argument names as keys and their corresponding values. - * - * @example - * // Assuming the script is run with: node index.js --name=John --age=30 - * cargs(process.argv); - * // Returns: { name: 'John', age: 30 } - */ -export const cargs = (argv) => { - const args = {}; - for (const arg of argv.slice(2)) { - let [argName, argValue] = arg.split('='); - argName = argName.replace(/^-+/, ''); - argValue = argValue ? (isNaN(argValue) ? argValue : parseFloat(argValue)) : true; - args[argName] = argValue; - } - return args; -}; diff --git a/Generator/modules/defaults.mjs b/Generator/modules/defaults.mjs deleted file mode 100644 index c57c25e..0000000 --- a/Generator/modules/defaults.mjs +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Module: defaults - * Description: This module provides default configurations, command-line argument parsing, - * and a help generator for the CLI tool. - * - * Author: Mark Battistella - * Licence: MIT - */ - -import { cargs } from './args.mjs'; - -// Default configuration constants -const DEFAULTS = { - databaseJson: './apple-device-database.json', - xCodeData: { - project: './FetchBezel/FetchBezel.xcodeproj', - scheme: 'FetchBezel', - bundleId: 'com.mb.FetchBezel' - }, - output: '../Sources/BezelKit/Resources/bezel.min.json', - debug: true -}; - -/** - * Returns the value if defined or defaults to the provided default value. - * - * @function - * @param {*} value - The value to check. - * @param {*} defaultValue - The default value to return if the value is undefined or true. - * @returns {*} - The value or the default value. - */ -const assignOrDefault = (value, defaultValue) => ( - value === undefined || value === true ? defaultValue : value -); - -const ARGS = cargs(process.argv); - -/** - * Gathers and returns configuration variables either from the provided command-line - * arguments or default values. - * - * @function - * @returns {Object} - Configuration object. - */ -export const getVariables = () => { - return { - databaseJson: assignOrDefault( - ARGS.database || ARGS.db, DEFAULTS.databaseJson), - xCodeData: { - project: assignOrDefault( - ARGS.project || ARGS.p, DEFAULTS.xCodeData.project), - scheme: assignOrDefault( - ARGS.scheme || ARGS.s, DEFAULTS.xCodeData.scheme), - bundleId: assignOrDefault( - ARGS.bundle || ARGS.b, DEFAULTS.xCodeData.bundleId) - }, - output: assignOrDefault( - ARGS.output || ARGS.o, DEFAULTS.output), - debug: assignOrDefault( - ARGS.debug || ARGS.d, DEFAULTS.debug) === 'false' ? false : true - }; -}; - -/** - * Generates and displays the help message for the CLI tool. - * - * @private - */ -const generateHelp = () => { - console.log(` ---------------------------------------------------- --- CLI for generating simulator bezel data -- ---------------------------------------------------- - -Usage: [command] [options] - -Options: - --database, -db Path to the Apple device database JSON file. - Default: './apple-device-database.json' - - --project, -p Path to the FetchBezel XCode project. - Default: './FetchBezel/FetchBezel.xcodeproj' - - --scheme, -s Scheme name for the FetchBezel project. - Default: 'FetchBezel' - - --bundle, -b Bundle ID for the FetchBezel app. - Default: 'com.mb.FetchBezel' - - --output, -o Path to the output JSON file. - Default: '../Sources/BezelKit/Resources/bezel.min.json' - - --debug, -d Enable debugging mode. Pass 'false' to disable. - Default: 'true' - - --help, -h Display this help message and exit. - -Example: - node index.js --database="./path/to/db.json" --debug="false" -`); -}; - -/** - * Displays the CLI tool's help message if the `help` or `h` command-line argument is provided. - * - * @function - */ -export const displayHelp = () => { - if (ARGS.help || ARGS.h) { - generateHelp(); - process.exit(0); - } -}; diff --git a/Generator/modules/logger.mjs b/Generator/modules/logger.mjs deleted file mode 100644 index 3a79511..0000000 --- a/Generator/modules/logger.mjs +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Module: logger - * Description: Provides custom logging functionalities, logging messages to both console and a log file. Additionally, it handles archiving and purging of old logs. - * - * Author: Mark Battistella - * Licence: MIT - */ - -// Importing required modules for filesystem and path manipulation. -import fs from 'fs'; -import path from 'path'; - -/** - * Initializes and configures custom logging. - * - * @param {boolean} debug - Flag to indicate whether to enable logging. - */ -export const setup = (debug) => { - - // Early exit if logging is disabled. - if (!debug) return; - - // Define constants for log directory and log file path. - const LOG_DIR = 'logs'; - const LOG_FILE = path.join(LOG_DIR, '_console.log'); - - /** - * Deletes the oldest logs, keeping only the 14 newest logs. - */ - const deleteOldestLogs = () => { - const logs = fs.readdirSync(LOG_DIR); // Read the log directory - const sortedLogs = logs.sort((a, b) => { - const aStat = fs.statSync(path.join(LOG_DIR, a)); - const bStat = fs.statSync(path.join(LOG_DIR, b)); - return bStat.mtime - aStat.mtime; // Sort logs by modification time in descending order. - }); - - // Remove logs if there are more than 14, keeping the newest. - while (sortedLogs.length > 13) { - const oldestLog = sortedLogs.pop(); - fs.unlinkSync(path.join(LOG_DIR, oldestLog)); - } - }; - - // Create the log directory if it doesn't exist. - if (!fs.existsSync(LOG_DIR)) { - fs.mkdirSync(LOG_DIR, { recursive: true }); - } - - // Archive and move the existing log file if it exists, and then delete the oldest logs. - if (fs.existsSync(LOG_FILE)) { - const date = new Date().toISOString().replace(/[:.]/g, '-'); - const archiveLogName = `console_${date}.log`; - const destination = path.join(LOG_DIR, archiveLogName); - fs.renameSync(LOG_FILE, destination); - deleteOldestLogs(); - } - - /** - * Creates a custom logger function for console methods. - * - * @param {string} method - The console method to override ('log', 'error', 'warn', 'info'). - * @returns {Function} - A custom logger function. - */ - const createCustomLogger = (method) => { - return (...args) => { - console['_' + method](...args); // Call the backup original method. - const entry = `[${getHumanReadableTimestamp()}] ` + args.join(' ') + '\n'; - fs.appendFile(LOG_FILE, entry, err => { // Append the log to the file. - if (err) { - console['_' + method]('Failed to write to log:', err); - } - }); - }; - }; - - /** - * Generates a human-readable timestamp for logging. - * - * @returns {string} A timestamp in a human-readable format. - */ - const getHumanReadableTimestamp = () => { - const date = new Date(); - const options = { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit', - hour12: true - }; - return date.toLocaleString(undefined, options); - }; - - // Backup existing console methods for safe overriding. - console._log = console.log; - console._error = console.error; - console._warn = console.warn; - console._info = console.info; - - // Create custom logger functions for each console method. - const customLogger = createCustomLogger('log'); - const customErrorLogger = createCustomLogger('error'); - const customWarnLogger = createCustomLogger('warn'); - const customInfoLogger = createCustomLogger('info'); - - // Override the existing console methods with custom loggers. - console.log = customLogger; - console.error = customErrorLogger; - console.warn = customWarnLogger; - console.info = customInfoLogger; -}; - -/** - * A generic logging function. - * - * @param {string} level - The logging level ('error', 'warn', 'info', etc.). - * @param {string} colour - The color for the log level. - * @param {string} [title=''] - The title to display before the message. - * @param {string} message - The message to log. - * @param {Error} [error] - Optional Error object. - * @param {number} [indent=0] - The number of spaces for indentation. - */ -const genericLog = (level, colour, title = '', message, error, indent) => { - const indentation = " ".repeat(indent); - const logMessage = `${indentation}${colour}${title}${colours.reset}${message}`; - console[level](logMessage); - if (error && error.message) { - const errorMessage = `${indentation}${colours.fg.gray} ↳ Message: ${colours.reset}${error.message}`; - console[level](errorMessage); - } -}; - -/** - * Log an error message. - * - * @param {string} message - The error message. - * @param {Error} [error] - Optional Error object. - * @param {number} [indent=0] - The number of spaces for indentation. - */ -export const error = (message, error = null, indent = 0) => { - genericLog('error', colours.fg.red, '[x] ERROR: ', message, error, indent); -}; - -/** - * Log a warning message. - * - * @param {string} message - The warning message. - * @param {Error} [error] - Optional Error object. - * @param {number} [indent=0] - The number of spaces for indentation. - */ -export const warn = (message, error = null, indent = 0) => { - genericLog('warn', colours.fg.yellow, '[!] WARN: ', message, error, indent); -}; - -/** - * Log an informational message. - * - * @param {string} message - The information message. - * @param {Error} [error] - Optional Error object. - * @param {number} [indent=0] - The number of spaces for indentation. - */ -export const info = (message, error = null, indent = 0) => { - genericLog('info', colours.fg.blue, '[i] INFO: ', message, error, indent); -}; - -/** - * Log a success message. - * - * @param {string} message - The success message. - * @param {number} [indent=0] - The number of spaces for indentation. - */ -export const success = (message, indent = 0) => { - genericLog('info', colours.fg.green, '[√] OKAY: ', message, null, indent); -}; - -/** - * General-purpose log function. - * - * @param {string} message - The message to log. - * @param {number} [indent=0] - The number of spaces for indentation. - */ -export const log = (message, indent = 0) => { - genericLog('info', colours.fg.gray, '', message, null, indent); -}; - -/** - * Colours object providing ANSI color codes for terminal text formatting. - * Useful for distinguishing different logging levels or highlighting specific messages. - */ -export const colours = { - reset: "\x1b[0m", - bright: "\x1b[1m", - dim: "\x1b[2m", - underscore: "\x1b[4m", - blink: "\x1b[5m", - reverse: "\x1b[7m", - hidden: "\x1b[8m", - - fg: { - black: "\x1b[30m", - red: "\x1b[31m", - green: "\x1b[32m", - yellow: "\x1b[33m", - blue: "\x1b[34m", - magenta: "\x1b[35m", - cyan: "\x1b[36m", - white: "\x1b[37m", - gray: "\x1b[90m", - crimson: "\x1b[38m" - }, - bg: { - black: "\x1b[40m", - red: "\x1b[41m", - green: "\x1b[42m", - yellow: "\x1b[43m", - blue: "\x1b[44m", - magenta: "\x1b[45m", - cyan: "\x1b[46m", - white: "\x1b[47m", - gray: "\x1b[100m", - crimson: "\x1b[48m" - } -}; \ No newline at end of file diff --git a/Generator/modules/utilities.mjs b/Generator/modules/utilities.mjs deleted file mode 100644 index a51bb47..0000000 --- a/Generator/modules/utilities.mjs +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Module: util - * Description: Provides a collection of utility functions designed to perform various - * operations to extract bezel radius data from an Xcode project. - * - * Author: Mark Battistella - * Licence: MIT - */ - -import { promises as fsp } from 'fs'; -import { execSync } from 'child_process'; -import * as logger from './logger.mjs'; - -/** - * Parses a JSON file and returns its contents as an object. - * - * @async - * @param {string} file - Path to the JSON file. - * @returns {Object} - Parsed contents of the JSON file. - * @throws {Error} If reading the file or parsing JSON fails. - */ -const parseJsonFile = async (file) => { - const data = await fsp.readFile(file, 'utf8'); - return JSON.parse(data); -}; - -/** - * Executes a shell command and returns its standard output. - * - * @param {string} command - The command to execute. - * @returns {string} - The standard output of the executed command. - */ -const executeCommand = command => { - return execSync(command, { encoding: 'utf8' }); -}; - -/** - * Extracts a value from a settings string based on a key. - * The settings are expected to be newline-separated key-value pairs. - * - * @param {string} settings - The settings string, newline-separated. - * @param {string} key - The key for which the value needs to be extracted. - * @returns {string|null} - The extracted value or null if the key is not found. - */ -const getSettingValue = (settings, key) => { - const settingLine = settings.split('\n').find(line => line.includes(key)); - return settingLine ? settingLine.split('=')[1].trim() : null; -}; - -/** - * Introduces a delay in the execution. - * - * @param {number} ms - The delay duration in milliseconds. - * @returns {Promise} - Resolves after the specified delay. - */ -const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); - - -/** - * Extracts relevant device data from a specified file. - * - * @async - * @param {string} file - Path to the JSON file containing device data. - * @returns {Object} - An object containing the pending devices to process and the original database. - * @throws {Error} If there's an error in parsing the file or processing the data. - */ -export const extractDeviceDataFromFile = async (file) => { - // Parse the provided JSON file to get the original database. - const originalDatabase = await parseJsonFile(file); - - // Combine pending and problematic devices from the original database. - const combinedPendingDevices = { ...originalDatabase.pending, ...originalDatabase.problematic }; - - // Filter out iPod, iPad, and iPhone devices from the database. - const databaseDevices = Object.entries(originalDatabase.devices) - .filter(([deviceType]) => ['iPod', 'iPad', 'iPhone'].includes(deviceType)) - .reduce((acc, [, deviceList]) => ({ ...acc, ...deviceList }), {}); - - // Identify devices in the combined pending list that are not in the main database. - const pendingDevices = filterUnlistedDevices(combinedPendingDevices, databaseDevices); - - // If there are no new pending devices, log a success message and exit. - if (Object.keys(pendingDevices).length === 0) { - logger.success('There are no new simulators to process 🎉'); - process.exit(0); - } - - return { pendingDevices, originalDatabase }; -}; - -/** - * Filters out devices that are not listed in a main device database. - * - * @param {Object} pendingDevices - An object of devices that are pending processing. - * @param {Object} allDevices - An object containing the main list of devices. - * @returns {Object} - An object containing only the devices from the pending list that are not in the main device list. - */ -const filterUnlistedDevices = (pendingDevices, allDevices) => { - // Retrieve the keys (device identifiers) from the main device database. - const deviceKeys = Object.keys(allDevices); - - // Filter out devices from the pending list that aren't present in the main device list. - return Object.keys(pendingDevices).reduce((acc, deviceKey) => { - // If a device from the pending list isn't in the main list, add it to the accumulator. - if (!deviceKeys.includes(deviceKey)) { - acc[deviceKey] = pendingDevices[deviceKey]; - } - return acc; - }, {}); -}; - - -/** - * Transforms device objects into an array of device identifiers and names. - * - * @param {Object} deviceObjects - The device objects to transform. - * @returns {Array} An array of objects containing device identifiers and names. - */ -const transform = deviceObjects => - Object.keys(deviceObjects).map(identifier => ( - { identifier, name: deviceObjects[identifier].name }) - ); - -/** - * Retrieves a list of available simulators. - * - * @returns {Object} An object containing available devices parsed from the command's JSON output. - */ -const getAvailableSimulators = () => { - const json = executeCommand('xcrun simctl list devices -j'); - return JSON.parse(json).devices; -}; - -/** - * Retrieves a list of available runtimes. - * - * @returns {Array} An array of runtime objects sorted by version in descending order. - */ -const getAvailableRuntimes = () => { - const json = executeCommand('xcrun simctl list runtimes -j'); - return JSON.parse(json).runtimes.sort( - (a, b) => parseFloat(b.version) - parseFloat(a.version)); -}; - -/** - * Retrieves data for a specific simulator by name. - * - * @param {string} name - The name of the simulator to search for. - * @returns {Object|null} The simulator object if found, otherwise null. - */ -const getSimulatorData = name => { - const simulators = getAvailableSimulators(); - for (const runtime in simulators) { - const foundDevice = simulators[runtime].find(device => device.name === name); - if (foundDevice) return foundDevice; - } - return null; -}; - -/** - * Retrieves the supported runtime for a specific simulator. - * - * @param {string} name - The name of the simulator to search for. - * @returns {Object|null} An object containing simulator and runtime identifiers, otherwise null. - */ -const getSupportedRuntime = name => { - const runtimes = getAvailableRuntimes(); - for (const runtime of runtimes) { - const foundDevice = runtime.supportedDeviceTypes.find(device => device.name === name); - if (foundDevice) return { simulatorId: foundDevice.identifier, runtimeId: runtime.identifier }; - } - return null; -}; - -/** - * Installs a simulator. - * - * @param {Object} options - An object containing `name`, `simulatorId`, and `runtimeId` - * for the simulator to install. - * @returns {string} The output of the installation command. - */ -const installSimulator = ({ name, simulatorId, runtimeId }) => - executeCommand(`xcrun simctl create "${name}" "${simulatorId}" "${runtimeId}"`) - .toString() - .trim(); - -/** - * Processes a simulator device by either retrieving its existing data or installing - * it if not present. - * - * @param {Object} device - The device object containing information like its name. - * @returns {Object|null} An object containing the processed device data, or null if - * the device cannot be processed. - */ -const processSimulator = device => { - - // Check if the simulator for the given device already exists. - const existingSimulator = getSimulatorData(device.name); - - // If the simulator exists, return its data along with the given device data. - if (existingSimulator) return { - ...device, - udid: existingSimulator.udid, - state: existingSimulator.state - }; - - // If the simulator doesn't exist, check if there's a supported runtime available for it. - const supportedRuntime = getSupportedRuntime(device.name); - - // If there's no supported runtime, log a warning and return null. - if (!supportedRuntime) { - logger.warn(`No supported runtime found for device: ${device.name}`); - return null; - } - - // Install the simulator for the given device using the found supported runtime. - const udid = installSimulator({ name: device.name, ...supportedRuntime }); - - // If the simulator couldn't be installed, log a warning and return null. - if (!udid) { - logger.warn(`Failed to install simulator for device: ${device.name}`); - return null; - } - - // Retrieve the newly installed simulator's data. - const simulatorData = getSimulatorData(device.name); - return { - ...device, - udid: udid, - state: simulatorData.state - }; -}; - -/** - * Processes a set of simulator objects to determine which ones exist and which don't. - * - * @param {Object[]} objects - An array of simulator objects to be processed. - * @returns {Object} An object containing two arrays: `foundDevices` with existing - * simulators and `unfoundDevices` with simulators that couldn't be found or processed. - */ -export const getSimulatorObjectData = objects => { - - // Arrays to store the found and unfound devices. - const foundDevices = []; - const unfoundDevices = []; - - // Transform the given objects into a usable format. - const transformedObjects = transform(objects); - - // Iterate over each transformed object. - transformedObjects.forEach(object => { - // Process the simulator object to check if it exists. - const result = processSimulator(object); - - // Based on the result, classify the device as either found or unfound. - result ? foundDevices.push(result) : unfoundDevices.push(object); - }); - - // Return the classified devices in two separate arrays. - return { foundDevices, unfoundDevices }; -}; - - -/** - * Returns the build path for an app using given project parameters. - * - * @param {string} projectPath - The path to the Xcode project. - * @param {string} projectScheme - The scheme name of the Xcode project. - * @returns {string} The path to the built app. - */ -const getAppBuildPath = (projectPath, projectScheme) => { - - // Execute a clean build of the Xcode project, suppressing warnings in the output. - executeCommand(`xcodebuild -project "${projectPath}" -scheme "${projectScheme}" -destination 'generic/platform=iOS Simulator' clean build 2>&1 | grep -v warning`); - - // Retrieve build settings of the Xcode project. - const buildSettings = executeCommand(`xcodebuild -project "${projectPath}" -sdk iphonesimulator -configuration Debug -showBuildSettings`); - - // Extract the directory where the built products reside from the build settings. - const builtProductsDirectory = getSettingValue(buildSettings, "BUILT_PRODUCTS_DIR"); - - // Extract the name of the built product from the build settings. - const fullProductName = getSettingValue(buildSettings, "FULL_PRODUCT_NAME"); - - // Return the full path to the built app. - return `${builtProductsDirectory}/${fullProductName}`; -}; - -/** - * Shuts down a specified simulator if it's not already in a `Shutdown` state. - * - * @param {Object} simulator - The simulator object with details such as its - * `state`, `name`, and `udid`. - */ -const shutdownSimulator = (simulator) => { - - // Check if the simulator is not already in a 'Shutdown' state. - if (simulator.state !== 'Shutdown') { - // Log a warning that the simulator isn't shut down. - logger.warn('Simulator is not shutdown', null, 2); - - // Log an attempt to shut down the simulator. - logger.log(`↳ Attempting to shutdown: ${simulator.name}`, 6); - - // Execute the command to shut down the simulator using its UDID. - executeCommand(`xcrun simctl shutdown "${simulator.udid}"`); - - // Log a success message indicating the simulator was shut down. - logger.success('Simulator successfully shut down', 2); - } -}; - -/** - * Reads data from a simulator based on its UDID and a specified bundle ID. - * - * @async - * @param {string} udid - The UDID of the simulator. - * @param {string} bundleId - The bundle ID of the app whose data needs to be read. - * @returns {Object} The parsed JSON data from the specified file path within the simulator. - */ -const readSimulatorData = async (udid, bundleId) => { - - // Get the app's container path within the simulator using its UDID and bundle ID. - const appContainerPath = executeCommand(`xcrun simctl get_app_container "${udid}" "${bundleId}" data`).trim(); - - // Construct the file path to the desired JSON data within the app's container. - const filePath = `${appContainerPath}/Documents/output.json`; - - // Parse and return the JSON data from the specified file path. - return await parseJsonFile(filePath); -}; - - -/** - * Generates data for a list of simulators based on project details and an app bundle ID. - * - * @async - * @param {Object[]} simulators - An array of simulator objects. - * @param {string} projectPath - The path to the Xcode project. - * @param {string} projectScheme - The scheme name of the Xcode project. - * @param {string} appBundleID - The bundle ID of the app for which data is being generated. - * @returns {Object[]} An array of objects containing data for each simulator. - */ -export const generateData = async (simulators, projectPath, projectScheme, appBundleID) => { - const allSimulatorData = []; - - // Determine the build path for the app using the project details. - const appBuildPath = getAppBuildPath(projectPath, projectScheme); - const totalSimulators = simulators.length; - - for (const [index, simulator] of simulators.entries()) { - const indexNumber = index + 1 - - // Display the current simulator being processed. - console.log( - logger.colours.bg.cyan, - `** Start work on simulator: ${indexNumber} / ${totalSimulators} **`, - logger.colours.reset, - '\n' - ); - - // Log details of the current simulator. - logger.info(`Current device: ${simulator.name}`, null, 2) - logger.log(`↳ Name: ${simulator.name}`, 6); - logger.log(`↳ Identifier: ${simulator.identifier}`, 6); - logger.log(`↳ UDID: ${simulator.udid}`, 6); - logger.log(`↳ State: ${simulator.state}`, 6); - - // Ensure the simulator is shut down. - shutdownSimulator(simulator); - - // Boot the simulator. - logger.info('Booting the simulator for testing', null, 2); - executeCommand(`xcrun simctl boot '${simulator.udid}'`); - - // Install and launch the app on the simulator. - logger.info(`Installing local project with bundle ID: ${appBundleID}`, null, 2); - logger.log('↳ Installing app', 6); - executeCommand(`xcrun simctl install '${simulator.udid}' "${appBuildPath}"`); - - logger.log('↳ Launching app', 6); - executeCommand(`xcrun simctl launch '${simulator.udid}' '${appBundleID}'`); - - // Wait for a while to let the app complete its operations. - logger.log('↳ Waiting 5 seconds', 6); - await delay(5000); - - // Read data from the simulator. - logger.log('↳ Reading bezel data from device', 6); - const data = await readSimulatorData(simulator.udid, appBundleID); - - const deviceData = { - ... simulator, - bezel: data.bezel - }; - allSimulatorData.push(deviceData); - logger.log('↳ Found device data', 6); - - // Wait again for other possible operations. - logger.log('↳ Waiting 5 seconds', 6); - await delay(5000); - - // Terminate and uninstall the app from the simulator. - logger.log('↳ Terminating app', 6); - executeCommand(`xcrun simctl terminate '${simulator.udid}' "${appBundleID}"`); - logger.log('↳ Deleting app from simulator', 6); - executeCommand(`xcrun simctl uninstall "${simulator.udid}" "${appBundleID}"`); - - // Shut down the simulator after processing. - logger.info('Shutting down the simulator\n', null, 2); - executeCommand(`xcrun simctl shutdown "${simulator.udid}"`); - }; - - return allSimulatorData; -}; - - -/** - * Merges new device data with original device data, adding or updating device entries as required. - * - * @param {Object} originalData - The original device data. - * @param {Object[]} newData - Array of new device objects to be merged. - * @returns {Object} - The merged device data. - */ -const mergeDeviceData = (originalData, newData) => { - newData.forEach(device => { - - // Determine the device category (e.g., 'iPhone') from the device name. - const category = device.name.split(" ")[0]; - - // If the category does not exist in original data, initialize it. - if (!originalData.devices[category]) { - originalData.devices[category] = {}; - } - - // If device already exists, update its bezel data, else add the device entry. - if (originalData.devices[category][device.identifier]) { - originalData.devices[category][device.identifier].bezel = device.bezel; - } else { - originalData.devices[category][device.identifier] = { - name: device.name, - bezel: device.bezel - }; - } - }); - return originalData; -}; - -/** - * Cleans the device database, setting pending to empty and adding unfound devices - * to the problematic list. - * - * @param {Object} newData - The new device data to be cleaned. - * @param {Object[]} unfoundDevices - Array of device objects that weren't found. - * @returns {Object} - The cleaned device data. - */ -const cleanDatabase = (newData, unfoundDevices) => { - - // Reset the pending list to empty. - newData.pending = {}; - - // For each unfound device, if it's not in the problematic list, add it. - unfoundDevices.forEach(device => { - if (!newData.problematic[device.identifier]) { - newData.problematic[device.identifier] = { - name: device.name ? device.name : '' - }; - } - }); - return newData; -}; - -/** - * Sorts the keys of a JSON object using a custom sorting function. - * - * The sort order is determined by extracting numeric values from keys and sorting them. - * If two keys have the same numeric value, they are sorted lexicographically. - * - * @param {Object} json - The JSON object to be sorted. - * @returns {Object} - The sorted JSON object. - */ -const sortJSON = (json) => { - - /** - * Custom sorting function for string keys. - * - * Extracts numbers from keys and sorts them in ascending order. - * If two keys have the same numeric value, sorts them lexicographically. - * - * @param {string} a - First key to compare. - * @param {string} b - Second key to compare. - * @returns {number} - Returns -1 if 'a' should be sorted before 'b', 1 if 'a' should be sorted after 'b', and 0 if they are equal. - */ - const customSort = (a, b) => { - const numberA = parseFloat(a.match(/\d+(?:,\d+)?/)); - const numberB = parseFloat(b.match(/\d+(?:,\d+)?/)); - if (numberA < numberB) return -1; - if (numberA > numberB) return 1; - return a.localeCompare(b); - } - - /** - * Recursively sorts the keys of an object. - * - * Sorts the keys of the input object based on the customSort function. - * If a key's value is an object, sorts its keys recursively. - * - * @param {Object} obj - The object whose keys need to be sorted. - * @returns {Object} - The object with sorted keys. - */ - const sortKeysRecursively = (obj) => { - if (typeof obj !== 'object' || obj === null) { - return obj; - } - const sortedObj = {}; - Object.keys(obj).sort(customSort).forEach(key => { - sortedObj[key] = sortKeysRecursively(obj[key]); - }); - return sortedObj; - } - - return sortKeysRecursively(json); -} - -/** - * Processes and saves the new device database. - * - * This function does the following: - * 1. Merges new device data with the original data. - * 2. Cleans the merged data by updating the problematic list with unfound devices and resetting the pending list. - * 3. Sorts the cleaned data. - * 4. Writes the sorted data to a cache file and writes a minified version to a package file. - * - * @async - * @param {Object} originalData - The original device data. - * @param {Object[]} newData - Array of new device objects. - * @param {Object[]} unfoundDevices - Array of device objects that weren't found. - * @param {string} cacheFilePath - Path where the sorted data should be saved. - * @param {string} packageFilePath - Path where the minified data should be saved. - */ -export const saveNewDatabase = async (originalData, newData, unfoundDevices, cacheFilePath, packageFilePath) => { - - // Merge new data with the original data. - const mergedData = mergeDeviceData(originalData, newData); - - // Clean the merged data by updating the problematic list and resetting the pending list. - const cleanData = cleanDatabase(mergedData, unfoundDevices); - - // Sort the cleaned data. - const sortedData = sortJSON(cleanData); - - // Prepare a minified version of the sorted data by removing the pending and problematic lists. - const minifiedData = { ...sortedData }; - delete minifiedData.pending; - delete minifiedData.problematic; - - // Write the sorted data to the cache file. - await fsp.writeFile(cacheFilePath, JSON.stringify(sortedData, null, 2), 'utf-8'); - logger.success(`Saved cache file: ${cacheFilePath}`); - - // Write the minified data to the package file. - await fsp.writeFile(packageFilePath, JSON.stringify(minifiedData, null, null), 'utf-8'); - logger.success(`Saved resource file: ${packageFilePath}`); -}; diff --git a/Generator/package.json b/Generator/package.json deleted file mode 100644 index a7548f0..0000000 --- a/Generator/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "bezel-extractor", - "version": "1.0.0", - "description": "A simple project to install iOS and iPadOS simulators, run an Xcode project to extract bezel data, and merge it into a single JSON file.", - "main": "index.js", - "repository": { - "type": "git", - "url": "https://github.com/markbattistella/bezelkit-extractor/" - }, - "author": "Mark Battistella", - "license": "MIT", - "bugs": { - "url": "https://github.com/markbattistella/bezelkit-extractor/issues/" - }, - "homepage": "https://github.com/markbattistella/bezelkit-extractor/", - "keywords": [], - "type": "module", - "scripts": { - "start": "node index.js" - }, - "dependencies": {}, - "devDependencies": {} -} \ No newline at end of file diff --git a/LICENCE b/LICENCE index c6c8e91..dd9d55f 100644 --- a/LICENCE +++ b/LICENCE @@ -14,7 +14,7 @@ copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE diff --git a/README.md b/README.md index 7af4995..b2381e3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- + # BezelKit @@ -37,7 +37,7 @@ Another consideration stems from the variability in screen bezel dimensions acro 1. If the actual bezel radius is smaller or larger than the static value, the UI corners will appear disproportionately thick or thin. - ![Zoomed - Static Value](https://raw.githubusercontent.com/markbattistella/BezelKit/main/Data/zoomed-static.jpg) + ![Zoomed - Static Value](https://raw.githubusercontent.com/markbattistella/BezelKit/main/.github/data/zoomed-static.jpg) 2. On older devices or those with square screens, such as the SE models, the display will inaccurately feature curved corners when it should not. @@ -45,7 +45,7 @@ While Apple has provided the [`ContainerRelativeShape`](https://developer.apple. A nice looking solution would look like this: -![Zoomed - BezelKit](https://raw.githubusercontent.com/markbattistella/BezelKit/main/Data/zoomed-bezelkit.jpg) +![Zoomed - BezelKit](https://raw.githubusercontent.com/markbattistella/BezelKit/main/.github/data/zoomed-bezelkit.jpg) ## Compatibility @@ -99,7 +99,7 @@ let innerBezel = outerBezel - distance // Perfect ratio By following this approach, you can ensure that your UI elements scale perfectly in relation to the device's bezel size. -![Perfect scaling](https://raw.githubusercontent.com/markbattistella/BezelKit/main/Data/ratio.jpg) +![Perfect scaling](https://raw.githubusercontent.com/markbattistella/BezelKit/main/.github/data/ratio.jpg) ### Setting a Fallback Bezel Size @@ -256,7 +256,7 @@ struct ContentView: View { } ``` -![Comparison - Static Values](https://raw.githubusercontent.com/markbattistella/BezelKit/main/Data/comparison-static.jpg) +![Comparison - Static Values](https://raw.githubusercontent.com/markbattistella/BezelKit/main/.github/data/comparison-static.jpg) In a fixed value configuration, devices with no curved screen look odd, while this `cornerRadius` is designed for the iPhone 14 Pro Max, it looks chunky on the iPhone 14, and *good-ish* on the iPhone 14 Pro. @@ -275,7 +275,7 @@ struct ContentView: View { } ``` -![Comparison - BezelKit](https://raw.githubusercontent.com/markbattistella/BezelKit/main/Data/comparison-bezelkit.jpg) +![Comparison - BezelKit](https://raw.githubusercontent.com/markbattistella/BezelKit/main/.github/data/comparison-bezelkit.jpg) As you can see, with no `setFallbackBezelKit` set, the iPhone SE (3rd generation) value is set to `0.0` and results in no curve. However, all other curved devices have a consistent look. @@ -336,7 +336,7 @@ If you'd like to update or extend the list of device bezel sizes, you can easily 1. **Adding to `pending` object**: Add more devices and their identifiers to the existing JSON file. Make sure the friendly names in the JSON match the "Device Type" from the `Create New Simulator` screen in Xcode. - ![Add New Simulator](https://raw.githubusercontent.com/markbattistella/BezelKit/main/Data/simulator.jpg) + ![Add New Simulator](https://raw.githubusercontent.com/markbattistella/BezelKit/main/.github/data/simulator.jpg) ```json "pending" : {