The iOS packaging script wrote project.yml into the repo root with `name: MiniPlayer` and ran xcodegen there, regenerating MiniPlayer.xcodeproj as an iOS-only project and destroying the macOS target. Generate into an isolated dir (.build-ios/xcodegen) under a distinct project name (MiniPlayerIOS), reference packages/sources by absolute path so they resolve from the nested location, and archive that project instead. The macOS project is never touched. Also wire Assets.xcassets into the iOS target for the app icon.
184 lines
5.6 KiB
Bash
Executable File
184 lines
5.6 KiB
Bash
Executable File
#!/bin/bash
|
||
# ========================================
|
||
# MiniPlayer iOS 打包脚本
|
||
# 生成 .ipa (需要签名配置)
|
||
# ========================================
|
||
set -e
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||
PARENT_DIR="$(cd "$PROJECT_DIR/.." && pwd)"
|
||
APP_NAME="MiniPlayer"
|
||
VERSION=$(date +%Y.%m.%d)
|
||
BUILD_DIR="$PROJECT_DIR/.build-ios"
|
||
|
||
# 签名配置
|
||
TEAM_ID="${IOS_TEAM_ID:-LR8YT5M53U}"
|
||
BUNDLE_ID="com.miniplayer.ios"
|
||
PROVISIONING_PROFILE="${IOS_PROVISIONING_PROFILE:-}" # 留空用 automatic signing
|
||
EXPORT_METHOD="development" # development / ad-hoc / app-store
|
||
|
||
echo "=== MiniPlayer iOS 打包 ==="
|
||
echo "项目目录: $PROJECT_DIR"
|
||
echo "版本: $VERSION"
|
||
echo "Team ID: $TEAM_ID"
|
||
|
||
# 1. 生成 Xcode 项目
|
||
echo ""
|
||
echo "--- Step 1: 生成 Xcode 项目 ---"
|
||
|
||
# 关键:iOS 工程生成到一个独立目录 + 独立工程名,
|
||
# 绝不在仓库根目录运行 xcodegen —— 否则会以 name: MiniPlayer
|
||
# 覆盖 macOS 的 MiniPlayer.xcodeproj,破坏 macOS target。
|
||
IOS_GEN_DIR="$BUILD_DIR/xcodegen"
|
||
mkdir -p "$IOS_GEN_DIR"
|
||
cat > "$IOS_GEN_DIR/project.yml" << EOF
|
||
name: MiniPlayerIOS
|
||
options:
|
||
bundleIdPrefix: com.miniplayer
|
||
deploymentTarget:
|
||
iOS: "17.0"
|
||
xcodeVersion: "15.0"
|
||
generateEmptyDirectories: true
|
||
|
||
packages:
|
||
SwiftBricks:
|
||
path: $PARENT_DIR/swiftbricks
|
||
StreamRecorder:
|
||
path: $PARENT_DIR/StreamRecorder
|
||
|
||
targets:
|
||
MiniPlayerIOS:
|
||
type: application
|
||
platform: iOS
|
||
sources:
|
||
- path: $PROJECT_DIR/Sources
|
||
excludes:
|
||
- "**/PlayerRecorder.swift"
|
||
- path: $PROJECT_DIR/Assets.xcassets
|
||
buildPhase: resources
|
||
dependencies:
|
||
- package: SwiftBricks
|
||
- package: StreamRecorder
|
||
product: StreamRecorderKit
|
||
settings:
|
||
base:
|
||
PRODUCT_BUNDLE_IDENTIFIER: $BUNDLE_ID
|
||
MARKETING_VERSION: $VERSION
|
||
CURRENT_PROJECT_VERSION: 1
|
||
INFOPLIST_KEY_CFBundleDisplayName: "MiniPlayer"
|
||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation: true
|
||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents: true
|
||
INFOPLIST_KEY_UILaunchScreen_Generation: true
|
||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad: "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"
|
||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone: "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"
|
||
SWIFT_VERSION: "5.9"
|
||
CODE_SIGN_STYLE: Automatic
|
||
DEVELOPMENT_TEAM: $TEAM_ID
|
||
GENERATE_INFOPLIST_FILE: YES
|
||
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
||
resources:
|
||
- path: $PROJECT_DIR/Sources/Resources
|
||
EOF
|
||
|
||
if command -v xcodegen &> /dev/null; then
|
||
(cd "$IOS_GEN_DIR" && xcodegen generate)
|
||
echo " ✓ Xcode 项目生成成功: $IOS_GEN_DIR/MiniPlayerIOS.xcodeproj"
|
||
else
|
||
echo " ⚠ xcodegen 未安装,使用 xcodebuild + SPM 模式"
|
||
rm -f "$IOS_GEN_DIR/project.yml"
|
||
fi
|
||
|
||
# 2. Archive
|
||
echo ""
|
||
echo "--- Step 2: Archive ---"
|
||
|
||
if [ -f "$IOS_GEN_DIR/MiniPlayerIOS.xcodeproj/project.pbxproj" ]; then
|
||
# 使用独立目录里生成的 iOS 工程(不会触碰 macOS 工程)
|
||
SCHEME="MiniPlayerIOS"
|
||
PROJECT_FLAG="-project $IOS_GEN_DIR/MiniPlayerIOS.xcodeproj"
|
||
else
|
||
# 使用 SPM 自动生成的项目
|
||
SCHEME="MiniPlayeriOS"
|
||
PROJECT_FLAG=""
|
||
fi
|
||
|
||
ARCHIVE_PATH="$BUILD_DIR/$APP_NAME.xcarchive"
|
||
mkdir -p "$BUILD_DIR"
|
||
|
||
xcodebuild archive \
|
||
$PROJECT_FLAG \
|
||
-scheme "$SCHEME" \
|
||
-destination "generic/platform=iOS" \
|
||
-archivePath "$ARCHIVE_PATH" \
|
||
-allowProvisioningUpdates \
|
||
2>&1 | tail -30
|
||
|
||
ARCHIVE_EXIT=${PIPESTATUS[0]}
|
||
|
||
if [ $ARCHIVE_EXIT -ne 0 ]; then
|
||
echo " ✗ Archive 失败 (exit code: $ARCHIVE_EXIT)"
|
||
echo " 提示: 确保 Team ID 和签名配置正确"
|
||
exit 1
|
||
fi
|
||
|
||
echo " ✓ Archive 完成"
|
||
|
||
# 3. Export .ipa
|
||
echo ""
|
||
echo "--- Step 3: 导出 .ipa ---"
|
||
|
||
# 生成 ExportOptions.plist
|
||
cat > "$BUILD_DIR/ExportOptions.plist" << EOF
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>method</key>
|
||
<string>$EXPORT_METHOD</string>
|
||
<key>teamID</key>
|
||
<string>$TEAM_ID</string>
|
||
<key>compileBitcode</key>
|
||
<false/>
|
||
<key>stripSwiftSymbols</key>
|
||
<true/>
|
||
<key>thinning</key>
|
||
<string><none></string>
|
||
</dict>
|
||
</plist>
|
||
EOF
|
||
|
||
IPA_OUTPUT="$BUILD_DIR/ipa"
|
||
mkdir -p "$IPA_OUTPUT"
|
||
|
||
xcodebuild -exportArchive \
|
||
-archivePath "$ARCHIVE_PATH" \
|
||
-exportPath "$IPA_OUTPUT" \
|
||
-exportOptionsPlist "$BUILD_DIR/ExportOptions.plist" \
|
||
-allowProvisioningUpdates \
|
||
2>&1 | tail -10
|
||
|
||
IPA_FILE=$(find "$IPA_OUTPUT" -name "*.ipa" -type f | head -1)
|
||
|
||
if [ -n "$IPA_FILE" ]; then
|
||
# 复制到项目根目录(Finder/Xcode Add App 弹窗可见)
|
||
cp "$IPA_FILE" "$PROJECT_DIR/$APP_NAME.ipa"
|
||
echo ""
|
||
echo "=============================="
|
||
echo " iOS 打包完成!"
|
||
echo "=============================="
|
||
echo " .ipa: $PROJECT_DIR/$APP_NAME.ipa"
|
||
echo " 大小: $(du -h "$PROJECT_DIR/$APP_NAME.ipa" | cut -f1)"
|
||
echo ""
|
||
echo " 安装方式:"
|
||
echo " - Xcode: Window > Devices > Add App → 选择项目根目录下的 .ipa"
|
||
echo " - AltStore / SideStore: 直接导入 .ipa"
|
||
echo " - TestFlight: 使用 app-store 签名方式"
|
||
else
|
||
echo " ✗ .ipa 导出失败"
|
||
echo " 提示: 检查签名配置和 ExportOptions.plist"
|
||
fi
|
||
|
||
# 清理临时文件(只清理独立生成目录,不触碰仓库根目录)
|
||
rm -f "$IOS_GEN_DIR/project.yml"
|