В этой статье я расскажу о скрипте, который поможет вам определить, используете ли вы в коде API для которых скоро Apple будет требовать объяснений.
Почему использование API нужно будет объяснять
Компания Apple классифицировала несколько API, которые могут быть использованы для идентификации устройства или пользователя (так называемый «фингерпринтинг»).
API были сгруппированы следующим образом:
- File timestamp API
- System boot time API
- Disk space API
- Active keyboard API
- User defaults API
Актуальный список «необходимых для объяснения API», состоящий из UserDefaults, ProcessInfo.systemUptime и многих других, вы можете найти здесь.
Зачем проверять декларируемые API
Начиная с осени 2023 г. при загрузке в App Store Connect нового приложения или обновления, использующего такой API (возможно, из сторонних SDK), который требует указания причины, вы будете получать предупреждение, если не указали причину в манифесте конфиденциальности своего приложения.
Скрипт для поиска таких API
Возможно, вы не захотите ждать (будущих) проверок, выполняемых при загрузке в App Store Connect.
Я написал следующий сценарий для сканирования файлов Swift/Objective-C на предмет потенциального использования этих API.
Скрипт не является идеальным. Он может выдавать ложные срабатывания, например, если вы объявите переменную creationDate, то сценарий найдет ее, хотя вам стоит беспокоиться только в том случае, если вы используете FileAttributeKey.creationDate.
#!/bin/bash # https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api searchTerms=( # File timestamp APIs "creationDate" "modificationDate" "fileModificationDate" "contentModificationDateKey" "creationDateKey" "getattrlist" "getattrlistbulk" "fgetattrlist" "stat" "fstat" "fstatat" "lstat" "getattrlistat" # System boot time APIs "systemUptime" "mach_absolute_time" # Disk space APIs "volumeAvailableCapacityKey" "volumeAvailableCapacityForImportantUsageKey" "volumeAvailableCapacityForOpportunisticUsageKey" "volumeTotalCapacityKey" "systemFreeSize" "systemSize" "statfs" "statvfs" "fstatfs" "fstatvfs" "getattrlist" "fgetattrlist" "getattrlistat" # Active keyboard APIs "activeInputModes" # User defaults APIs "UserDefaults" ) search_dir="$1" if [ -z "$search_dir" ]; then echo "Usage: $0 <search_dir>" exit 1 fi for pattern in "${searchTerms[@]}"; do find "$search_dir" -type f \( -name "*.swift" -o -name "*.m" \) -exec grep -H -Fw "$pattern" {} + done
Если вы сканируете большую кодовую базу, я рекомендую собирать результаты в текстовый файл для более удобной ручной проверки.
bash findRequiredReasonAPIUsage.sh /Users/MarcoEidinger/MySLargeSwiftProject > results.txt
Сообщите мне, если вы найдете способы дальнейшего улучшения скрипта, и я обновлю его.