{"id":20441993,"url":"https://github.com/johnbean393/extensionkit","last_synced_at":"2026-02-03T10:31:30.285Z","repository":{"id":214349011,"uuid":"736244804","full_name":"johnbean393/ExtensionKit","owner":"johnbean393","description":"A Swift package with additional functionality for Swift \u0026 SwiftUI.","archived":false,"fork":false,"pushed_at":"2024-07-11T04:46:24.000Z","size":24205,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-22T18:04:58.528Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnbean393.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-27T11:25:48.000Z","updated_at":"2025-02-23T12:43:36.000Z","dependencies_parsed_at":"2024-01-18T04:30:40.849Z","dependency_job_id":"6d38931e-6e20-408e-a24f-e0c0d46f02fe","html_url":"https://github.com/johnbean393/ExtensionKit","commit_stats":null,"previous_names":["johnbean393/pattoniumkit","johnbean393/extensionkit"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/johnbean393/ExtensionKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnbean393%2FExtensionKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnbean393%2FExtensionKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnbean393%2FExtensionKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnbean393%2FExtensionKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnbean393","download_url":"https://codeload.github.com/johnbean393/ExtensionKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnbean393%2FExtensionKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29041302,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T10:09:22.136Z","status":"ssl_error","status_checked_at":"2026-02-03T10:09:16.814Z","response_time":96,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T09:36:29.546Z","updated_at":"2026-02-03T10:31:30.269Z","avatar_url":"https://github.com/johnbean393.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ExtensionKit\n\n**ExtensionKit** is a Swift Package with additional functionality for Swift and SwiftUI.\n\n# Installation\n\nTo install **ExtensionKit**, simply add it as a dependency to your Swift project using the Swift Package Manager. I recommend using the Xcode method personally via:\n\n`File` → `Add Packages...` → `Search or Enter Package Url` → `https://github.com/johnbean393/ExtensionKit.git`\n\n# Usage(Non-exhaustive)\n\nTo use ExtensionKit in your project, first import the framework:\n```Swift\nimport ExtensionKit\n```\n\n### Array\n```Swift\n// Maps array in parallel\nfunc parallelMap\u003cT\u003e(_ transform: (Element) -\u003e T) -\u003e [T]\n```\n\n### Color\n```Swift\n// Get intermediate color\nfunc incrementColor(toColor: Color, percentage: Float) -\u003e Color\n\n// Example usage\nlet color: Color = Color.red.incrementColor(toColor: .green, percentage: 0.5) // Gives 50-50 mix between the colors red and green\n```\n\n### Date\n```Swift\n// Init date from date components\ninit(month: Int, day: Int, year: Int, hour: Int = 0, minute: Int = 0, second: Int = 0)\n```\n\n### Double\n```Swift\n// Add leading and trailing zeros\nfunc addZeros(wholeNumTarget: Int, fractionalTarget: Int) -\u003e String\n\n// Example usage\nlet price: Double = 9.9\nprint(price.addZeros(wholeNumTarget: 2)) // \"09.9\"\nprint(price.addZeros(wholeNumTarget: 2, fractionalTarget: 2)) // \"09.90\"\n```\n\n### Int\n```Swift\n// Add leading zeros\nfunc addLeadingZeros(target: Int = 2) -\u003e String\n\n// Example usage\nlet serialNum: Double = 9\nprint(serialNum.addLeadingZeros()) // 09\nprint(serialNum.addLeadingZeros(target: 3)) // \"009\"\n```\n\n### ProcessInfo\n```Swift\n// Get processor architecture\nvar machineHardwareName: String?\n\n// Example usage on Intel\nprint(ProcessInfo.processInfo.machineHardwareName!) // \"x86_64\"\n\n// Example usage on Apple Silicon\nprint(ProcessInfo.processInfo.machineHardwareName!) // \"arm64\"\n```\n\n### String\n```Swift\n// Check if string is number\nvar isNumber: Bool\n\n// Get lines in a string\nvar lines: [String]\n\n// Convert camel case to words\nfunc camelCaseToWords() -\u003e String\n\n// Example usage\nlet camelCase: String = \"ExtensionKitIsTheBest\"\nprint(camelCase.camelCaseToWords()) // \"Extension Kit Is The Best\"\n\n// Wildcard match\nfunc wildcard(pattern: String) -\u003e Bool\n\n// Example usage\nprint(\"201.93.92.123\".wildcard(pattern: \"201.93.9[23].???\")) // true\nprint(\"201.93.93.001\".wildcard(pattern: \"201.93.9[23].???\")) // true\nprint(\"docs.github.com\".wildcard(pattern: \"*.github.com\")) // true\n\n// Identify dominant language\nfunc strDominantLanguage() throws -\u003e String\n\n// Example usage\nprint(try? \"Hello, World\".strDominantLanguage()) // \"en\"\n```\n\n### URL\n```Swift\n// Get POSIX filepath\nfunc posixPath() -\u003e String\n\n// Example usage\nlet desktopUrl: URL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask)[0]\nprint(desktopUrl.posixPath()) // \"/Users/username/Desktop/\"\n\n// Check if directory contains item\nfunc containsItem(itemUrl: URL) -\u003e Bool\n\n// Example usage\nlet desktopUrl: URL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask)[0]\nlet item1Url: URL = desktopUrl.appendingPathComponent(\"test.txt\")\nlet item2Url: URL = desktopUrl.appendingPathComponent(\"New Folder\").appendingPathComponent(\"test.txt\")\nprint(desktopUrl.containsItem(itemUrl: item1Url)) // true\nprint(desktopUrl.containsItem(itemUrl: item2Url)) // true\n\n// List URLs of files in directory\nfunc listDirectory() throws -\u003e [URL]\n\n// Get last modified date of file\nfunc lastModifiedDate() throws -\u003e Date\n\n// Calculate size of directory in bits\nfunc directorySize() -\u003e Int64\n\n// Check if file exists\nfunc fileExists() -\u003e Bool\n```\n\n### View\n```Swift\n// Apply a modifier conditionally\n@ViewBuilder public func `if`\u003cContent: View\u003e(_ conditional: Bool, content: (Self) -\u003e Content) -\u003e some View\n\n// Example usage\nstruct ContentView: View {\n\t\n\t@State private var showBorder: Bool = false\n\t\n    var body: some View {\n        VStack {\n\t\t    Button(\"\\(!showBorder ? \"Show\" : \"Hide\") Border\") {\n\t\t        showBorder.toggle()\n\t\t    }\n\t\t    Circle()\n\t\t        .if(showBorder) { view in\n\t\t            view.border(Color.black)\n\t\t        }\n        }\n\t}\n\t\n}\n```\n\n### CliTools: Simple tools for the CLI (macOS only)\n```Swift\n// Run a command in the terminal\nfunc runCommand(command: String) -\u003e String\n\n// Example usage\nprint(runCommand(command: \"echo 'Hello, World!'\")) // \"Hello, World!\"\n\n// Relaunch app after 'n' seconds\nfunc relaunch(afterDelay seconds: TimeInterval = 5) -\u003e Never\n```\n\n### FileSystemTools: Simple tools to manipulate the file system\n```Swift\n// Example usage for FileSystemTools\nFileSystemTools.functionName(parameters)\n\n\n// Get \"~/Desktop/\" directory url (macOS only)\nfunc getDesktopUrl() -\u003e URL\n\n// Get \"~/Downloads/\" directory url\nfunc getDownloadsUrl() -\u003e URL\n\n// Get \"~/Documents/\" directory url\nfunc getDocumentsUrl() -\u003e URL\n\n// Get \"~/Library/Application Support/\" directory url\nfunc getAppSupportDirUrl() -\u003e URL\n\n// Open a panel for users to select a file (macOS only)\nfunc openPanel(url: URL, files: Bool, folders: Bool, dialogTitle: String) throws -\u003e URL\n\n// Create a new directory\nfunc createDirectory(url: URL)\n\n// List contents of a directory\nfunc listDirectory(dirUrl: URL) -\u003e [URL]\n\n// Open directory in Finder (macOS only)\nfunc openDirectory(url: URL)\n\n// Open window to AirDrop a file (macOS only)\nfunc airDropFiles(urls: [URL]) throws\n```\n\n### ProcessorTools: Quickly retrieve information about the processor\n```Swift\n// Example usage for ProcessorTools\nProcessorTools.functionName(parameters)\n\n// Check if processor if arm64\nfunc isArmProcessor() -\u003e Bool\n\n// Get processor core count\nfunc getCoreCount() -\u003e Int\n```\n\n### TextExtractor: Extract text from a file (macOS only)\n```Swift\n// Extract text from a file\n// Supported file formats include txt, rtf, csv, py, swift, doc, docx, docm, pages, pptx, pdf, png, jpg, bmp, jpeg, tiff, webp, heic, and any other file that uses UTF8 encoding\nfunc extractText(url: URL) async throws -\u003e String\n\n// Example usage\nlet text: String = try? await TextExtractor.extractText(url: URL(filePath: \"/Users/username/Desktop/test.txt\"))\nprint(text) // \"Text in file\" \n```\n\n### ValueDataModel: Make data models without the boilerplate code\n```Swift\n// Example usage for ValueDataModel\n\n\n//  Balloon.swift\n\nimport Foundation\nimport SwiftUI\nimport ExtensionKit\n\n// Custom struct that conforms to Identifiable, Codable and Equatable \nstruct Balloon: Identifiable, Codable, Equatable {\n\t\n\tvar id: UUID = UUID()\n\tvar size: BalloonSize\n\t\n\tstatic func random() -\u003e Balloon {\n\t\tlet size: BalloonSize = [.small, .medium, .large].randomElement()!\n\t\treturn Balloon(size: size)\n\t}\n\t\n}\n\nenum BalloonSize: String, CaseIterable, Codable {\n\tcase small, medium, large\n}\n\n\n//  BalloonData.swift\n\nimport Foundation\nimport ExtensionKit\n\n// Inherit data model boilerplate code from ValueDataModel\nclass BalloonData: ValueDataModel\u003cBalloon\u003e {\n\t\n\trequired init(appDirName: String = Bundle.main.applicationName ?? Bundle.main.description, datastoreName: String = \"\\(Bundle.main.applicationName ?? Bundle.main.description)Data\") {\n\t\tsuper.init(appDirName: appDirName, datastoreName: datastoreName)\n\t}\n\t\n\t// Add new static property\n\tstatic let shared: BalloonData = BalloonData(appDirName: \"ValueDataModel Test\", datastoreName: \"valueDataModelTest\")\n\t\n\t// Add new method\n\tfunc deleteRandom() {\n\t\tif !values.isEmpty {\n\t\t\tprint(0..\u003cvalues.count)\n\t\t\tlet randIndex: Int = Int.random(in: 0..\u003cvalues.count)\n\t\t\tlet _ = values.remove(at: randIndex)\n\t\t}\n\t}\n\t\n}\n\n\n//  ValueDataModel_DemoApp.swift\n\nimport SwiftUI\n\n@main\nstruct ValueDataModel_DemoApp: App {\n\t\n\t// Use the object in your app\n\t@StateObject private var balloonData: BalloonData = BalloonData()\n\t\n    var body: some Scene {\n        WindowGroup {\n\t\t\tContentView()\n\t\t\t\t.environmentObject(balloonData)\n        }\n    }\n}\n\n\n//  ContentView.swift\n\nimport SwiftUI\n\nstruct ContentView: View {\n\t\n\t@EnvironmentObject var balloonData: BalloonData\n\t\n    var body: some View {\n\t\tVStack(alignment: .leading) {\n\t\t\tButton(\"Add Balloon\") {\n\t\t\t\twithAnimation(.spring()) {\n\t\t\t\t\tballoonData.add(Balloon.random())\n\t\t\t\t}\n\t\t\t}\n\t\t\tButton(\"Pop a Balloon\") {\n\t\t\t\twithAnimation(.spring()) {\n\t\t\t\t\tballoonData.deleteRandom()\n\t\t\t\t}\n\t\t\t}\n\t\t\tForEach(balloonData.values) { balloon in\n\t\t\t\tBalloonView(balloon: balloon)\n\t\t\t}\n\t\t}\n    }\n}\n\n#Preview {\n    ContentView()\n}\n// \n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnbean393%2Fextensionkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnbean393%2Fextensionkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnbean393%2Fextensionkit/lists"}