{"id":23388240,"url":"https://github.com/jaywcjlove/myapplistkit","last_synced_at":"2026-03-01T13:16:07.284Z","repository":{"id":264904376,"uuid":"894633938","full_name":"jaywcjlove/MyAppListKit","owner":"jaywcjlove","description":"Encapsulation of My Personal App List","archived":false,"fork":false,"pushed_at":"2025-04-02T15:04:06.000Z","size":59,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-03T11:28:12.053Z","etag":null,"topics":["ios","ios-swift","macos","swift","swift-package","swift-package-manager"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaywcjlove.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"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},"funding":{"ko_fi":"jaywcjlove","buy_me_a_coffee":"jaywcjlove","custom":["https://www.paypal.me/kennyiseeyou","https://jaywcjlove.github.io/#/sponsor"]}},"created_at":"2024-11-26T17:47:06.000Z","updated_at":"2025-04-03T09:12:54.000Z","dependencies_parsed_at":"2024-12-14T12:25:49.428Z","dependency_job_id":"8294ed88-c5f5-407a-b86d-6b5f625434a3","html_url":"https://github.com/jaywcjlove/MyAppListKit","commit_stats":null,"previous_names":["jaywcjlove/myapplistkit"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaywcjlove%2FMyAppListKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaywcjlove%2FMyAppListKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaywcjlove%2FMyAppListKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaywcjlove%2FMyAppListKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaywcjlove","download_url":"https://codeload.github.com/jaywcjlove/MyAppListKit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247848133,"owners_count":21006199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["ios","ios-swift","macos","swift","swift-package","swift-package-manager"],"created_at":"2024-12-22T02:18:21.066Z","updated_at":"2025-12-29T19:30:43.524Z","avatar_url":"https://github.com/jaywcjlove.png","language":"Swift","funding_links":["https://ko-fi.com/jaywcjlove","https://buymeacoffee.com/jaywcjlove","https://www.paypal.me/kennyiseeyou","https://jaywcjlove.github.io/#/sponsor"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"left\"\u003e\n\u003ca href=\"./README-zh.md\"\u003e简体中文\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cdiv markdown=\"1\"\u003e\n  \u003csup\u003eUsing \u003ca href=\"https://wangchujiang.com/#/app\" target=\"_blank\"\u003emy app\u003c/a\u003e is also a way to \u003ca href=\"https://wangchujiang.com/#/sponsor\" target=\"_blank\"\u003esupport\u003c/a\u003e me:\u003c/sup\u003e\n  \u003cbr\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/Deskmark/6755948110\" title=\"Deskmark for macOS\"\u003e\u003cimg alt=\"Deskmark\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/deskmark.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/Keyzer/6500434773\" title=\"Keyzer for macOS\"\u003e\u003cimg alt=\"Keyzer\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/keyzer.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://github.com/jaywcjlove/vidwall-hub\" title=\"Vidwall Hub for macOS\"\u003e\u003cimg alt=\"Vidwall Hub\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/vidwall-hub.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/VidCrop/6752624705\" title=\"VidCrop for macOS\"\u003e\u003cimg alt=\"VidCrop\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/vidcrop.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/Vidwall/6747587746\" title=\"Vidwall for macOS\"\u003e\u003cimg alt=\"Vidwall\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/vidwall.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://wangchujiang.com/mousio-hint/\" title=\"Mousio Hint for macOS\"\u003e\u003cimg alt=\"Mousio Hint\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/mousio-hint.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6746747327\" title=\"Mousio for macOS\"\u003e\u003cimg alt=\"Mousio\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/mousio.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6745227444\" title=\"Musicer for macOS\"\u003e\u003cimg alt=\"Musicer\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/musicer.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6743841447\" title=\"Audioer for macOS\"\u003e\u003cimg alt=\"Audioer\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/audioer.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6744690194\" title=\"FileSentinel for macOS\"\u003e\u003cimg alt=\"FileSentinel\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/file-sentinel.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6743495172\" title=\"FocusCursor for macOS\"\u003e\u003cimg alt=\"FocusCursor\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/focus-cursor.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6742680573\" title=\"Videoer for macOS\"\u003e\u003cimg alt=\"Videoer\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/videoer.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6740425504\" title=\"KeyClicker for macOS\"\u003e\u003cimg alt=\"KeyClicker\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/key-clicker.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6739052447\" title=\"DayBar for macOS\"\u003e\u003cimg alt=\"DayBar\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/daybar.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6739444407\" title=\"Iconed for macOS\"\u003e\u003cimg alt=\"Iconed\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/iconed.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6737160756\" title=\"Mousio for macOS\"\u003e\u003cimg alt=\"Mousio\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/rightmenu-master.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6723903021\" title=\"Paste Quick for macOS\"\u003e\u003cimg alt=\"Quick RSS\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/paste-quick.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6670696072\" title=\"Quick RSS for macOS/iOS\"\u003e\u003cimg alt=\"Quick RSS\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/quick-rss.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6670167443\" title=\"Web Serve for macOS\"\u003e\u003cimg alt=\"Web Serve\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/web-serve.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6503953628\" title=\"Copybook Generator for macOS/iOS\"\u003e\u003cimg alt=\"Copybook Generator\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/copybook-generator.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6471227008\" title=\"DevTutor for macOS/iOS\"\u003e\u003cimg alt=\"DevTutor for SwiftUI\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/devtutor.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6479819388\" title=\"RegexMate for macOS/iOS\"\u003e\u003cimg alt=\"RegexMate\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/regex-mate.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6479194014\" title=\"Time Passage for macOS/iOS\"\u003e\u003cimg alt=\"Time Passage\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/time-passage.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6478772538\" title=\"IconizeFolder for macOS\"\u003e\u003cimg alt=\"Iconize Folder\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/iconize-folder.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6478511402\" title=\"Textsound Saver for macOS/iOS\"\u003e\u003cimg alt=\"Textsound Saver\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/textsound-saver.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6476924627\" title=\"Create Custom Symbols for macOS\"\u003e\u003cimg alt=\"Create Custom Symbols\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/create-custom-symbols.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6476452351\" title=\"DevHub for macOS\"\u003e\u003cimg alt=\"DevHub\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/devhub.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6476400184\" title=\"Resume Revise for macOS\"\u003e\u003cimg alt=\"Resume Revise\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/resume-revise.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6472593276\" title=\"Palette Genius for macOS\"\u003e\u003cimg alt=\"Palette Genius\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/palette-genius.png\"\u003e\u003c/a\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/6470879005\" title=\"Symbol Scribe for macOS\"\u003e\u003cimg alt=\"Symbol Scribe\" height=\"52\" width=\"52\" src=\"https://wangchujiang.com/appicon/symbol-scribe.png\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n\u003chr\u003e\n\n\nMyAppListKit\n===\n\nEncapsulation of My Personal App List\n\nWelcome to download [DevTutor](https://apps.apple.com/app/devtutor/id6471227008), a cheat sheet app designed to help developers quickly build excellent applications using SwiftUI.\n\n\u003cp\u003e\n  \u003ca target=\"_blank\" href=\"https://apps.apple.com/app/devtutor/id6471227008\" title=\"DevTutor for SwiftUI AppStore\"\u003e\u003cimg alt=\"DevTutor for SwiftUI AppStore\" src=\"https://jaywcjlove.github.io/sb/download/macos.svg\" height=\"51\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Installation\n\nYou can add MyAppListKit to an Xcode project by adding it as a package dependency.\n\n1. From the File menu, select Add Packages…\n2. Enter https://github.com/jaywcjlove/MyAppListKit in the Search or Enter Package URL search field\n3. Link `MyAppListKit` to your application target\n\nOr add the following to `Package.swift`:\n\n```swift\n.package(url: \"https://github.com/jaywcjlove/MyAppListKit\", branch: \"main\")\n```\n\nOr [add the package in Xcode](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app).\n\n## Usage\n\n```swift\nimport MyAppListKit\n    \nList {\n    ForEach(MyAppList.apps(), id: \\.appId) { app in\n        Button(app.name, action: {\n            app.openApp()\n            // or\n            MyAppList.openApp(appId: app.appId, appstoreId: app.appstoreId)\n        })\n    }\n}\n\nButton(\"More Apps by Me\") {\n    MyAppList.openURL(url: URL(string: MyAppList.appsByMe)!)\n    // or\n    MyAppList.openAppsByMe()\n}\n\nMyAppList.appDevHub           // -\u003e AppData\nMyAppList.appDevHub.storeURL  // -\u003e URL: macappstore://apps.apple.com/app/id6476452351\nMyAppList.appDevHub.appStoreWriteReview  \n// -\u003e URL: macappstore://apps.apple.com/app/id6476452351?action=write-review\nMyAppList.appDevHub.openURL() // Open in browser\nMyAppList.appDevHub.openWriteReviewURL() // Open WriteReview in browser\nMyAppList.appDevHub.openApp() // Open the app or its store download page\nMyAppList.appDevHub.openWriteReviewURL() // Open the app or its store download page\n```\n\nReturns the URL of the default app associated with the given bundle identifier.\n\n```\nMyAppList.appDevHub.appURL()\n```\n\nChecks if the app is installed\n\n```swift\nMyAppList.isAppInstalled(appId: \"com.wangchujiang.daybar\")\n```\n\nGet app icon\n\n```swift\nMyAppList.getAppIcon() // Get the app's App Store icon\n// Get icon using bundleIdentifier (if app is installed locally)\nMyAppList.getAppIcon(forId: \"com.wangchujiang.vidwall\") \n// Get icon using bundleIdentifier; if not found locally, fallback to App Store icon\nMyAppList.getAppIcon(forId: \"com.wangchujiang.vidwall\", defaultAppStore: true) \n// Get icon using bundleIdentifier; if not found locally, \n// fetch from App Store using appstoreId\nMyAppList.getAppIcon(forId: \"com.wangchujiang.vidwall\", appstoreId: \"6747587746\") \n// Fetch icon directly from App Store using the app's ID\nMyAppList.fetchAppIconFromAppStore(appId: \"6747587746\") \n```\n\n## Example Command Menu\n\n```swift\nimport SwiftUI\nimport MyAppListKit\n\nextension Locale {\n    /// Get the system's preferred language Locale, ignoring the app's region settings\n    /// This ensures that the MyAppListKit component always uses \n    /// the system language instead of the app's region settings\n    static var systemPreferred: Locale {\n        Locale(identifier: Locale.preferredLanguages.first ?? \"en\")\n    }\n}\n\nstruct CommandMenus: Commands {\n    var body: some Commands {\n        CommandMenu(String.localized(key: \"more_tools\", locale: Locale.systemPreferred)) {\n            MoreAppsView().environment(\\.locale, Locale.systemPreferred)\n        }\n        CommandGroup(replacing: .systemServices) {}\n        CommandGroup(after: CommandGroupPlacement.appInfo) {\n            Divider()\n            MyAppCheckForUpdatesView(app: MyAppList.appIconizeFolder)\n                .environment(\\.locale, Locale.systemPreferred)\n            Divider()\n            CommandGroupView()\n        }\n        CommandGroup(replacing: CommandGroupPlacement.help) {\n            MyAppCheckForUpdatesView(app: MyAppList.appIconizeFolder)\n                .environment(\\.locale, Locale.systemPreferred)\n            Divider()\n            CommandGroupView()\n        }\n    }\n}\n\nstruct CommandGroupView: View {\n    var body: some View {\n        Group {\n            ButtonWebsite(app: MyAppList.appIconizeFolder)\n            ButtonRateApp(app: MyAppList.appIconizeFolder)\n            ButtonSendFeedback(app: MyAppList.appIconizeFolder)\n            \n            MoreAppsMenuView()\n            \n            Divider()\n            CommandAppButton(app: MyAppList.appIconed)\n            CommandAppButton(app: MyAppList.appCreateCustomSymbols)\n            CommandAppButton(app: MyAppList.appPaletteGenius)\n            CommandAppButton(app: MyAppList.appDevHub)\n            Divider()\n        }\n        .environment(\\.locale, Locale.systemPreferred)\n    }\n}\n\nstruct CommandAppButton: View {\n    let app: MyAppList.AppData\n    var body: some View {\n        Button(action: {\n            app.openApp()\n        }, label: {\n            HStack {\n                MoreAppsIcon(appId: app.appId, appstoreId: app.appstoreId)\n                let text: String = \" - \"\n                Text(app.name) +\n                Text(text).foregroundStyle(Color.secondary) +\n                Text(String.localized(key: desc ?? \"\", locale: Locale.systemPreferred))\n                    .foregroundStyle(Color.secondary).font(.system(size: 10))\n            }\n        })\n    }\n}\n```\n\n## MyAppCheckForUpdatesView\n\n```swift\nimport MyAppListKit\n\nstruct ContentView: View {\n    var body: some View {\n        MyAppCheckForUpdatesView(app: MyAppList.appIconed)\n                    \n        MyAppCheckForUpdatesView(app: MyAppList.appIconed) { label in\n            HStack {\n                Text(label)\n                Spacer()\n                Image(systemName: \"chevron.right\")\n            }\n        }\n        .frame(maxWidth: .infinity)\n        .buttonStyle(.link)\n    }\n}\n```\n\n## MoreAppsView\n\nDisplay My Apps on the Menu.\n\n```swift\nstruct CommandMenus: Commands {\n    var body: some Commands {\n        //CommandMenu(\"More Tools\") {\n        //    MoreAppsView()\n        //}\n        MoreAppsCommandMenus()\n        MoreAppsCommandMenus() {\n            Group {\n                // ....\n            }\n        }\n        CommandGroup(replacing: CommandGroupPlacement.help) {\n            MoreAppsMenuView()\n        }\n    }\n}\n```\n\n## ButtonRateApp \u0026 ButtonSendFeedback\n\nA button that guides users to rate or review the app on the App Store. When clicked, it opens the “Write a Review” page for the current app.\n\n```swift\nstruct CommandMenus: Commands {\n    var body: some Commands {\n        CommandGroup(replacing: CommandGroupPlacement.help) {\n            ButtonWebsite(app: MyAppList.appRegexMate)\n            ButtonRateApp(app: MyAppList.appRegexMate)\n            Divider()\n            ButtonSendFeedback(app: MyAppList.appRegexMate)\n        }\n    }\n}\n```\n\n\n## MoreAppsCommandMenus\n\n```swift\nimport MyAppListKit\n\n@main\nstruct IconizeFolderApp: App {\n    var body: some Scene {\n        return Window(\"\", id: \"MainWindow\") {\n            ContentView()\n        }\n        .commands {\n            MoreAppsCommandMenus()\n        }\n    }\n\n}\n```\n\n## My Apps List\n\n```swift\nlet locale: Locale = Locale(identifier: Locale.preferredLanguages.first ?? \"en\")\n\nForEach(MyAppList.apps(), id: \\.appId) { app in\n    Button(action: {\n        MyAppList.openApp(appId: app.appId, appstoreId: app.appstoreId)\n    }, label: {\n        Label(title: {\n            VStack(alignment: .leading) {\n                Text(app.name).font(.system(size: 12))\n                    .multilineTextAlignment(.leading)\n                if let desc = app.desc {\n                    Text(String.localized(key: desc, locale: locale))\n                        .lineLimit(nil)\n                        .fixedSize(horizontal: false, vertical: true)\n                        .foregroundStyle(Color.secondary)\n                        .font(.system(size: 10))\n                        .multilineTextAlignment(.leading)\n                        .lineSpacing(0)\n                        .frame(maxWidth: .infinity, alignment: .leading)\n                }\n            }\n            .frame(maxWidth: .infinity, alignment: .leading)\n        }, icon: {\n            MoreAppsIcon(appId: app.appId, appstoreId: app.appstoreId)\n        })\n    })\n    .buttonStyle(.link)\n}\n```\n\n## License\n\nLicensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaywcjlove%2Fmyapplistkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaywcjlove%2Fmyapplistkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaywcjlove%2Fmyapplistkit/lists"}