Как решить проблемы с WS-соединением и зависанием камеры на мобильной платформе 1С:Предприятие?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разработка под мобильную платформу «1С:Предприятие 8» всегда сопряжена с преодолением специфических трудностей, вызванных различиями в операционных системах Android и iOS, особенностями прошивок сторонних производителей и поведением самой платформы при обновлении версий. В этой статье мы подробно разберем две классические проблемы, с которыми часто сталкиваются разработчики мобильных приложений на 1С: внезапный сбой авторизации при WS-соединениях и зависание стандартных средств камеры на некоторых современных смартфонах.

Мы детально проанализируем причины возникновения этих неполадок, рассмотрим практические кейсы и выработаем надежные, проверенные решения для обеспечения стабильной работы мобильного клиента.

Часть 1. Ошибка работы с Интернет: «No authentication found» при WS-соединении

Рассмотрим распространенную ситуацию: мобильное приложение, опубликованное на веб-сервере Apache, взаимодействует с центральной базой данных посредством Web-сервисов. Код инициализации соединения выглядит стандартно:


Определение = Новый WSОпределения("http://192.168.1.100/BaseMain/ws/SaveData?wsdl", "export", "958kf63", , 10, , Ложь);

Внезапно после очередного обновления платформы или изменения настроек сети на некоторых мобильных устройствах данная строка начинает вызывать исключение: «Ошибка работы с Интернет: No authentication found» (или аналогичное сообщение «No authentication challenges found»). При этом на части устройств обмен продолжает работать стабильно, даже если версии операционной системы и мобильной платформы совпадают. Выясним, почему так происходит.

Основная причина кроется в конфликте механизмов аутентификации на веб-сервере и ужесточении требований безопасности в новых версиях мобильной платформы 1С (начиная с 8.3.12). Проанализируем ключевые факторы:

  1. Конфликт типов авторизации (SSO/NTLM/Kerberos): Если на веб-сервере (особенно под управлением IIS, но также и на Apache при наличии определенных модулей интеграции) включена сквозная аутентификация Windows, сервер при запросе ожидает доменные данные. Мобильные клиенты, работающие на Android или iOS, физически не умеют отправлять доменные токены «из коробки». Вместо того чтобы предложить стандартный HTTP Basic Auth, веб-сервер сбрасывает соединение или возвращает некорректный ответ, на что мобильная платформа реагирует ошибкой отсутствия авторизации.
  2. Строгая проверка заголовков HTTP в новых версиях 1С: Разработчики платформы 1С планомерно усиливают безопасность сетевых соединений. Если более ранние версии (например, 8.3.11) прощали веб-серверу некорректные или отсутствующие заголовки авторизации в заголовках ответов (WWW-Authenticate), то версии 8.3.12 и старше жестко следуют стандартам RFC. Если сервер не присылает надлежащий Challenge-запрос, мобильный клиент мгновенно прекращает попытку соединения.
  3. Специфика сетевого окружения Android-устройств: Выборочность проявления ошибки на «одинаковых» телефонах объясняется внутренними настройками ОС. Разные производители (например, Xiaomi с оболочкой MIUI/HyperOS, Samsung с OneUI) внедряют собственные механизмы энергосбережения, проксирования трафика или встроенные средства безопасности (антивирусы, VPN-клиенты). Эти надстройки могут перехватывать сетевые пакеты, вырезать HTTP-заголовки Authorization: Basic ... или искажать SSL-рукопожатие, из-за чего веб-сервер перестает распознавать авторизационные данные мобильного клиента.

Как решить проблему с WS-соединением?

Для устранения этой ошибки можно пойти несколькими путями. Разберем по шагам каждое решение.

Способ 1. Настройка файла публикации default.vrd

Самое простое и правильное решение — явно отключить использование аутентификации операционной системы в файле публикации веб-сервиса. Для этого найдем на сервере файл default.vrd, соответствующий нашей публикации, и отредактируем его, добавив параметр useOSAuthentication="false". Пример структуры файла:


<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       base="/BaseMain"
       ib="Connect=&quot;Srvr=server;Ref=BaseMain;&quot;"
       useOSAuthentication="false">
    <ws>
        <point name="SaveData" alias="SaveData" enable="true"/>
    </ws>
</point>

После сохранения изменений обязательно перезапустите веб-сервер (Apache или IIS).

Способ 2. Разделение публикаций для десктопных и мобильных пользователей

Если в вашей организации для обычных ПК-пользователей настроена сквозная доменная авторизация (Active Directory) через веб-сервер, отключение этой опции парализует их работу. В таком случае рекомендуется создать две независимые публикации на веб-сервере:

Способ 3. Проверка и установка SSL-сертификатов

Если обмен происходит по защищенному протоколу HTTPS, мобильное устройство обязательно должно доверять SSL-сертификату сервера. Если сертификат самоподписанный (часто используется для тестов), мобильное приложение 1С заблокирует соединение без объяснения причин, выдав общую ошибку работы с Интернет. Необходимо вручную импортировать корневой сертификат вашего сервера в системное хранилище доверенных сертификатов на каждом проблемном мобильном устройстве (через настройки безопасности Android/iOS).

Способ 4. Временный откат или обновление платформы

В качестве быстрого временного решения (workaround) можно выполнить откат мобильной платформы на более раннюю стабильную версию (например, с 8.3.12 на 8.3.11). Однако в долгосрочной перспективе правильнее обновить мобильную платформу до актуального релиза (например, ветки 8.3.14 или старше), предварительно исправив настройки веб-сервера согласно Способу 1.

---

Часть 2. Проблема зависания камеры при СделатьФотоснимок()

Перейдем ко второй важнейшей проблеме — нестабильной работе встроенных мультимедийных средств. Разработчики часто используют следующий стандартный код для получения фотографий:


Разрешение = Новый РазрешениеКамерыУстройства;
Разрешение.Высота = 1024;
Разрешение.Ширина = 1365;        
ДанныеФото = СредстваМультимедиа.СделатьФотоснимок(ТипКамерыУстройства.Авто, Разрешение, 70);

На многих современных смартфонах (особенно бренда Xiaomi с прошивками MIUI/HyperOS) вызов этого метода приводит к зависанию интерфейса: камера открывается, снимок делается, но после нажатия кнопки подтверждения экран застывает. Картинка возвращается в приложение только после того, как пользователь принудительно свернет и заново развернет мобильное приложение 1С.

Выясним причину этого поведения. Все дело в агрессивной оптимизации оперативной памяти мобильной ОС. Когда 1С вызывает системную камеру через СредстваМультимедиа, управление передается системному процессу съемки, а само приложение 1С уходит в фоновый режим. Операционная система смартфона в этот момент мгновенно приостанавливает («замораживает») графический контекст 1С для экономии ресурсов. При возвращении из камеры приложение 1С не получает сигнал на перерисовку интерфейса. Ручное сворачивание и разворачивание приложения заставляет операционную систему принудительно обновить графический слой 1С.

Альтернативное решение для Android: Использование системных интентов

Чтобы обойти системные ограничения энергосбережения Android и избавиться от зависаний, мы можем отказаться от объекта СредстваМультимедиа и вызвать камеру как внешнее приложение с помощью объекта ЗапускПриложенияМобильногоУстройства (механизм Android Intents). Посмотрим на пример реализации:


// Определим путь для сохранения временного файла снимка
ИмяФайла = ПолучитьИмяВременногоФайла(".jpg");
ФайлКартинки = Новый Файл(ИмяФайла);

// Настраиваем интент для вызова стандартной камеры Android
ЗахватИзображения = Новый ЗапускПриложенияМобильногоУстройства("android.media.action.IMAGE_CAPTURE");
ЗахватИзображения.ДополнительныеДанные.Добавить("output", ФайлКартинки.ПолноеИмя, "Uri");

// Запускаем внешнее приложение камеры и ожидаем возврата управления
РезультатЗапуска = ЗахватИзображения.Запустить(Истина);

Если РезультатЗапуска = 0 Тогда
    // Фото успешно сделано и сохранено во временный файл
    Если ФайлКартинки.Существует() Тогда
        ДвоичныеДанныеФото = Новый ДвоичныеДанные(ФайлКартинки.ПолноеИмя);
        // Выполняем дальнейшую обработку полученного фото
    КонецЕсли;
Иначе
    Предупреждение("Не удалось запустить камеру или съемка была отменена.");
КонецЕсли;

Этот подход работает безупречно на всех Android-устройствах, поскольку операционная система корректно обрабатывает жизненный цикл приложений при явном вызове внешнего интента IMAGE_CAPTURE и возвращает управление в 1С без потери контекста отрисовки.

---

Часть 3. Создание универсального кроссплатформенного механизма съемки

Главный недостаток вызова камеры через механизм интентов Android заключается в том, что этот способ абсолютно несовместим с iOS. На устройствах Apple (iPhone, iPad) нет концепции глобальных интентов, аналогичных Android. Попытка выполнить данный код на iOS приведет к аварийному завершению работы приложения.

Проанализируем ситуацию и построим универсальную архитектуру съемки. На iOS стандартный метод СредстваМультимедиа.СделатьФотоснимок() работает стабильно и без зависаний, поскольку политика управления памятью в iOS жестко регламентирует переходы состояний приложений, не допуская деградации интерфейса. Следовательно, нам необходимо разделить логику выполнения кода в зависимости от текущей операционной системы устройства.

Разберем по шагам построение универсальной функции получения фотографии:


&НаКлиенте
Процедура ВыполнитьСъемку()

    #Если МобильноеПриложениеКлиент Тогда
        
        // Проверяем тип операционной системы устройства
        ИнформацияОСистеме = Новая СистемнаяИнформация;
        ТипПлатформы = ИнформацияОСистеме.ТипПлатформы;
        
        Если ТипПлатформы = ТипПлатформыКачестваМобильногоУстройства.Android Тогда
            // Используем стабильный вызов через Android Intent
            ВыполнитьСъемкуAndroid();
        ИначеЕсли ТипПлатформы = ТипПлатформыКачестваМобильногоУстройства.iOS Тогда
            // Используем стандартные средства мультимедиа iOS
            ВыполнитьСъемкуiOS();
        Иначе
            Предупреждение("Данная операционная система не поддерживается.");
        КонецЕсли;
        
    #Иначе
        Предупреждение("Съемка доступна только на мобильном устройстве!");
    #КонецЕсли

КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьСъемкуAndroid()

    ИмяФайла = ПолучитьИмяВременногоФайла(".jpg");
    ЗахватИзображения = Новый ЗапускПриложенияМобильногоУстройства("android.media.action.IMAGE_CAPTURE");
    ЗахватИзображения.ДополнительныеДанные.Добавить("output", ИмяФайла, "Uri");
    
    Если ЗахватИзображения.Запустить(Истина) = 0 Тогда
        ФайлФото = Новый Файл(ИмяФайла);
        Если ФайлФото.Существует() Тогда
            ОбработатьПолученноеИзображение(ИмяФайла);
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьСъемкуiOS()

    Разрешение = Новый РазрешениеКамерыУстройства;
    Разрешение.Высота = 1024;
    Разрешение.Ширина = 1365;
    
    Попытка
        ДанныеФото = СредстваМультимедиа.СделатьФотоснимок(ТипКамерыУстройства.Авто, Разрешение, 70);
        Если ДанныеФото <> Неопределено Тогда
            ИмяФайла = ПолучитьИмяВременногоФайла(".jpg");
            ДанныеФото.Записать(ИмяФайла);
            ОбработатьПолученноеИзображение(ИмяФайла);
        КонецЕсли;
    Исключение
        ЗаписатьЛогОшибки(ОписаниеОшибки());
        Предупреждение("Ошибка при работе с камерой iOS: " + КраткоеПредставлениеОшибки(ОписаниеОшибки()));
    КонецПопытки;

КонецПроцедуры

Важные нюансы при работе с внешней камерой на Android

Рассмотрим два критических момента, о которых нужно помнить при использовании внешнего интента на Android:

  1. Оптимизация размера файлов: При использовании IMAGE_CAPTURE камера фотографирует с максимальным разрешением, поддерживаемым физическим модулем устройства. Полученный файл может весить более 10 МБ. Передача таких объемов данных на сервер через мобильный интернет нецелесообразна. Начиная с версии платформы 8.3.14, в мобильной платформе появились отличные инструменты сжатия. Посмотрим на пример масштабирования картинки перед отправкой:
    
    // Пример уменьшения размера изображения
    КартинкаОригинал = Новый Картинка(ИмяФайла);
    КартинкаСжатая = КартинкаОригинал.Преобразовать(ФорматКартинки.JPEG, 1024, 768);
    КартинкаСжатая.Записать(ИмяФайла);
    
  2. Разрешения и манифест приложения (Permissions): Для того чтобы мобильное приложение имело право взаимодействовать с камерой (особенно на iOS), при сборке мобильного приложения в сборщике 1С необходимо обязательно установить флаги разрешений на использование камеры и галереи (ключи NSCameraUsageDescription и NSPhotoLibraryUsageDescription с текстовым описанием цели использования). Отсутствие этих настроек в манифесте приведет к моментальному закрытию («вылету») приложения при попытке вызвать фотосъемку на iOS.

Применяя предложенные нами подходы к разграничению авторизации на веб-сервере и разделению логики работы с камерой под разные мобильные операционные системы, вы сможете добиться высочайшей стабильности и отказоустойчивости ваших мобильных решений на платформе «1С:Предприятие 8».

← На главную