#!/bin/bash # iOS 12/13 兼容性检查脚本 # 用于验证项目是否正确配置以支持低版本 iOS echo "======================================" echo "iOS 12/13 兼容性检查" echo "======================================" echo "" PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" ERRORS=0 WARNINGS=0 # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # 检查函数 check_passed() { echo -e "${GREEN}✓${NC} $1" } check_failed() { echo -e "${RED}✗${NC} $1" ERRORS=$((ERRORS + 1)) } check_warning() { echo -e "${YELLOW}⚠${NC} $1" WARNINGS=$((WARNINGS + 1)) } echo "1. 检查代码中是否还有 Task 关键字(Swift Concurrency)..." if grep -r "Task\s*{" "$PROJECT_DIR/PlayBTopOn" --include="*.swift" 2>/dev/null | grep -v "//"; then check_failed "发现未处理的 Task 调用,这会在 iOS 15 以下崩溃" else check_passed "未发现 Task 调用" fi echo "" echo "2. 检查代码中是否有未保护的 async/await..." # 检查 async 函数,同时检查前一行是否有 @available 或 #if 保护 UNPROTECTED_ASYNC=0 while IFS= read -r file; do if [ -f "$file" ]; then # 使用 awk 检查每个 async 函数前是否有保护 UNPROTECTED=$(awk ' /func.*async/ { protected = 0 for (i = 1; i <= 3; i++) { line_num = NR - i if (line_num in lines) { if (lines[line_num] ~ /@available/ || lines[line_num] ~ /#if/) { protected = 1 break } } } if (!protected && !/\/\//) print NR": "$0 } { lines[NR] = $0 } ' "$file") if [ -n "$UNPROTECTED" ]; then UNPROTECTED_ASYNC=1 fi fi done < <(find "$PROJECT_DIR/PlayBTopOn" -name "*.swift" 2>/dev/null) if [ "$UNPROTECTED_ASYNC" -eq 1 ]; then check_warning "发现可能未保护的 async 函数(请手动确认)" else check_passed "所有 async 函数都已保护" fi echo "" echo "3. 检查 AppTrackingTransparency 导入是否使用条件编译..." # 检查 import AppTrackingTransparency 前面是否有 #if canImport UNPROTECTED_IMPORTS=0 while IFS= read -r file; do if [ -f "$file" ]; then UNPROTECTED=$(awk ' /^import AppTrackingTransparency/ { protected = 0 for (i = 1; i <= 2; i++) { line_num = NR - i if (line_num in lines) { if (lines[line_num] ~ /#if canImport/) { protected = 1 break } } } if (!protected) print FILENAME":"NR": "$0 } { lines[NR] = $0 } ' "$file") if [ -n "$UNPROTECTED" ]; then echo "$UNPROTECTED" UNPROTECTED_IMPORTS=1 fi fi done < <(find "$PROJECT_DIR/PlayBTopOn" -name "*.swift" 2>/dev/null) if [ "$UNPROTECTED_IMPORTS" -eq 1 ]; then check_failed "发现无条件导入 AppTrackingTransparency,应使用 #if canImport()" else check_passed "AppTrackingTransparency 导入已正确保护" fi echo "" echo "4. 检查 Podfile 的最低版本设置..." if [ -f "$PROJECT_DIR/Podfile" ]; then PLATFORM_VERSION=$(grep "platform :ios" "$PROJECT_DIR/Podfile" | grep -o "'[0-9.]*'" | tr -d "'") if [ -n "$PLATFORM_VERSION" ]; then MAJOR_VERSION=$(echo "$PLATFORM_VERSION" | cut -d. -f1) if [ "$MAJOR_VERSION" -le 12 ]; then check_passed "Podfile 最低版本: iOS $PLATFORM_VERSION" else check_warning "Podfile 最低版本较高: iOS $PLATFORM_VERSION,建议设置为 12.0" fi else check_warning "未在 Podfile 中找到 platform 版本设置" fi else check_warning "未找到 Podfile 文件" fi echo "" echo "5. 检查 Info.plist 配置..." if [ -f "$PROJECT_DIR/PlayBTopOn/Info.plist" ]; then check_passed "找到 Info.plist" # 检查是否有 NSUserTrackingUsageDescription(如果要在 iOS 14+ 请求 ATT) if grep -q "NSUserTrackingUsageDescription" "$PROJECT_DIR/PlayBTopOn/Info.plist"; then check_passed "已配置 NSUserTrackingUsageDescription" else check_warning "未配置 NSUserTrackingUsageDescription(如需在 iOS 14+ 请求追踪权限,需要添加此项)" fi else check_failed "未找到 Info.plist" fi echo "" echo "6. 检查项目配置文件..." if [ -f "$PROJECT_DIR/PlayBTopOn.xcodeproj/project.pbxproj" ]; then # 检查 Deployment Target DEPLOYMENT_TARGET=$(grep "IPHONEOS_DEPLOYMENT_TARGET" "$PROJECT_DIR/PlayBTopOn.xcodeproj/project.pbxproj" | head -1 | grep -o "[0-9.]*" | head -1) if [ -n "$DEPLOYMENT_TARGET" ]; then MAJOR=$(echo "$DEPLOYMENT_TARGET" | cut -d. -f1) if [ "$MAJOR" -le 12 ]; then check_passed "Deployment Target: iOS $DEPLOYMENT_TARGET" else check_warning "Deployment Target 较高: iOS $DEPLOYMENT_TARGET,建议设置为 12.0" fi fi # 检查 AppTrackingTransparency 是否存在(但无法确定是否为 Optional) if grep -q "AppTrackingTransparency" "$PROJECT_DIR/PlayBTopOn.xcodeproj/project.pbxproj"; then check_warning "项目中引用了 AppTrackingTransparency - 请手动确认在 Xcode 中设置为 Optional" else check_warning "项目中未显式链接 AppTrackingTransparency(可能是自动链接)- 请在 Xcode 中确认" fi else check_failed "未找到项目配置文件" fi echo "" echo "7. 检查其他可能导致崩溃的代码模式..." # 检查 @MainActor if grep -r "@MainActor" "$PROJECT_DIR/PlayBTopOn" --include="*.swift" 2>/dev/null | grep -v "//"; then check_warning "发现 @MainActor 注解(需要 iOS 15+),请确认已用 @available 保护" fi # 检查 AsyncStream if grep -r "AsyncStream" "$PROJECT_DIR/PlayBTopOn" --include="*.swift" 2>/dev/null | grep -v "//"; then check_warning "发现 AsyncStream(需要 iOS 15+),请确认已用 @available 保护" fi echo "" echo "======================================" echo "检查完成" echo "======================================" echo -e "错误: ${RED}$ERRORS${NC}" echo -e "警告: ${YELLOW}$WARNINGS${NC}" if [ $ERRORS -eq 0 ]; then echo "" echo -e "${GREEN}✓ 代码修改看起来没有问题!${NC}" echo "" echo "⚠️ 重要提醒:" echo "1. 请在 Xcode 中手动检查 AppTrackingTransparency.framework 是否设置为 Optional" echo " 路径: Build Phases -> Link Binary With Libraries -> AppTrackingTransparency.framework -> Status: Optional" echo "" echo "2. 在 iOS 12/13 真机或模拟器上测试,确保不会崩溃" echo "" echo "详细配置指南请查看: iOS12_COMPATIBILITY_GUIDE.md" else echo "" echo -e "${RED}✗ 发现 $ERRORS 个错误,请修复后再编译${NC}" fi exit $ERRORS