Что означает ошибка NSURL 1002
Ошибка NSURL Error Code 1002 (код -1002 в системах Apple) означает, что URL-запрос не может быть выполнен из-за проблем с безопасностью соединения. Полный текст ошибки часто выглядит так:
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
Она возникает при использовании классов NSURLSession или NSURLConnection в iOS/macOS, когда система блокирует запрос по политике App Transport Security (ATS). ATS по умолчанию требует, чтобы все внешние HTTP-запросы использовали протокол HTTPS с современными шифрами. Ошибка появляется в логах Xcode и в консоли приложения в момент выполнения сетевого запроса.
Причины возникновения
Ошибка NSURL 1002 имеет конкретные технические причины:
- Использование незащищённого HTTP вместо HTTPS. Самый частый случай. Запрос на
http://example.com/apiбудет заблокирован ATS. - Несоответствие SSL/TLS-сертификата сервера. Сертификат самоподписанный, просроченный, выдан для другого домена или использует слабые шифры.
- Некорректный или невалидный URL. Наличие пробелов, недопустимых символов (например, неэкранированных кириллических букв) или ошибка в схеме (
htp://вместоhttp://). - Конфликт с настройками ATS в
Info.plist. Отсутствие необходимых исключений для домена или неправильная структура конфигурационного файла. - Проблемы с DNS или сетевым экраном. Устройство не может разрешить домен или корпоративный фаервол/прокси блокирует запрос.
Способы решения
Способ 1: Быстрое решение — разрешить все HTTP-запросы (не для продакшена)
Для тестирования или внутренних приложений можно временно отключить ATS полностью.
- В Xcode откройте файл
Info.plistвашего проекта. - Нажмите кнопку + в последней строке, чтобы добавить новый ключ.
- Введите
NSAppTransportSecurity(тип Dictionary). - Раскройте новый словарь, добавьте ключ
NSAllowsArbitraryLoads(тип Boolean). - Установите значение YES.
<!-- Фрагмент Info.plist -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
⚠️ Важно: Этот метод запрещён для публикации в App Store, если только ваше приложение не предназначено для корпоративного распространения. Используйте только для отладки.
Способ 2: Правильное решение — добавить исключение для конкретного домена
Это рекомендуемый Apple подход, который сохраняет безопасность для остальных доменов.
- Откройте
Info.plist. - Добавьте ключ
NSAppTransportSecurity(тип Dictionary), если его ещё нет. - Внутри этого словаря добавьте ключ
NSExceptionDomains(тип Dictionary). - В
NSExceptionDomainsсоздайте запись с именем вашего домена (например,api.myserver.com). Имя должно точно совпадать с доменом в URL. - Для этого домена добавьте следующие ключи:
NSIncludesSubdomains(Boolean) → YES (если нужны все поддомены).NSTemporaryExceptionAllowsInsecureHTTPLoads(Boolean) → YES (если сервер использует HTTP).NSTemporaryExceptionMinimumTLSVersion(String) →TLSv1.2(если сервер поддерживает только старый TLS).
<!-- Фрагмент Info.plist с исключением -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>api.myserver.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
</dict>
</dict>
</dict>
💡 Совет: Если ваш сервер уже использует HTTPS с валидным сертификатом, никаких исключений не нужно. Ошибка 1002 в этом случае указывает на проблему с сертификатом. Исправьте сертификат на сервере.
Способ 3: Проверьте и приведите URL в порядок
Иногда проблема не в политике ATS, а в самом URL.
- Убедитесь в использовании правильной схемы. Запрос должен начинаться с
https://(предпочтительно) илиhttp://. - Экранируйте специальные символы. Если в URL есть пробелы, кириллица или символы вроде
#,?, их нужно закодировать. ИспользуйтеaddingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)в Swift илиstringByAddingPercentEncodingWithAllowedCharactersв Objective-C. - Проверьте домен на опечатки. Ошибка в имени домена (например,
exmaple.com) приведёт к сбою DNS и может вызвать 1002.
Пример кода для экранирования URL в Swift:
let rawString = "поиск?запрос=привет мир"
let escapedString = rawString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
// Результат: "поиск?запрос=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80"
Способ 4: Сброс сетевых настроек устройства
Если проблема проявляется на конкретном устройстве, а не в симуляторе, и все настройки кода верны, возможно, проблема в кэше DNS или конфликте VPN.
- На устройстве iOS откройте Настройки → Основные → Перенос или сброс iPhone.
- Выберите Сброс сетевых настроек.
- Подтвердите действие. Устройство перезагрузится, и все сохранённые Wi-Fi сети, пароли и VPN-конфигурации будут удалены.
- Подключитесь к сети заново и проверьте работу приложения.
Профилактика
Чтобы избежать ошибки NSURL 1002 в будущем:
- Всегда используйте HTTPS для production-сборок. Настройте ваш сервер с валидным SSL-сертификатом от доверенного центра (Let's Encrypt, DigiCert и т.д.).
- Валидируйте URL на клиенте перед отправкой запроса. Проверяйте схему, домен и корректность экранирования.
- Тестируйте приложение на разных сетях (Wi-Fi, мобильные данные, роуминг) и в разных географических регионах, если приложение глобальное.
- Не оставляйте
NSAllowsArbitraryLoads = YESв финальной версии приложения для App Store. Используйте точечные исключения черезNSExceptionDomains. - Мониторьте серверные сертификаты. Настройте автоматическое обновление и уведомления о просрочении.