Подтвердить что ты не робот

IPhone: как получить сафари, чтобы распознать vcard?

Я пытаюсь создать QR-код, чтобы пользователи iPhone могли импортировать мою адресную книгу. Я делаю это:

  • размещение файла VCF (vcard) на моем веб-сервере
  • создание QR-изображения, содержащего этот URL-адрес.

http://markharrison.net/mh-vcf-small.png

Это работает на моем настольном браузере (он открывает vcard приложением адресной книги).

На iPhone QR-ридер успешно сообщает сафари о доступе к vcard, но затем сафари жалуется, что не знает, как обращаться с vcard. Я подтвердил, что отправляется Content-Type: text/x-vcard.

Итак, мои вопросы:

  • Как получить Safari для распознавания моего vcard?
  • Есть ли другой формат карты, который распознает сафари?
4b9b3361

Ответ 1

[ОБНОВЛЕНО - сентябрь 2013 г. - iOS7 теперь поддерживает прямую загрузку файлов VCARD и импорт в собственное приложение для контактов]

function isiOS7($user_agent=NULL) {
    if(!isset($user_agent)) {
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    }
    return (strpos($user_agent, 'OS 7') !== FALSE);
}

# Output file contents - simple version
if(!isIphone() || isiOS7()) {
    # Send correct headers      
    header("Content-type: text/x-vcard; charset=utf-8"); 
                // Alternatively: application/octet-stream
                // Depending on the desired browser behaviour
                // Be sure to test thoroughly cross-browser

    header("Content-Disposition: attachment; filename=\"iphonecontact.vcf\";");
    # Output file contents 
    echo file_get_contents("iphonecontact.vcf");
    exit();
}

Далее следует полное описание альтернативного метода загрузки контактов с веб-страницы на iPhone через Mobile Safari. Основная идея заключается в том, чтобы связать необходимую контактную информацию в виде файла в календарном событии, которое обрабатывается мобильным сафари. Сам файл контакта является base64, закодированным в файле календаря "на лету" , используя простой PHP script. Так что читайте дальше...

Basic layout of embedded VCARD in VCALENDAR file

Просто нужен исходный код? Загрузите его здесь [iphone-contact-download-demo] для полноценного веб-приложения HTML5, которое вы можете скопировать и воспроизвести или перейти на http://iphone.mobicontact.info для рабочей демонстрации. Демонстрационная версия использует манифест кэша HTML5, который загружает контент в браузер поддержки iphone или HTML5 для использования в автономном режиме. Пожалуйста, обратитесь к Google за дополнительной информацией о "оффлайновых веб-приложениях", если вы хотите узнать больше.

Встроенный VCARD в VCALENDAR для iPhone скачать Возможно, вы прочитали, что невозможно скачать файлы контактов (данные формата VCARD как .vcf файл) прямо на ваш iPhone с веб-страницы с помощью Mobile Safari. Браузер просто не распознает расширение .vcf и тип mime (text/x-vcard) как что-то, над чем он должен работать. В стороне Android и большинство других мобильных устройств должны иметь возможность легко обрабатывать файлы VCARD - сам стандарт стареет, как холмы!

Вы также можете прочитать, что можно добиться чего-то работоспособного, запросив адрес электронной почты пользователей, а затем отправить им по электронной почте файл контакта или создать ссылку на запись в Google Map и извлечь из нее контактную информацию (для записи в Google Map требуется недель для достижения в Великобритании).

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

Теперь на этом этапе я также должен упомянуть, что вы можете загружать некоторые сторонние приложения, которые поддерживают поддержку файлов VCARD (.vcf), таких как QRAFTER и VCARD GETTER, как от превосходного QR-читателя Kerem Erkan, так и от его блога по этому вопросу и iPad, и импортером HIPSCAN vcard. Но предполагая, что ваши читатели установили эти приложения, на мой взгляд, слишком далеко, поэтому я искал альтернативное решение для электронной почты, карт Google и сторонних приложений.

Прежде чем продолжить, есть много ссылок, описывающих проблему более подробно:

Переполнение стека имеет несколько потоков по теме Принудительная загрузка vCard (thesheep.co.uk) Решение EMAIL и связанный с ним блог из кода Train здесь vCard параметры для скачивания Существует также возможное решение, использующее Карты Google здесь. И это также рассматривается в этой статье из Dataplex. Джонас Шмид говорит о правильном использовании типов файлов. MacRumours thread

Затем я подумал, iPhone поддерживает файлы vcalendar, загруженные с веб-страницы с IOS5. Файлы VCALENDAR обычно имеют расширение .ics и обрабатываются мобильным сафари, открывая окно, в котором файл можно открыть и сохранить в календаре. Я считаю невероятным, что Apple и Mobile Safari поддерживают файлы VCAL, но не файлы VCARD, но это именно так. Итак, что, если бы я мог прикреплять файл VCARD к файлу VCALENDAR?

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

Сначала я попытался добавить вложение в календарь календаря Outlook в Windows, которое, хотя возможно, не правильно загрузилось при привязке с веб-страницы и, конечно же, не дало результата, который я получил после. Итак, я решил попробовать использовать программное обеспечение Apple, поскольку, в конце концов, мы пытаемся загрузить на iPhone. Использование приложения Apple по умолчанию для календаря "iCal" представляет одну фундаментальную проблему - вы не можете добавлять вложения к назначению события/календаря! Таким образом, я googled "добавление вложений в события календаря в OSX" или подобное и нашел эту замечательную статью, которая указала мне в правильном направлении.

Добавление вложений в назначения календаря в OSX.

Итак, через несколько минут и с установленной копией BusyCal, я смог создать событие и прикрепить к нему файл VCARD (ранее сохраненный/экспортированный из моих контактов в OSX). Этот шаг необходим только для понимания формата файла, созданного при добавлении в элемент календаря, - вам НЕ нужно устанавливать BusyCal для реализации решения, описанного ниже, но я включаю его для справки, чтобы вы могли видеть, как VCARD встроен в файл VCALENDAR/VEVENT (.ics).

Шаги, которые я использовал, были на Apple iMac, работающем с OSX Lion:

Экспортируйте контакт из своей контактной/адресной книги, чтобы создать файл VCARD (.vcf) - вы можете отредактировать этот файл с помощью текстового редактора, чтобы удалить все лишние вещи, такие как UID и PROD-ID, если хотите. BEGIN:VCARD VERSION:3.0 N:Contact;iPhone;;; FN:iPhone Contact EMAIL;type=INTERNET;type=WORK;type=pref:[email protected] TEL;type=CELL;type=VOICE;type=pref:012-345-6789 END:VCARD Создайте новый календарь - назовите его так, как вам нравится, я использовал "vcal" - в области "На моем Mac", чтобы при экспорте этого календаря для создания файла .ics все, что вы получаете, - это единственное событие с подключенной картой а не все события, которые могут возникнуть, если вы используете существующий календарь. Создайте новое событие - назовите его любым, что угодно - и дайте ему произвольное время и дату. Присоедините файл VCARD от (1) к этому новому событию - см. Снимок экрана. BusyCal on iMac allows attachements to VCALENDAR appointments Сохраните событие в календаре. В главном меню BusyCal экспортируйте календарь в файл .ics на локальном диске - загрузите zip файл здесь → Событие календаря Apple с прикрепленным файлом контакта. Теперь вы можете использовать свой любимый текстовый редактор для изучения того, как Apple хранит вложения в событиях календаря и результат использует: ATTACH; VALUE = BINARY; ENCODING = BASE64; FMTTYPE = text/directory; X-APPLE-FILENAME = iPhone Contact.vcf: QkVHSU46VkNBUkQNClZFUlNJT046M... и т.д.... [кодировка с кодировкой base64 VCARD]  Поэтому я тогда удалил все лишние вещи, которые мне не нужны (проб и ошибок здесь), пока у меня не было абсолютного минимума, который по-прежнему был признан iPhone как действительное событие календаря с приложением. Причина этого заключается в том, чтобы сделать файл PHP, который создает событие календаря на последней веб-странице, как можно проще - вот минимальный уровень, который я уменьшил до него.

Таким образом, все вышеперечисленное, как я уже сказал, не является необходимым для реализации решения для загрузки контактов - я просто хотел показать вам, как я понял, как Apple прикрепляет файлы, используя контактную линию X-APPLE-FILENAME. И, конечно же, как они кодируют данные VCARD с использованием кодировки base64. Итак, теперь у нас есть вся информация, которая нам нужна для создания VEVENT на лету и прикрепления VCARD к ним, которые могут быть загружены прямо на iPhone через Mobile Safari.

1) Загрузите файл контакта (.vcf), который вы хотите загрузить, - вам понадобится этот файл, чтобы вы могли либо загрузить его прямо в не-iphones, либо base64 закодировать его для iPhone.

2) Создайте ссылку на файл PHP, который будет генерировать событие календаря "на лету" , например: Загрузите iPhone, возможно, в мобильное приложение HTML5, как показано ниже: Simple link to the PHP file to download the contact within VCALENDAR

3) Создайте или загрузите vcal.php с кодом здесь iphonecontact-source-code. Этот файл PHP применяет правильный тип заголовка/содержимого для загружаемого файла календаря, тогда у вас есть выбор либо получить содержимое файла календаря непосредственно "iphonecontact.ics", как это сделано в "vcal-from-file.php", либо создать календарь "на лету" , как показано в "vcal.php". Последний мой предпочтительный метод, потому что вы получаете красивое временное событие календаря, показывающее время и дату загрузки.

4) Это! Вы все настроены - теперь перейдите на веб-страницу на своем iphone и нажмите ссылку, чтобы выполнить "vcal.php". Теперь ваш браузер должен показать файл iphonecontact.ics и попросить его открыть его в приложении "Календарь" Calendar appointment downloaded from web page

5) Выберите "Открыть в...", и вам будет представлено назначение календаря и прикрепленный файл контакта. Calendar event with attached contact file

6) Обратите внимание, как я установил заголовок события календаря на что-то полезное, чтобы сообщить пользователю, что делать со встроенным файлом контакта (вы можете увидеть строку в vcal.php, которая устанавливает поле SUMMARY для события). Итак, теперь щелкните прикрепленный файл контакта... Opened contact file

7) И затем "Создать новый контакт", и вы почти там... Contact SAVED!!!

Сохраните контакт и проклинайте под своим дыханием на обручах Apple заставила вас прыгнуть!

Теперь есть несколько моментов, которые я хотел бы упомянуть здесь, основываясь на опыте использования этой техники в веб-приложениях HTML5:

Использование манифеста кэша - у меня было неожиданное поведение/проблемы, служащие файлу календаря (iphonecontact.ics), если он был кэширован - я просто не мог заставить его работать, поэтому я исключаю его из манифеста, что означает его всегда загружается - исходный код включен в этот zip файл iphonecontact-source-code.

Конечно, вы могли бы кое-что сделать, чтобы обнаружить в файле vcal.php PHP файл VCALENDAR для iPhone и самого файла VCARD для всех других браузеров. Его достаточно простая проверка и хорошо документирована с помощью поиска Google, поэтому я оставлю это вам, чтобы понять это, если вам нужно и не стесняйтесь публиковать код здесь, если вы это сделаете.

Я думаю, что об этом - так суммировать:

Мобильное сафари не поддерживает файлы VCARD (.vcf) напрямую, но поддерживает файлы VCALENDAR (.ics).

  • Лучшие лучшие решения - это отправить по электронной почте контакт, запросив адрес электронной почты пользователей или вставить контакт в ссылку google map или загрузить приложение, которое обрабатывает VCARDS.
  • Apple поддерживает вложения в файлы календаря, но не так легко, так как мы знаем, как это сделать, мы можем сделать это в PHP.
  • Вставьте VCARD в файл VCALENDAR, чтобы пользователь мог сохранить контакт в своей адресной книге всего за один клик или два.

Надеюсь, вам понравится это решение - это так хорошо, как я думаю, мы собираемся до тех пор, пока Apple не смягчит и не разрешит Mobile Safari принимать файлы VCARD.

До следующего раза...

Ответ 2

Я только что опубликовал альтернативное решение в своем блоге, в котором описывается, как присоединить файл контакта в виде вложения в файл календаря, который обрабатывается мобильным сафари от iOS5 и далее.

http://mobicontact.info/iphone/download-contact-from-web-page/

В блоге представлено полное решение, включающее исходный код и изображения всего процесса, и, как таковое, гораздо легче читать, чем то, что я могу поставить здесь на Stack Overflow. Главное отметить, что Apple использует:

ATTACH;VALUE=BINARY;ENCODING=BASE64;FMTTYPE=text/directory;
X-APPLE-FILENAME=iPhone Contact.vcf:
QkVHSU46VkNBUkQNClZFUlNJT046M…etc… [base64 encoded VCARD]

для встроенных VCARD в файлах VCALENDAR. Создайте файл VCALENDAR, а затем base64 закодируйте свой VCARD внутри него - фрагмент кода ниже (полная информация в моем блоге)

<?php
# Send correct headers      
header("Content-type: text/x-vcalendar; charset=utf-8"); 
# Alternatively: application/octet-stream
# Depending on the desired browser behaviour
# Be sure to test thoroughly cross-browser

header("Content-Disposition: attachment; filename=\"iphonecontact.ics\";");
# Output file contents - simple version
#echo file_get_contents("iphonecontact.ics");

# Generate file contents - advanced version
# BEGIN:VCALENDAR
# VERSION:2.0
# BEGIN:VEVENT
# DTSTART;TZID=Europe/London:20120617T090000
# DTEND;TZID=Europe/London:20120617T100000
# SUMMARY:iPhone Contact
# DTSTAMP:20120617T080516Z
# ATTACH;VALUE=BINARY;ENCODING=BASE64;FMTTYPE=text/directory;
#  X-APPLE-FILENAME=iphonecontact.vcf:
#  QkVHSU46VkNBUkQNClZFUlNJT046My4wDQpOOkNvbnRhY3Q7aVBob25lOzs7DQpGTjppUGhvbm
#  UgQ29udGFjdA0KRU1BSUw7VFlQRT1JTlRFUk5FVDtUWVBFPVdPUks6aXBob25lQHRoZXNpbGlj
#  b25nbG9iZS5jb20NClRFTDtUWVBFPUNFTEw7VFlQRT1WT0lDRTtUWVBFPXByZWY6KzQ0MTIzND
#  U2Nzg5MA0KRU5EOlZDQVJE
# END:VEVENT
# END:VCALENDAR

echo "BEGIN:VCALENDAR\n";
echo "VERSION:2.0\n";
echo "BEGIN:VEVENT\n";
echo "SUMMARY:Click attached contact below to save to your contacts\n";
$dtstart = date("Ymd")."T".date("Hi")."00";
echo "DTSTART;TZID=Europe/London:".$dtstart."\n";
$dtend = date("Ymd")."T".date("Hi")."01";
echo "DTEND;TZID=Europe/London:".$dtend."\n";
echo "DTSTAMP:".$dtstart."Z\n";
echo "ATTACH;VALUE=BINARY;ENCODING=BASE64;FMTTYPE=text/directory;\n";
echo " X-APPLE-FILENAME=iphonecontact.vcf:\n";
$vcard = file_get_contents("iphonecontact.vcf");        # read the file into memory
$b64vcard = base64_encode($vcard);                      # base64 encode it so that it can be used as an attachemnt to the "dummy" calendar appointment
$b64mline = chunk_split($b64vcard,74,"\n");             # chunk the single long line of b64 text in accordance with RFC2045 (and the exact line length determined from the original .ics file exported from Apple calendar
$b64final = preg_replace('/(.+)/', ' $1', $b64mline);   # need to indent all the lines by 1 space for the iphone (yes really?!!)
echo $b64final;                                         # output the correctly formatted encoded text
echo "END:VEVENT\n";
echo "END:VCALENDAR\n";
?>