e5a83843db
Add resilient usage analytics, OOBE gateway flows, clipboard semantic ranking, purchase recovery, style learning, and managed current-information search.
717 lines
28 KiB
YAML
717 lines
28 KiB
YAML
# XcodeGen configuration for OSGKeyboard
|
||
# Run `./Scripts/generate-xcodeproj.sh` to create OSGKeyboard.xcodeproj.
|
||
# App home-screen icon: OSGKeyboard/AppIcon.icon (Icon Composer, iOS 26).
|
||
# Repo only tracks project.yml; .xcodeproj is gitignored.
|
||
|
||
name: OSGKeyboard
|
||
options:
|
||
bundleIdPrefix: com.osgkeyboard
|
||
# XcodeGen 2.37+ emits AppIcon.icon as folder.iconcomposer.icon natively.
|
||
# Older XcodeGen releases may need Scripts/patch-icon-composer.sh (fallback).
|
||
# Minimum OS: iOS 26. We dropped older iOS support so the
|
||
# legacy speech + AVAudioSession branching could be removed in
|
||
# favour of iOS 26's `SpeechAnalyzer` (always on-device) and
|
||
# `AVAudioApplication.requestRecordPermission` (iOS 17+). iPhone + iPad;
|
||
# no Mac Catalyst, no visionOS.
|
||
deploymentTarget:
|
||
iOS: "26.0"
|
||
developmentLanguage: en
|
||
createIntermediateGroups: true
|
||
generateEmptyDirectories: true
|
||
groupSortPosition: top
|
||
|
||
# iOS local ASR uses iOS 26 `SpeechAnalyzer` + `DictationTranscriber`.
|
||
# The shared iOS framework links librime for Chinese typing. Optional
|
||
# post-ASR polish and AI mode use the user-selected LLM provider.
|
||
# macOS local ASR links mlx-audio-swift (ThirdParty/) for Qwen3 MLX
|
||
# streaming; model weights are installed through the bundled catalog.
|
||
|
||
packages:
|
||
MLXAudio:
|
||
path: ThirdParty/mlx-audio-swift
|
||
Librime:
|
||
url: https://github.com/ghostflyby/librime-xcframework.git
|
||
exactVersion: 1.17.0-pack.1
|
||
|
||
settings:
|
||
base:
|
||
SWIFT_VERSION: "6.0"
|
||
IPHONEOS_DEPLOYMENT_TARGET: "26.0"
|
||
ENABLE_USER_SCRIPT_SANDBOXING: YES
|
||
SWIFT_STRICT_CONCURRENCY: complete
|
||
GENERATE_INFOPLIST_FILE: NO
|
||
ENABLE_MODULE_VERIFIER: YES
|
||
MODULE_VERIFIER_SUPPORTED_LANGUAGES: "objective-c objective-c++"
|
||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS: "gnu17 gnu++17"
|
||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED: YES
|
||
ASSETCATALOG_COMPILER_GENERATE_ASSET_SYMBOLS: YES
|
||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS: YES
|
||
STRING_CATALOG_GENERATE_SYMBOLS: YES
|
||
CLANG_CXX_LANGUAGE_STANDARD: c++17
|
||
MARKETING_VERSION: "2.0.1"
|
||
CURRENT_PROJECT_VERSION: "87"
|
||
# 签名配置来自 Signing.local.xcconfig(gitignored,不会被覆盖)
|
||
|
||
# 项目级签名 xcconfig,适用于所有 target
|
||
configFiles:
|
||
Debug: Signing.local.xcconfig
|
||
Release: Signing.local.xcconfig
|
||
|
||
targets:
|
||
|
||
# =========================================================
|
||
# 主 App
|
||
# =========================================================
|
||
OSGKeyboard:
|
||
type: application
|
||
platform: iOS
|
||
sources:
|
||
- path: OSGKeyboard/AppIcon.icon
|
||
buildPhase: resources
|
||
- path: OSGKeyboard
|
||
excludes:
|
||
- "AppIcon.icon"
|
||
- "OSGKeyboard.icon"
|
||
# Legacy PNG app icons must not coexist with AppIcon.icon — actool
|
||
# crashes when both are passed. iOS 26 uses Icon Composer only.
|
||
- "Assets.xcassets/AppIcon.appiconset"
|
||
- "Resources/CustomLanguageModel/**"
|
||
- "Resources/Shortcuts/**"
|
||
# Real keyboard chrome for DEBUG what's-new recording (same UI as Ext).
|
||
- path: OSGKeyboardExt/Utilities/ExtL10n.swift
|
||
- path: OSGKeyboardExt/Views/AIKeyboardView.swift
|
||
- path: OSGKeyboardExt/Views/LastInputEditView.swift
|
||
- path: OSGKeyboardExt/Views/KeyboardTopControls.swift
|
||
- path: OSGKeyboardExt/Views/ClipboardKeyboardViews.swift
|
||
- path: OSGKeyboardExt/Views/ToolbarActionButtons.swift
|
||
- path: OSGKeyboardExt/Views/GlobeInputModeButton.swift
|
||
- path: OSGKeyboardExt/Views/NativeKeyboardKeyStyle.swift
|
||
- path: OSGKeyboardExt/Utilities/KeyboardHapticFeedback.swift
|
||
- path: OSGKeyboardExt/Utilities/KeyboardSoundFeedback.swift
|
||
- path: OSGKeyboardExt/en.lproj/Keyboard.strings
|
||
buildPhase: resources
|
||
- path: OSGKeyboardExt/zh-Hans.lproj/Keyboard.strings
|
||
buildPhase: resources
|
||
# `.shortcut` is not a XcodeGen-known resource type; list each file
|
||
# as an explicit resource source or it never lands in the app bundle.
|
||
- path: OSGKeyboard/Resources/Shortcuts/OSGExtractTodos.shortcut
|
||
type: file
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Shortcuts/OSGExtractEvents.shortcut
|
||
type: file
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Shortcuts/OSGSaveToNotes.shortcut
|
||
type: file
|
||
buildPhase: resources
|
||
entitlements:
|
||
path: OSGKeyboard/OSGKeyboard.entitlements
|
||
properties:
|
||
com.apple.security.application-groups:
|
||
- group.com.osgkeyboard.shared
|
||
com.apple.security.device.audio-input: true
|
||
# Shared Keychain access group: the host app writes the LLM API
|
||
# key here in Settings; the keyboard extension reads it before
|
||
# each request. The first entry below becomes each process's
|
||
# default access group, so the Keychain helper does not need to
|
||
# specify kSecAttrAccessGroup explicitly.
|
||
keychain-access-groups:
|
||
- $(AppIdentifierPrefix)com.osgkeyboard.shared
|
||
# Host-only account sessions use this second group explicitly.
|
||
# The keyboard extension is intentionally not entitled to it.
|
||
- $(AppIdentifierPrefix)com.osgkeyboard.ios
|
||
com.apple.developer.applesignin:
|
||
- Default
|
||
com.apple.developer.devicecheck.appattest-environment: $(APP_ATTEST_ENVIRONMENT)
|
||
com.apple.developer.associated-domains:
|
||
- applinks:osglab.com
|
||
# iCloud Key-Value Store — personal dictionary sync across
|
||
# iPhone / iPad / Mac (Designed for iPad). Main app only.
|
||
# NOTE: this entitlement is a single STRING, not an array — an
|
||
# array value never matches the profile and breaks automatic
|
||
# signing ("doesn't match the entitlements file's value").
|
||
com.apple.developer.ubiquity-kvstore-identifier: $(TeamIdentifierPrefix)com.osgkeyboard.ios
|
||
resources:
|
||
- path: OSGKeyboard/Assets.xcassets
|
||
- path: OSGKeyboard/en.lproj
|
||
- path: OSGKeyboard/zh-Hans.lproj
|
||
- path: OSGKeyboard/Resources/Fonts/MaterialIcons-Regular.ttf
|
||
- path: OSGKeyboard/Resources/PrivacyPolicy.html
|
||
- path: OSGKeyboard/PrivacyInfo.xcprivacy
|
||
# Host-only heavy assets — keep out of the keyboard extension Shared framework.
|
||
# CLM uses a unique iOS-only path (`HostCLM/`): XcodeGen dedupes identical
|
||
# file paths across iOS/Mac, which previously left the iOS app without CLM.
|
||
- path: OSGKeyboard/Resources/Typing/Rime/osg_pinyin.dict.yaml
|
||
- path: OSGKeyboard/Resources/Typing/Rime/manifest.json
|
||
- path: OSGKeyboard/Resources/HostCLM/v1/OSGKeyboardCLM.bin
|
||
- path: OSGKeyboard/Resources/HostCLM/v1/compiled-manifest.json
|
||
- path: OSGKeyboard/Resources/LocalASR/local-asr-catalog.json
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/NOTICE.txt
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE.txt
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-PINYIN-SIMP-APACHE.txt
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-MATERIAL-ICONS-APACHE.txt
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-JIEBA-MIT.txt
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-PHRASE-PINYIN-DATA-MIT.txt
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-PINYIN-DATA-MIT.txt
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-NORVIG-PD.txt
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/THIRD_PARTY_NOTICES.md
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/third-party-notices.zip
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LIBRIME-COMBINED-NOTICES.txt
|
||
info:
|
||
path: OSGKeyboard/Info.plist
|
||
properties:
|
||
CFBundleDisplayName: OSGKeyboard
|
||
CFBundleShortVersionString: "$(MARKETING_VERSION)"
|
||
CFBundleVersion: "$(CURRENT_PROJECT_VERSION)"
|
||
LSApplicationCategoryType: public.app-category.utilities
|
||
# English is the development language; zh-Hans is the only
|
||
# translation right now. The list also tells iOS to surface
|
||
# the keyboard in the per-app language picker for both.
|
||
CFBundleDevelopmentRegion: en
|
||
CFBundleLocalizations:
|
||
- en
|
||
- zh-Hans
|
||
UILaunchScreen:
|
||
UIColorName: "BackgroundColor"
|
||
UISupportedInterfaceOrientations:
|
||
- UIInterfaceOrientationPortrait
|
||
UISupportedInterfaceOrientations~ipad:
|
||
- UIInterfaceOrientationPortrait
|
||
- UIInterfaceOrientationPortraitUpsideDown
|
||
- UIInterfaceOrientationLandscapeLeft
|
||
- UIInterfaceOrientationLandscapeRight
|
||
UIApplicationSceneManifest:
|
||
UIApplicationSupportsMultipleScenes: false
|
||
NSMicrophoneUsageDescription: "OSGKeyboard uses the microphone for voice dictation, including active Flow sessions while you type in other apps."
|
||
NSSpeechRecognitionUsageDescription: "OSGKeyboard uses speech recognition to transcribe your voice. Audio is processed on-device by default, or sent to your configured speech provider only when you enable cloud recognition."
|
||
UIBackgroundModes:
|
||
- audio
|
||
BGTaskSchedulerPermittedIdentifiers:
|
||
- com.osgkeyboard.ios.analytics-sync
|
||
NSAppTransportSecurity:
|
||
NSAllowsArbitraryLoads: false
|
||
ITSAppUsesNonExemptEncryption: false
|
||
# StoreKit 2 can return finished consumable credit purchases in
|
||
# Transaction.all so the account center can show purchase history.
|
||
SKIncludeConsumableInAppPurchaseHistory: true
|
||
# Runtime-resolved, team-prefixed group used by the host-private
|
||
# account Keychain store. Never copy this key to the extension plist.
|
||
OSGPrivateKeychainAccessGroup: $(AppIdentifierPrefix)com.osgkeyboard.ios
|
||
CFBundleURLTypes:
|
||
- CFBundleURLName: com.osgkeyboard.ios.settings
|
||
CFBundleURLSchemes:
|
||
- osgkeyboard
|
||
LSApplicationQueriesSchemes:
|
||
- weixin
|
||
- mqq
|
||
- wxwork
|
||
- dingtalk
|
||
- lark
|
||
- tg
|
||
- whatsapp
|
||
- line
|
||
- fb-messenger
|
||
- slack
|
||
- msteams
|
||
- discord
|
||
- notion
|
||
- bear
|
||
- obsidian
|
||
- drafts5
|
||
- googlegmail
|
||
- ms-outlook
|
||
- googlechrome
|
||
- sinaweibo
|
||
- xhsdiscover
|
||
- sgnl
|
||
- kakaotalk
|
||
- viber
|
||
- zalo
|
||
- skype
|
||
- zoomus
|
||
- shortcuts
|
||
- iosamap
|
||
- amapuri
|
||
- baidumap
|
||
- maps
|
||
- things
|
||
- todoist
|
||
- evernote
|
||
- onenote
|
||
- readdle-spark
|
||
- firefox
|
||
- microsoft-edge
|
||
- fb
|
||
- instagram
|
||
- twitter
|
||
- barcelona
|
||
- snapchat
|
||
- reddit
|
||
- pinterest
|
||
- zhihu
|
||
- bilibili
|
||
- snssdk1128
|
||
- tiktok
|
||
# All network calls are HTTPS (NSAppTransportSecurity above);
|
||
# nothing in the app uses non-exempt encryption. Declaring
|
||
# `ITSAppUsesNonExemptEncryption: false` lets us skip the
|
||
# annual self-classification questionnaire in App Store
|
||
# Connect on every upload.
|
||
ITSAppUsesNonExemptEncryption: false
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.ios
|
||
TARGETED_DEVICE_FAMILY: "1,2"
|
||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents: YES
|
||
INFOPLIST_KEY_LSApplicationCategoryType: public.app-category.utilities
|
||
SUPPORTS_MACCATALYST: NO
|
||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: NO
|
||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD: NO
|
||
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
||
# TestFlight upload: Automatic signing picks the right App Store profile.
|
||
CODE_SIGN_STYLE: Automatic
|
||
DEVELOPMENT_TEAM: X329MZU23S
|
||
configs:
|
||
Debug:
|
||
APP_ATTEST_ENVIRONMENT: development
|
||
Release:
|
||
APP_ATTEST_ENVIRONMENT: production
|
||
dependencies:
|
||
- target: OSGKeyboardShared
|
||
embed: true
|
||
- target: OSGKeyboardHostSupport
|
||
embed: true
|
||
- target: OSGKeyboardExt
|
||
# Keyboard Extension is a plugin of the main App; embed it.
|
||
embed: true
|
||
buildPhase: embedAppExtensions
|
||
- sdk: Speech.framework
|
||
- sdk: StoreKit.framework
|
||
|
||
# =========================================================
|
||
# Keyboard Extension
|
||
# =========================================================
|
||
OSGKeyboardExt:
|
||
type: app-extension
|
||
platform: iOS
|
||
sources:
|
||
- path: OSGKeyboardExt
|
||
excludes:
|
||
- "en.lproj"
|
||
- "zh-Hans.lproj"
|
||
- path: OSGKeyboardExt/en.lproj/Keyboard.strings
|
||
buildPhase: resources
|
||
- path: OSGKeyboardExt/zh-Hans.lproj/Keyboard.strings
|
||
buildPhase: resources
|
||
resources:
|
||
- path: OSGKeyboardExt/Assets.xcassets
|
||
- path: OSGKeyboardExt/PrivacyInfo.xcprivacy
|
||
settings:
|
||
base:
|
||
IPHONEOS_DEPLOYMENT_TARGET: "26.0"
|
||
entitlements:
|
||
path: OSGKeyboardExt/OSGKeyboardExt.entitlements
|
||
properties:
|
||
com.apple.security.application-groups:
|
||
- group.com.osgkeyboard.shared
|
||
# Shared with the host app so the keyboard extension can read the
|
||
# user's LLM API key. See OSGKeyboard/OSGKeyboard.entitlements
|
||
# for the full rationale.
|
||
keychain-access-groups:
|
||
- $(AppIdentifierPrefix)com.osgkeyboard.shared
|
||
info:
|
||
path: OSGKeyboardExt/Info.plist
|
||
properties:
|
||
CFBundleDisplayName: OSGKeyboard
|
||
CFBundleShortVersionString: "$(MARKETING_VERSION)"
|
||
CFBundleVersion: "$(CURRENT_PROJECT_VERSION)"
|
||
CFBundleDevelopmentRegion: en
|
||
CFBundleLocalizations:
|
||
- en
|
||
- zh-Hans
|
||
NSMicrophoneUsageDescription: "OSGKeyboard uses the microphone for voice dictation, including active Flow sessions while you type in other apps."
|
||
NSSpeechRecognitionUsageDescription: "OSGKeyboard uses speech recognition to transcribe your voice. Audio is processed on-device by default, or sent to your configured speech provider only when you enable cloud recognition."
|
||
NSExtension:
|
||
NSExtensionAttributes:
|
||
IsASCIICapable: false
|
||
PrefersRightToLeft: false
|
||
PrimaryLanguage: "mis"
|
||
RequestsOpenAccess: true
|
||
NSExtensionPointIdentifier: com.apple.keyboard-service
|
||
NSExtensionPrincipalClass: $(PRODUCT_MODULE_NAME).KeyboardViewController
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.ios.keyboard
|
||
TARGETED_DEVICE_FAMILY: "1,2"
|
||
SUPPORTS_MACCATALYST: NO
|
||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: NO
|
||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD: NO
|
||
# TestFlight upload: Automatic signing picks the right App Store profile.
|
||
CODE_SIGN_STYLE: Automatic
|
||
DEVELOPMENT_TEAM: X329MZU23S
|
||
dependencies:
|
||
- target: OSGKeyboardShared
|
||
embed: false
|
||
|
||
# Shared Framework (主 App 与扩展共用)
|
||
# =========================================================
|
||
OSGKeyboardShared:
|
||
type: framework
|
||
platform: iOS
|
||
sources:
|
||
- path: OSGKeyboardShared
|
||
excludes:
|
||
- "en.lproj"
|
||
- "zh-Hans.lproj"
|
||
- "**/*.swift.example"
|
||
- "Resources/**"
|
||
- "PrivacyInfo.xcprivacy"
|
||
- path: OSGKeyboardShared/en.lproj/Shared.strings
|
||
buildPhase: resources
|
||
- path: OSGKeyboardShared/zh-Hans.lproj/Shared.strings
|
||
buildPhase: resources
|
||
# Privacy manifest required for LevelDB statically linked via librime
|
||
# (ITMS-91061). Must live in this framework bundle, not only the app/ext.
|
||
- path: OSGKeyboardShared/PrivacyInfo.xcprivacy
|
||
buildPhase: resources
|
||
# Prefer sources+buildPhase over target-level `resources:` — the latter
|
||
# was not emitting Copy Bundle Resources entries for this framework.
|
||
- path: OSGKeyboardShared/Resources/Typing/English/english_lexicon.bin
|
||
buildPhase: resources
|
||
- path: OSGKeyboardShared/Resources/PolishStyles
|
||
buildPhase: resources
|
||
- path: OSGKeyboardShared/Resources/ClipboardSemantics
|
||
buildPhase: resources
|
||
- path: OSGRimeBridge
|
||
excludes:
|
||
- "include/**"
|
||
info:
|
||
path: OSGKeyboardShared/Info.plist
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.ios.shared
|
||
TARGETED_DEVICE_FAMILY: "1,2"
|
||
DEFINES_MODULE: YES
|
||
SKIP_INSTALL: YES
|
||
BUILD_LIBRARY_FOR_DISTRIBUTION: NO
|
||
DYLIB_INSTALL_NAME_BASE: "@rpath"
|
||
APPLICATION_EXTENSION_API_ONLY: YES
|
||
SWIFT_OBJC_BRIDGING_HEADER: OSGRimeBridge/include/OSGRimeBridge.h
|
||
CLANG_ENABLE_MODULES: YES
|
||
OTHER_CPLUSPLUSFLAGS: "$(inherited) -fmodules -fcxx-modules"
|
||
ENABLE_MODULE_VERIFIER: YES
|
||
# Embedded frameworks are re-signed by the containing app at package
|
||
# time. Signing this framework as a standalone build product is noisy
|
||
# and not recommended by Xcode.
|
||
CODE_SIGNING_ALLOWED: NO
|
||
CODE_SIGNING_REQUIRED: NO
|
||
CODE_SIGN_IDENTITY: ""
|
||
dependencies:
|
||
- package: Librime
|
||
product: RimeStatic
|
||
- sdk: libsqlite3.tbd
|
||
|
||
# Host-only support framework (ASR / CLM / Cloud / Charts / StoreKit).
|
||
# Keyboard extension does NOT link this — keeps Speech/AVFoundation/Charts
|
||
# out of the extension jetsam budget.
|
||
OSGKeyboardHostSupport:
|
||
type: framework
|
||
platform: iOS
|
||
sources:
|
||
- path: OSGKeyboardHostSupport
|
||
info:
|
||
path: OSGKeyboardHostSupport/Info.plist
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.ios.hostsupport
|
||
TARGETED_DEVICE_FAMILY: "1,2"
|
||
DEFINES_MODULE: YES
|
||
SKIP_INSTALL: YES
|
||
BUILD_LIBRARY_FOR_DISTRIBUTION: NO
|
||
DYLIB_INSTALL_NAME_BASE: "@rpath"
|
||
APPLICATION_EXTENSION_API_ONLY: NO
|
||
ENABLE_MODULE_VERIFIER: YES
|
||
CODE_SIGNING_ALLOWED: NO
|
||
CODE_SIGNING_REQUIRED: NO
|
||
CODE_SIGN_IDENTITY: ""
|
||
dependencies:
|
||
- target: OSGKeyboardShared
|
||
embed: false
|
||
- sdk: Speech.framework
|
||
- sdk: AVFoundation.framework
|
||
- sdk: Charts.framework
|
||
- sdk: StoreKit.framework
|
||
|
||
# =========================================================
|
||
# 单元测试
|
||
# =========================================================
|
||
OSGKeyboardTests:
|
||
type: bundle.unit-test
|
||
platform: iOS
|
||
sources:
|
||
- path: OSGKeyboardTests
|
||
- path: Tests/ProviderToolRequestCoordinatorTests.swift
|
||
info:
|
||
path: OSGKeyboardTests/Info.plist
|
||
dependencies:
|
||
- target: OSGKeyboard
|
||
- target: OSGKeyboardHostSupport
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.ios.tests
|
||
TARGETED_DEVICE_FAMILY: "1,2"
|
||
|
||
# =========================================================
|
||
# 键盘扩展单元测试 (TEST-4)
|
||
# =========================================================
|
||
OSGKeyboardExtTests:
|
||
type: bundle.unit-test
|
||
platform: iOS
|
||
sources:
|
||
- path: OSGKeyboardExtTests
|
||
- path: OSGKeyboardExt/Services/EditHintScheduler.swift
|
||
- path: OSGKeyboardExt/Services/ClipboardCaptureCoordinator.swift
|
||
# Host-only dict fixture for librime deploy tests (not linked into Ext).
|
||
- path: OSGKeyboard/Resources/Typing/Rime/osg_pinyin.dict.yaml
|
||
buildPhase: resources
|
||
info:
|
||
path: OSGKeyboardExtTests/Info.plist
|
||
dependencies:
|
||
- target: OSGKeyboardShared
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.ios.ext.tests
|
||
TARGETED_DEVICE_FAMILY: "1,2"
|
||
|
||
# =========================================================
|
||
# 实机 UI 测试
|
||
# =========================================================
|
||
# XCUITest 是 Apple 唯一开放的物理设备触摸注入通道,模拟器无法复现
|
||
# PiP 语音会话(isPictureInPictureSupported 恒为 false)。
|
||
OSGKeyboardUITests:
|
||
type: bundle.ui-testing
|
||
platform: iOS
|
||
sources:
|
||
- path: OSGKeyboardUITests
|
||
info:
|
||
path: OSGKeyboardUITests/Info.plist
|
||
dependencies:
|
||
- target: OSGKeyboard
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.ios.uitests
|
||
TARGETED_DEVICE_FAMILY: "1,2"
|
||
CODE_SIGN_STYLE: Automatic
|
||
DEVELOPMENT_TEAM: X329MZU23S
|
||
|
||
# =========================================================
|
||
# macOS 单元测试
|
||
# =========================================================
|
||
# Hosted in the Mac app so `@testable import OSGKeyboard` reaches the
|
||
# macOS-only types (MacAudioRecorder, overlay sizing) that cannot compile
|
||
# against the iOS targets.
|
||
OSGKeyboardMacTests:
|
||
type: bundle.unit-test
|
||
platform: macOS
|
||
deploymentTarget: "15.0"
|
||
sources:
|
||
- path: OSGKeyboardMacTests
|
||
- path: Tests/ProviderToolRequestCoordinatorTests.swift
|
||
info:
|
||
path: OSGKeyboardMacTests/Info.plist
|
||
dependencies:
|
||
- target: OSGKeyboardMac
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.mac.tests
|
||
MACOSX_DEPLOYMENT_TARGET: "15.0"
|
||
CODE_SIGN_STYLE: Automatic
|
||
DEVELOPMENT_TEAM: X329MZU23S
|
||
# The host target is named OSGKeyboardMac but ships as OSGKeyboard.app,
|
||
# so the path XcodeGen infers from the target name does not exist.
|
||
TEST_HOST: "$(BUILT_PRODUCTS_DIR)/OSGKeyboard.app/Contents/MacOS/OSGKeyboard"
|
||
BUNDLE_LOADER: "$(TEST_HOST)"
|
||
|
||
# =========================================================
|
||
# macOS 菜单栏 App
|
||
# =========================================================
|
||
# Standalone menu-bar utility: record → local/cloud ASR → polish → insert.
|
||
# Reuses the platform-agnostic core files from OSGKeyboardShared at the
|
||
# source level (no framework), excluding the iOS-only files that import
|
||
# SpeechAnalyzer / AVAudioSession / UIKit / SwiftUI views. Local mode uses
|
||
# Qwen3 MLX streaming via mlx-audio-swift plus catalog-managed weights.
|
||
OSGKeyboardMac:
|
||
type: application
|
||
platform: macOS
|
||
deploymentTarget: "15.0"
|
||
sources:
|
||
# Same Icon Composer asset as the iOS app — do not ship a separate PNG
|
||
# appiconset; actool crashes if both coexist.
|
||
- path: OSGKeyboard/AppIcon.icon
|
||
buildPhase: resources
|
||
# Reuse the iOS asset catalog for provider logos + brand mark. Exclude
|
||
# the PNG appiconset so it doesn't clash with AppIcon.icon above.
|
||
- path: OSGKeyboard/Assets.xcassets
|
||
excludes:
|
||
- "AppIcon.appiconset"
|
||
- path: OSGKeyboardMac
|
||
- path: OSGKeyboard/Services/OpenSourceLicenseCatalog.swift
|
||
- path: OSGKeyboardHostSupport
|
||
excludes:
|
||
# iOS SpeechAnalyzer / AVAudioSession capture — Mac has its own paths.
|
||
- "Services/ASRService.swift"
|
||
- "Services/CloudASR/CloudASRService.swift"
|
||
- "Services/FlowAudioSessionCoordinator.swift"
|
||
- "Services/FlowCaptureVoiceProcessing.swift"
|
||
- "Services/FlowContinuousCapture.swift"
|
||
- "Services/LiveDictationController.swift"
|
||
- "Models/AudioBufferSnapshot+AVFoundation.swift"
|
||
- "Info.plist"
|
||
- path: OSGKeyboardShared
|
||
excludes:
|
||
- "en.lproj"
|
||
- "zh-Hans.lproj"
|
||
- "Info.plist"
|
||
- "**/*.swift.example"
|
||
- "Resources/**"
|
||
- "DesignSystem/WaveformView.swift"
|
||
- "DesignSystem/RecordButton.swift"
|
||
- "DesignSystem/RecordButtonGesturePolicy.swift"
|
||
- "Services/KeyboardState.swift"
|
||
- "Services/KeyboardOpenSurfacePolicy.swift"
|
||
- "Models/MicVoiceAvailability+Keyboard.swift"
|
||
- "Models/TypingInputConfiguration.swift"
|
||
- "Models/TypingSurfaceMetrics.swift"
|
||
- "Typing/**"
|
||
- "Utilities/ProgressiveDictationTranscriptAccumulator.swift"
|
||
- path: OSGKeyboardShared/en.lproj/Shared.strings
|
||
buildPhase: resources
|
||
- path: OSGKeyboardShared/zh-Hans.lproj/Shared.strings
|
||
buildPhase: resources
|
||
- path: OSGKeyboardShared/Resources/PolishStyles
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/CustomLanguageModel/v1/phrases.tsv
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/CustomLanguageModel/v1/OSGKeyboardCLM.bin
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/CustomLanguageModel/v1/compiled-manifest.json
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/PrivacyPolicy.html
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/LocalASR/local-asr-catalog.json
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LIBRIME-COMBINED-NOTICES.txt
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-PINYIN-SIMP-APACHE.txt
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-MATERIAL-ICONS-APACHE.txt
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-JIEBA-MIT.txt
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-PHRASE-PINYIN-DATA-MIT.txt
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-PINYIN-DATA-MIT.txt
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE-NORVIG-PD.txt
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/LICENSE.txt
|
||
buildPhase: resources
|
||
- path: OSGKeyboard/Resources/Typing/Licenses/NOTICE.txt
|
||
buildPhase: resources
|
||
entitlements:
|
||
path: OSGKeyboardMac/OSGKeyboardMac.entitlements
|
||
properties:
|
||
# Sandbox disabled on purpose: this menu-bar dictation utility uses the
|
||
# Accessibility API to monitor a global hotkey and inject ⌘V into other
|
||
# apps — both are forbidden by App Sandbox. Ship via Developer ID +
|
||
# notarization (not Mac App Store / TestFlight, which force the sandbox).
|
||
com.apple.security.app-sandbox: false
|
||
com.apple.security.device.audio-input: true
|
||
com.apple.security.network.client: true
|
||
com.apple.developer.ubiquity-kvstore-identifier: $(TeamIdentifierPrefix)com.osgkeyboard.ios
|
||
keychain-access-groups:
|
||
- $(AppIdentifierPrefix)com.osgkeyboard.shared
|
||
info:
|
||
path: OSGKeyboardMac/Info.plist
|
||
properties:
|
||
CFBundleDisplayName: OSGKeyboard
|
||
CFBundleShortVersionString: "$(MARKETING_VERSION)"
|
||
CFBundleVersion: "$(CURRENT_PROJECT_VERSION)"
|
||
CFBundleDevelopmentRegion: en
|
||
CFBundleLocalizations:
|
||
- en
|
||
- zh-Hans
|
||
LSApplicationCategoryType: public.app-category.utilities
|
||
NSMicrophoneUsageDescription: "OSGKeyboard uses the microphone to transcribe your voice via your configured cloud speech provider."
|
||
NSSpeechRecognitionUsageDescription: "OSGKeyboard uses on-device speech recognition for local dictation mode."
|
||
NSHumanReadableCopyright: "OSGKeyboard"
|
||
ITSAppUsesNonExemptEncryption: false
|
||
CFBundleURLTypes:
|
||
- CFBundleURLName: com.osgkeyboard.mac.seed
|
||
CFBundleURLSchemes:
|
||
- osgkeyboard
|
||
settings:
|
||
base:
|
||
PRODUCT_NAME: OSGKeyboard
|
||
INFOPLIST_KEY_CFBundleDisplayName: OSGKeyboard
|
||
INFOPLIST_KEY_CFBundleName: OSGKeyboard
|
||
PRODUCT_BUNDLE_IDENTIFIER: com.osgkeyboard.mac
|
||
MACOSX_DEPLOYMENT_TARGET: "15.0"
|
||
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
||
# macOS app is not an app extension; override the framework-wide flag.
|
||
APPLICATION_EXTENSION_API_ONLY: NO
|
||
CODE_SIGN_STYLE: Automatic
|
||
DEVELOPMENT_TEAM: X329MZU23S
|
||
# Required for Developer ID distribution + notarization (outside App Store).
|
||
ENABLE_HARDENED_RUNTIME: YES
|
||
dependencies:
|
||
- package: MLXAudio
|
||
product: MLXAudioSTT
|
||
- sdk: Speech.framework
|
||
- sdk: AVFoundation.framework
|
||
- sdk: Charts.framework
|
||
- sdk: StoreKit.framework
|
||
- sdk: libsqlite3.tbd
|
||
|
||
schemes:
|
||
OSGKeyboard:
|
||
build:
|
||
targets:
|
||
OSGKeyboard: all
|
||
OSGKeyboardExt: all
|
||
run:
|
||
config: Debug
|
||
storeKitConfiguration: OSGKeyboard.storekit
|
||
test:
|
||
config: Debug
|
||
targets:
|
||
- OSGKeyboardTests
|
||
- OSGKeyboardExtTests
|
||
archive:
|
||
config: Release
|
||
|
||
# Device-only reproduction harness; kept out of the main scheme so CI and
|
||
# Scripts/run-tests.sh keep running unit tests without a physical device.
|
||
OSGKeyboardUITests:
|
||
build:
|
||
targets:
|
||
OSGKeyboard: all
|
||
OSGKeyboardExt: all
|
||
OSGKeyboardUITests: [test]
|
||
test:
|
||
config: Debug
|
||
targets:
|
||
- OSGKeyboardUITests
|
||
|
||
OSGKeyboardMac:
|
||
build:
|
||
targets:
|
||
OSGKeyboardMac: all
|
||
run:
|
||
config: Debug
|
||
test:
|
||
config: Debug
|
||
targets:
|
||
- OSGKeyboardMacTests
|
||
archive:
|
||
config: Release
|