https://github.com/jaywcjlove/MyAppListKit
Encapsulation of My Personal App List
https://github.com/jaywcjlove/MyAppListKit
ios ios-swift jaywcjlove macos swift swift-app swift-package swift-package-manager swiftui swiftui-app swiftui-application
Last synced: 6 days ago
JSON representation
Encapsulation of My Personal App List
- Host: GitHub
- URL: https://github.com/jaywcjlove/MyAppListKit
- Owner: jaywcjlove
- License: mit
- Created: 2024-11-26T17:47:06.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2026-05-29T08:57:18.000Z (about 1 month ago)
- Last Synced: 2026-05-29T10:24:06.582Z (about 1 month ago)
- Topics: ios, ios-swift, jaywcjlove, macos, swift, swift-app, swift-package, swift-package-manager, swiftui, swiftui-app, swiftui-application
- Language: Swift
- Homepage:
- Size: 185 KB
- Stars: 13
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README-zh.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- awesome-swift - MyAppListKit - Package for loading and using the author's app list data. (Utilities and Extensions)
README
MyAppListKit
===
[](https://jaywcjlove.github.io/#/sponsor)
[](https://x.com/jaywcjlove)

[](https://x.com/jaywcjlove)
用于展示应用列表、打开 App Store 链接、发送反馈和获取应用图标的 SwiftUI 工具。个人应用数据已拆分到可选的 `MyAppListKitApps` product。
欢迎下载 [DevTutor](https://jaywcjlove.github.io/maslink/?id=6471227008&platform=mac),这是一款旨在帮助开发者快速使用 SwiftUI 构建出色应用的速查手册应用。
## 安装
你可以将 MyAppListKit 添加到 Xcode 项目中,作为一个包依赖。
1. 在 Xcode 的菜单栏中选择「File > Add Packages…」
2. 在「Search or Enter Package URL」字段中输入:
`https://github.com/jaywcjlove/MyAppListKit`
3. 将 `MyAppListKit` 链接到你的应用目标(Target)
4. 如果需要使用内置的个人应用列表,同时链接 `MyAppListKitApps`
或者在你的 `Package.swift` 文件中添加以下内容:
```swift
.package(url: "https://github.com/jaywcjlove/MyAppListKit", branch: "main")
```
也可以参考 [Xcode 添加依赖包的官方文档](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app)。
## 使用方法
```swift
import MyAppListKit
import MyAppListKitApps
List {
// 遍历我的应用列表
ForEach(MyAppListApps.apps(), id: \.appId) { app in
Button(app.name, action: {
app.openApp() // 打开应用(如果已安装)
// 或者使用静态方法打开应用(根据 appId 或 App Store ID)
MyAppList.openApp(appId: app.appId, appstoreId: app.appstoreId)
})
}
}
// 显示“更多我的应用”按钮
Button("More Apps by Me") {
MyAppList.openURL(url: URL(string: MyAppListApps.appsByMe)!) // 打开我的所有应用页面(自定义 URL)
// 或使用封装的方法打开
MyAppListApps.openAppsByMe()
}
// 获取一个应用(如 DevHub)相关的信息和操作方法
MyAppListApps.appDevHub // -> AppData 实例,包含应用信息
MyAppListApps.appDevHub.storeURL // -> 应用在 App Store 的链接(URL 类型)
// 例如:macappstore://apps.apple.com/app/id6476452351
MyAppListApps.appDevHub.appStoreWriteReview // -> App Store 评论链接
// 例如:macappstore://apps.apple.com/app/id6476452351?action=write-review
MyAppListApps.appDevHub.openURL() // 在浏览器中打开应用页面
MyAppListApps.appDevHub.openWriteReviewURL() // 在浏览器中打开写评论页面
MyAppListApps.appDevHub.openApp() // 打开本地应用,或跳转到 App Store 下载页面
MyAppListApps.appDevHub.openWriteReviewURL() // 同上,主要用于引导用户写评论
```
返回与指定 Bundle Identifier 关联的默认应用的 URL。
```swift
MyAppListApps.appDevHub.appURL()
```
## 迁移说明
个人应用数据已从 `MyAppListKit` 移动到可选的 `MyAppListKitApps` product。
1. 对使用内置个人应用列表的 target 增加 `MyAppListKitApps` 依赖。
2. 在代码中增加 `import MyAppListKitApps`。
3. 将 `MyAppList.appDevHub`、`MyAppList.allApps`、`MyAppList.apps()`、`MyAppList.appsByMe`、`MyAppList.openAppsByMe()` 替换为对应的 `MyAppListApps.*` API。
4. 可复用视图需要显式传入数据:`MoreAppsView(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)`、`MoreAppsMenuView(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)` 或 `MoreAppsCommandMenus(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)`。
`MyAppListKit` 现在保持通用。如果你维护自己的应用列表,继续使用 `MyAppList.AppData`,并把自己的 `[MyAppList.AppData]` 传给这些视图即可。
检查应用是否已安装。
```swift
MyAppList.isAppInstalled(appId: "com.wangchujiang.vidwall")
```
获取应用图标
```swift
MyAppList.getAppIcon() // 获取应用商店图标
// 通过 bundleIdentifier 获取图标(如果本地安装了应用)
MyAppList.getAppIcon(forId: "com.wangchujiang.vidwall")
// 通过 bundleIdentifier 获取图标,如果本地不存在,则返回 App Store 图标
MyAppList.getAppIcon(forId: "com.wangchujiang.vidwall", defaultAppStore: true)
// 通过 bundleIdentifier 获取图标,如果本地不存在,则根据 appstoreId 从 App Store 获取图标
MyAppList.getAppIcon(forId: "com.wangchujiang.vidwall", appstoreId: "6747587746")
// 直接通过 App Store 的应用 ID 获取图标
MyAppList.fetchAppIconFromAppStore(appId: "6747587746")
```
本地化字符串的区域设置
```swift
String.localized("Confirm \"\(data.title)\" data", locale: "zh")
String.localized("Confirm Deletion", locale: "zh")
String.localized("Confirm Deletion", locale: Locale(identifier: "zh"))
```
获取依赖包本地国际化字符串
```swift
String.localized(key: "my_other_apps", locale: "zh")
```
## 示例菜单
```swift
import SwiftUI
import MyAppListKit
import MyAppListKitApps
extension Locale {
/// 获取系统首选语言的 Locale,忽略应用的区域设置
/// 这用于确保 MyAppListKit 组件始终使用系统语言而不是应用区域设置
static var systemPreferred: Locale {
Locale(identifier: Locale.preferredLanguages.first ?? "en")
}
}
struct CommandMenus: Commands {
var body: some Commands {
CommandMenu(String.localized(key: "more_tools", locale: Locale.systemPreferred)) {
MoreAppsView(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)
.environment(\.locale, Locale.systemPreferred)
}
CommandGroup(replacing: .systemServices) {}
CommandGroup(after: CommandGroupPlacement.appInfo) {
Divider()
MyAppCheckForUpdatesView(app: MyAppListApps.appIconizeFolder)
.environment(\.locale, Locale.systemPreferred)
Divider()
CommandGroupView()
}
CommandGroup(replacing: CommandGroupPlacement.help) {
MyAppCheckForUpdatesView(app: MyAppListApps.appIconizeFolder)
.environment(\.locale, Locale.systemPreferred)
Divider()
CommandGroupView()
}
}
}
struct CommandGroupView: View {
var body: some View {
Group {
ButtonWebsite(app: MyAppListApps.appIconizeFolder)
ButtonRateApp(app: MyAppListApps.appIconizeFolder)
ButtonSendFeedback(app: MyAppListApps.appIconizeFolder)
MoreAppsMenuView(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)
Divider()
CommandAppButton(app: MyAppListApps.appIconed)
CommandAppButton(app: MyAppListApps.appCreateCustomSymbols)
CommandAppButton(app: MyAppListApps.appPaletteGenius)
CommandAppButton(app: MyAppListApps.appDevHub)
Divider()
}
.environment(\.locale, Locale.systemPreferred)
}
}
struct CommandAppButton: View {
let app: MyAppList.AppData
var body: some View {
Button(action: {
app.openApp()
}, label: {
HStack {
MoreAppsIcon(appId: app.appId, appstoreId: app.appstoreId)
let text: String = " - "
Text(app.name) +
Text(text).foregroundStyle(Color.secondary) +
Text(String.localized(key: app.desc ?? "", bundle: app.descBundle, locale: Locale.systemPreferred))
.foregroundStyle(Color.secondary).font(.system(size: 10))
}
})
}
}
```
## MyAppCheckForUpdatesView
```swift
import MyAppListKit
import MyAppListKitApps
struct ContentView: View {
var body: some View {
MyAppCheckForUpdatesView(app: MyAppListApps.appIconed)
MyAppCheckForUpdatesView(app: MyAppListApps.appIconed) { label in
HStack {
Text(label)
Spacer()
Image(systemName: "chevron.right")
}
}
.frame(maxWidth: .infinity)
.buttonStyle(.link)
}
}
```
## MoreAppsView
在菜单中显示我的应用。
```swift
struct CommandMenus: Commands {
var body: some Commands {
//CommandMenu("More Tools") {
// MoreAppsView(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)
//}
MoreAppsCommandMenus(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)
MoreAppsCommandMenus(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe) {
Group {
// ....
}
}
CommandGroup(replacing: CommandGroupPlacement.help) {
MoreAppsMenuView(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)
}
}
}
```
## ButtonRateApp & ButtonSendFeedback
用于引导用户前往 App Store 评分/评论应用的按钮。点击后会打开当前应用在 App Store 的“撰写评论”页面。
```swift
struct CommandMenus: Commands {
var body: some Commands {
CommandGroup(replacing: CommandGroupPlacement.help) {
ButtonWebsite(app: MyAppListApps.appRegexMate)
ButtonRateApp(app: MyAppListApps.appRegexMate)
Divider()
ButtonSendFeedback(app: MyAppListApps.appRegexMate)
}
}
}
```
## MoreAppsCommandMenus
```swift
import MyAppListKit
import MyAppListKitApps
@main
struct IconizeFolderApp: App {
var body: some Scene {
return Window("", id: "MainWindow") {
ContentView()
}
.commands {
MoreAppsCommandMenus(apps: MyAppListApps.apps(), appsByMeURL: MyAppListApps.appsByMe)
}
}
}
```
## 我的应用列表
```swift
let locale: Locale = Locale(identifier: Locale.preferredLanguages.first ?? "en")
ForEach(MyAppListApps.apps(), id: \.appId) { app in
Button(action: {
MyAppList.openApp(appId: app.appId, appstoreId: app.appstoreId)
}, label: {
Label(title: {
VStack(alignment: .leading) {
Text(app.name).font(.system(size: 12))
.multilineTextAlignment(.leading)
if let desc = app.desc {
Text(String.localized(key: desc, bundle: app.descBundle, locale: locale))
.lineLimit(nil)
.fixedSize(horizontal: false, vertical: true)
.foregroundStyle(Color.secondary)
.font(.system(size: 10))
.multilineTextAlignment(.leading)
.lineSpacing(0)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
}, icon: {
MoreAppsIcon(appId: app.appId, appstoreId: app.appstoreId)
})
})
.buttonStyle(.link)
}
```
## 许可证
本项目采用 MIT 许可证授权。