You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

181 lines
4.9 KiB

#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
DEFAULT_OUTPUT_DIR="$PROJECT_ROOT/build/ios_release"
OUTPUT_DIR="$DEFAULT_OUTPUT_DIR"
EXTRA_ARGS=()
# -------- 路径验证函数 --------
validate_output_path() {
local path="$1"
# 如果是文件路径(以 .ipa 结尾)
if [[ "$path" == *.ipa ]]; then
local dir="$(dirname "$path")"
# 检查目录是否可写
if [[ ! -w "$dir" ]] 2>/dev/null; then
# 尝试创建目录
if ! mkdir -p "$dir" 2>/dev/null; then
echo "❌ 错误: 无法创建输出目录: $dir" >&2
echo " 提示: 请使用可写的路径,例如: ~/Desktop/output.ipa 或 ./build/myapp.ipa" >&2
return 1
fi
fi
# 检查父目录是否可写
if [[ ! -w "$dir" ]]; then
echo "❌ 错误: 输出目录不可写: $dir" >&2
return 1
fi
else
# 如果是目录路径
if [[ ! -w "$(dirname "$path")" ]] 2>/dev/null && [[ "$path" != "$PROJECT_ROOT"* ]]; then
# 尝试创建目录
if ! mkdir -p "$path" 2>/dev/null; then
echo "❌ 错误: 无法创建输出目录: $path" >&2
echo " 提示: 请使用可写的路径,例如: ~/Desktop/ 或 ./build/" >&2
return 1
fi
fi
fi
return 0
}
# -------- 参数解析 --------
while [[ $# -gt 0 ]]; do
case "$1" in
--output=*)
OUTPUT_DIR="${1#*=}"
shift
;;
--output)
[[ $# -lt 2 ]] && { echo "❌ --output 需要路径"; exit 1; }
OUTPUT_DIR="$2"
shift 2
;;
*)
EXTRA_ARGS+=("$1")
shift
;;
esac
done
# -------- 环境检查 --------
command -v flutter >/dev/null 2>&1 || {
echo "❌ Flutter 未安装或未加入 PATH"
exit 1
}
xcodebuild -version >/dev/null 2>&1 || {
echo "❌ Xcode 未正确安装"
exit 1
}
echo "🧩 Flutter 版本:"
flutter --version
# 验证输出路径
if ! validate_output_path "$OUTPUT_DIR"; then
echo "⚠️ 使用默认输出目录: $DEFAULT_OUTPUT_DIR"
OUTPUT_DIR="$DEFAULT_OUTPUT_DIR"
fi
# 展开 ~ 和相对路径
OUTPUT_DIR="${OUTPUT_DIR/#\~/$HOME}"
if [[ "$OUTPUT_DIR" != /* ]]; then
OUTPUT_DIR="$PROJECT_ROOT/$OUTPUT_DIR"
fi
mkdir -p "$OUTPUT_DIR"
pushd "$PROJECT_ROOT" >/dev/null
echo "📦 清理旧构建..."
flutter clean
echo "🧹 清理 Flutter pub cache 中的 im_flutter_sdk..."
flutter pub cache clean im_flutter_sdk 2>/dev/null || true
flutter pub cache clean im_flutter_sdk_ios 2>/dev/null || true
echo " ✓ 已清理 im_flutter_sdk 相关缓存"
echo "📚 获取依赖..."
flutter pub get
echo "🧹 清理 iOS 依赖缓存..."
cd ios
if [[ -f "Podfile.lock" ]]; then
rm -f Podfile.lock
echo " ✓ 已删除 Podfile.lock"
fi
if [[ -d "Pods" ]]; then
rm -rf Pods
echo " ✓ 已删除 Pods 目录"
fi
if [[ -d ".symlinks" ]]; then
rm -rf .symlinks
echo " ✓ 已删除 .symlinks 目录"
fi
# 清理 Xcode DerivedData 中的相关缓存
if [[ -d "$HOME/Library/Developer/Xcode/DerivedData" ]]; then
find "$HOME/Library/Developer/Xcode/DerivedData" -name "*Runner*" -type d -exec rm -rf {} + 2>/dev/null || true
echo " ✓ 已清理 Xcode DerivedData"
fi
cd ..
echo "📦 重新安装 iOS Pods..."
cd ios
pod deintegrate 2>/dev/null || true
# 清理 CocoaPods 缓存中的 im_flutter_sdk_ios 和 HyphenateChat
pod cache clean im_flutter_sdk_ios --all 2>/dev/null || true
pod cache clean HyphenateChat --all 2>/dev/null || true
# 强制更新 pod 仓库(仅清理时执行一次)
if [[ ! -f ".pod_install_done" ]]; then
echo " 🔄 更新 CocoaPods 仓库..."
pod repo update 2>/dev/null || true
touch .pod_install_done
fi
pod install
cd ..
echo "🚀 开始构建 iOS IPA..."
if [[ ${#EXTRA_ARGS[@]} -gt 0 ]]; then
flutter build ipa --release "${EXTRA_ARGS[@]}"
else
flutter build ipa --release
fi
IPA_DIR="$PROJECT_ROOT/build/ios/ipa"
BUILT_IPA="$(ls -t "$IPA_DIR"/*.ipa 2>/dev/null | head -n 1)"
if [[ -z "$BUILT_IPA" ]]; then
echo "❌ 未找到 IPA,构建失败"
exit 1
fi
if [[ "$OUTPUT_DIR" == *.ipa ]]; then
TARGET_PATH="$OUTPUT_DIR"
# 确保父目录存在且可写
parent_dir="$(dirname "$TARGET_PATH")"
if ! mkdir -p "$parent_dir" 2>/dev/null || [[ ! -w "$parent_dir" ]]; then
echo "❌ 错误: 无法写入到: $TARGET_PATH" >&2
echo " 使用默认路径: $DEFAULT_OUTPUT_DIR/$(basename "$BUILT_IPA")" >&2
TARGET_PATH="$DEFAULT_OUTPUT_DIR/$(basename "$BUILT_IPA")"
mkdir -p "$(dirname "$TARGET_PATH")"
fi
else
TARGET_PATH="$OUTPUT_DIR/$(basename "$BUILT_IPA")"
# 确保目录存在且可写
if ! mkdir -p "$OUTPUT_DIR" 2>/dev/null || [[ ! -w "$OUTPUT_DIR" ]]; then
echo "❌ 错误: 无法写入到: $OUTPUT_DIR" >&2
echo " 使用默认路径: $DEFAULT_OUTPUT_DIR" >&2
TARGET_PATH="$DEFAULT_OUTPUT_DIR/$(basename "$BUILT_IPA")"
mkdir -p "$(dirname "$TARGET_PATH")"
fi
fi
cp "$BUILT_IPA" "$TARGET_PATH"
echo "✅ 构建完成:$TARGET_PATH"
popd >/dev/null