Пошаговая инструкция по созданию мобильного приложения для iOS (без xcode) с обменом через WEB сервисы Часть I.




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2025-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

25 Comments

  1. anton.fly7

    не получается загрузить на iPad измененное приложение Заказ (((

    джейл не сделать т.к. версия 6.1.3

    Reply
  2. amrec.ru

    Тут ничего не поделаешь, нужен джейл

    или по инструкции ИТС + аккаунт разработчика apple

    Перевел свою управленческую базу на айпад, очень доволен)))

    Reply
  3. master-73

    Это все хорошо, но есть НО…

    Как с main базы отправить на mobile данные

    Reply
  4. amrec.ru

    Несложно. Если надо напишу статью об этом

    Reply
  5. Venzor

    (4) Ghez,

    Было бы очень интересно почитать.

    Reply
  6. amrec.ru
  7. anton.fly7

    у Рарус есть решение для обмену через web-сервис

    Смысл в том, что объекты, которые должны поехать в узел (iPad), сохраняешь в таблицу значений, эту таблицу помещаешь в хранилище, хранилище в xml, xml строкой передаешь через web-сервис в узел, в узле распаковываешь таблицу, пробегаешь по строкам — записываешь объекты ))

    там много нюансов, но у меня по этой схеме работают 30 узлов, обмен раз в 15 минут

    Reply
  8. anton.fly7

    Не подскажешь где так же доступно почитать про публикацию через XCode ? на ИТС как обычно не очень понятно…

    я почти готов купить аккаунт Apple ))

    Reply
  9. amrec.ru

    Выгрузка в Хранилище значений удобна, можно сжимать данные)

    Эта статья задумывалась как простая пошаговая инструкция без углубления в теорию и технические ньюансы

    Видимо сперва делаем это http://www.iguides.ru/forum/showthread.php?t=43253

    А потом с помощью «Помощника создания мобильного приложения» формируем проект xcode

    Но это всего лишь догадки

    Reply
  10. master-73

    (7) Подробней можно как то это увидеть?

    Reply
  11. anton.fly7

    (10) рарус продает эту разработку очень дорого (все относительно конечно, но для меня точно дорого)

    возможно если найдете их клиентов, которым внедрили…

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

    могу только на пальцах объяснить ключевые моменты )

    Reply
  12. amrec.ru

    Тоже изучаю эту область с такими же целями))) Думаю android перспективнее, потому что многие специализированные устройства никогда не будут с ios на борту. Хотя какая нам разница 🙂 конфа одна устройства разные)))

    Reply
  13. anton.fly7

    (12) по своему опыту могу сказать что iOS устройства носят более состоятельные клиенты )

    Reply
  14. master-73

    могу сказать что и дроид-устройства есть не дешевые, все зависит от «имени» и параметров устройства

    Reply
  15. KovalOleg

    А у меня вот тут:

    Определение = Новый WSОпределения(«http://192.168.15.155/MobileWS/ws/exchange/?wsdl»);

    спотыкается «Ошибка при вызове конструктора(WSОпределения). Неверный Формат.

    А из браузера по ссылке XML-документ показывается.

    З.Ы. правда из андроида ломлюсь, но по идее должно работать все равно.

    Reply
  16. amrec.ru

    Попробуй перезапустить apache

    Reply
  17. demetr2011

    (15)Константу можно завести (разбор wsdl указывать по идее не обязательно:) ). И не злоупотребляйте легкими решениями. iOS and Android по-разному ведут себя на некоторых функциях(ждем релиз).

    >Установите Сервер Apache Ссылка

    апач наверно будет лишним:)

    (8)Виртуалка (лучше образом: от 4Гб ) и скачайте Xcode.

    Компиляция / подпись ( <key>E1CDevelopmentMode</key> ) не займет много времени.

    Reply
  18. Fantasisto

    Спасибо огромное за статью! очень полезна!

    Единственное — выскакивает ошибка при записи номенклатуры клиенте (на компьюетере) —

    Ошибка при выполнении обработчика — ‘ПриЗаписи’
    по причине:
    {Справочник.Номенклатура.МодульОбъекта(5)}: Ошибка при вызове метода контекста (ЗагрузитьНоменклатуру)
    Результат = Прокси.ЗагрузитьНоменклатуру(Код, Наименование);
    по причине:
    Ошибка вызова операции сервиса:  {exchange}:exchange:ЗагрузитьНоменклатуру()
    по причине:
    Ошибка SOAP сервера:  Неизвестная ошибка. {WebСервис.exchange.Модуль(13)}: Ошибка при вызове метода контекста (Записать)
    по причине:
    {WebСервис.exchange.Модуль(13)}: Ошибка при вызове метода контекста (Записать)
    по причине:
    
    по причине:
    Конфликт блокировок при выполнении транзакции:
    Превышено максимальное время ожидания предоставления блокировки

    Показать

    А при записи элемента на мобильном пишет «Неверный формат».

    С чем это может быть связано?

    Заранее спасибо!

    Reply
  19. rutony

    Так и не решилась эта проблема «Неверный формат» на андроиде?

    Reply
  20. slaviksoft

    у меня тоже говорит «неверный формат» на мобильном устройстве LG P765

    апач перезапускал, даже на англ. язык все переименовал

    не помогло

    Reply
  21. deaddy64

    Наверно глюк релиза с этим самым WSОпределение «неверный формат». У меня такая же проблема.

    Reply
  22. omut

    Решил проблему с неверным форматом. Нормально работает на андроиде, серверная база крутится на 8.2. Общий алгоритм такой:

    1. Создаем пустой пакет XDTO, задаем для него корректное URI пространство имен в таком формате: http://mydomenname (указание протокола, судя по всему, обязательно, использование поддоменов в имени допустимо, имя пространства только латиницей, допустимы цифры и символы как для любого доменного имени)

    2. Создаем веб-сервис. у него URI пространство имен задаем точно такое же, как у пакета, созданного в п. 1. Имя пакета можно писать кириллицей, имя файла публикации лучше латиницей (кириллицу не проверял, но такой вариант точно не фонтан, т.к. параметр войдет в адрес веб-сервиса)

    3. Задаем следующие пакеты XDTO для веб-сервиса: http://v8.1c.ru/8.1/data/core, http://v8.1c.ru/8.1/data/enterprise/current-config и тот пакет, который создали в п.1

    4. Внимательно смотрим типы возвращаемых значений операций и типы значений параметров, включаемых в веб-сервис. Описание необходимого типа подглядываем в синтакспомощнике.

    5. Публикуем веб-сервис

    6. В конфигурации мобильного приложения делаем следующий вызов:

    Определения = новый WSОпределения(«http://СерверСервисов/ИмяВебСервиса.1cws?wsdl»,ИмяПользователя,Пароль);
    Прокси = новый WSПрокси(Определения,»http://mydomenname»,»МобильныеПриложения»,»МобильныеПриложенияSoap»);
    

    Тут важно, чтобы первый параметр был такой же, как в п.1

    Этого достаточно, чтобы ошибка пропала и подключение прошло успешно.

    Reply
  23. arccos6pi

    (22) omut, я бы сказал что тут даже лишнее есть,1 и 3 пункт не нужны(точнее не обязательны,и без них прекрасно работает)

    Reply
  24. omut

    Да, уже тоже это выяснилось. В п.3 достаточно включить те, из которых берутся описания типов. Например, если будет тип, условно говоря, ТаблицаЗначений, то без этих пакетов не обойтись. Так что все из описания типов, где сериализованы, то и указать.

    Reply
  25. alex15650

    (22) omut, супер, спасибо!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *