11

我正在尝试创建一个二维码,以便 iPhone 用户可以导入我的通讯录信息。我这样做是:

  • 将 VCF (vcard) 文件放在我的 Web 服务器上
  • 创建包含此 URL 的 QR 图像。

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

这适用于我的桌面浏览器(它使用地址簿应用程序打开电子名片)。

在 iPhone 上,QR 阅读器成功告诉 safari 访问 vcard,但随后 safari 抱怨它不知道如何处理 vcard。我已经确认Content-Type: text/x-vcard正在发送。

所以,我的问题:

  • 如何让 Safari 识别我的电子名片?
  • safari 是否可以识别另一种卡片格式?
4

2 回答 2

14

[更新 - 2013 年 9 月 - 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();
}

以下是通过 Mobile Safari 将联系人从网页下载到 iPhone 的替代方法的完整描述。基本思想是将所需的联系信息作为文件附加到由移动 safari 处理的日历事件中。联系人文件本身使用简单的 PHP 脚本在日历文件中动态进行 base64 编码。所以请继续阅读...

VCALENDAR 文件中嵌入 VCARD 的基本布局

只想要源代码?在此处下载 [iphone-contact-download-demo] 以获得完整的 HTML5 Web 应用程序,您可以自由复制和复制,或访问http://iphone.mobicontact.info以获得工作演示。该演示使用 HTML5 缓存清单,它将内容下载到您的 iphone 或支持 HTML5 的浏览器以供离线使用。如果您想了解更多信息,请 google 以获取有关“离线网络应用程序”的更多详细信息。

VCALENDAR 中的嵌入式 VCARD for iPhone 下载 您可能已经了解到,无法使用 Mobile Safari 从网页将联系人文件(VCARD 格式数据为 .vcf 文件)直接下载到您的 iPhone。浏览器只是无法将 .vcf 扩展名和 mime 类型 (text/x-vcard) 识别为它应该处理的内容。顺便说一句,Android 和大多数其他移动设备应该能够足够轻松地处理 VCARD 文件 - 标准本身就像山一样古老!

您可能还读过,通过请求用户电子邮件地址,然后通过电子邮件向他们发送联系文件或创建指向 Google 地图条目的链接并从中提取联系信息(Google 地图条目需要数周时间才能达到在英国)。

虽然这些都是可行的解决方案,但它们并不是我所说的用户友好型,我尝试让我的客户接受其中任何一个,以在移动网络应用程序上下载联系人,但没有成功。

现在我还应该提到,您可以下载一些第三方应用程序,这些应用程序添加了对 VCARD (.vcf) 文件的支持 - 例如 QRAFTER 和 VCARD GETTER 都来自 Kerem Erkan 的优秀 QR 阅读器和他关于该主题和 iPad 解决方案的博客,和 HIPSCAN 电子名片导入器。但在我看来,假设你的读者安装了这些应用程序有点太过分了,所以我搜索了电子邮件、谷歌地图和第三方应用程序的替代解决方案。

在我继续之前,有许多链接更详细地描述了该问题:

堆栈溢出有几个关于强制 vCard 下载主题的线程 (thesheep.co.uk) EMAIL 解决方案和来自 Code Train 的相关博客 here vCard options for download 这里还有一个使用 Google Maps 的可能解决方案。Dataplex 的这篇文章也涵盖了这一点。Jonas Schmid 谈到正确地提供文件类型。MacRumors 线程

然后我开始想,iPhone 确实支持从 IOS5 的网页下载的 vcalendar 文件。VCALENDAR 文件通常具有 .ics 扩展名,并由移动 safari 处理,打开一个窗口,可以在该窗口中打开文件并将其保存到日历中。我发现 Apple 和 Mobile Safari 支持 VCAL 文件但不支持 VCARD 文件令人难以置信,但事实就是如此。那么如果我可以将 VCARD 文件附加到 VCALENDAR 文件呢?

第一个障碍是获取日历事件的附件...

最初,我尝试将附件添加到 Windows 中的 Outlook 日历约会中,尽管从网页链接时可能无法正确下载,当然也没有产生我想要的结果。所以,我决定尝试使用 Apple 软件,毕竟我们正在尝试下载到 iPhone 上。使用 Apple 的默认日历应用程序“iCal”存在一个基本问题 - 您无法将附件添加到事件/日历约会!因此,我在 Google 上搜索“在 OSX 中为日历事件添加附件”或类似内容,发现这篇出色的文章为我指明了正确的方向。

在 OSX 中向日历约会添加附件。

所以几分钟后,在安装了 BusyCal 的副本后,我能够创建一个事件并将 VCARD 文件附加到它(之前从我在 OSX 中的联系人中保存/导出)。此步骤仅用于了解在将附件添加到日历项时创建的文件的格式 - 您不需要安装 BusyCal 来实施下面描述的解决方案,但我将其包含在内以供参考,以便您了解 VCARD 如何嵌入在 VCALENDAR/VEVENT (.ics) 文件中。

我使用的步骤是在运行 OSX Lion 的 Apple iMac 上:

从您的联系人/通讯录中导出联系人以创建 VCARD 文件 (.vcf) - 如果您愿意,您可以使用文本编辑器编辑此文件以去除所有额外的内容,例如 UID 和 PROD-ID。 BEGIN:VCARD VERSION:3.0 N:Contact;iPhone;;; FN:iPhone Contact EMAIL;type=INTERNET;type=WORK;type=pref:iphone@mobicontact.info TEL;type=CELL;type=VOICE;type=pref:012-345-6789 END:VCARD 创建一个新日历 - 随意命名,我在“在我的 Mac”区域中使用了“vcal”,这样当您导出此日历以生成 .ics 文件时,您所得到的只是带有附加卡片的单个事件而不是使用现有日历时可能拥有的所有事件。创建一个新事件——你可以随意命名它——并给它一个任意的时间和日期。将 (1) 中的 VCARD 文件附加到这个新事件 - 参见屏幕截图。iMac 上的 BusyCal 允许附加到 VCALENDAR 约会 将事件保存到日历。从 BusyCal 的主菜单中,将日历导出到本地磁盘上的 .ics 文件 - 在此处下载 zip 文件 --> Apple 日历事件以及附加的联系人文件。您现在可以使用您喜欢的文本编辑器检查 Apple 如何在日历事件中存储附件,结果是使用:ATTACH;VALUE=BINARY;ENCODING=BASE64;FMTTYPE=text/directory; X-APPLE-FILENAME=iPhone Contact.vcf: QkVHSU46VkNBUkQNClZFUlNJT046M...等... [base64 编码的 VCARD] 然后我去掉了我不需要的所有额外的东西(这里是反复试验),直到我有绝对最小值iPhone 仍将其识别为带有附件的有效日历事件。

因此,正如我所说,以上所有内容对于实施联系人下载解决方案并不是必需的 - 我只是想向您展示我是如何理解 Apple 如何使用 X-APPLE-FILENAME 联系人行附加文件的。当然,他们如何使用 base64 编码对 VCARD 数据进行编码。因此,现在我们拥有了即时创建 VEVENT 并将 VCARD 附加到它们所需的所有信息,这些信息可以通过 Mobile Safari 直接下载到 iPhone。

1) 上传您要下载的联系人文件 (.vcf) - 您需要此文件,以便您可以将其直接下载到非 iPhone 或为 iPhone 进行 base64 编码。

2) 创建一个指向 PHP 文件的链接,该文件将即时生成日历事件,例如:下载 Contact iPhone 可能在 HTML5 移动应用程序中,如下所示: 在 VCALENDAR 中下载联系人的 PHP 文件的简单链接

3) 使用 iphonecontact-source-code 此处的代码创建或上传 vcal.php。此 PHP 文件为要下载的日历文件应用正确的标题/内容类型,然后您可以选择直接获取日历文件内容“iphonecontact.ics”,如“vcal-from-file.php”中所做的那样,或者生成动态日历,如“vcal.php”所示。后者是我的首选方法,因为您会得到一个带有时间戳的日历事件,显示下载的时间和日期。

4)就是这样!一切就绪 - 现在浏览到您 iPhone 上的网页并单击链接以执行“vcal.php”。您的浏览器现在应该显示 iphonecontact.ics 文件并要求您在手机日历应用程序中打开它 从网页下载的日历约会

5)选择“打开方式...”,您将看到日历约会和附加的联系人文件。 带有附加联系人文件的日历事件

6)注意我如何将日历事件的标题设置为有用的东西,以告诉用户如何处理嵌入的联系人文件(您可以在 vcal.php 中看到为事件设置摘要字段的行)。所以现在点击附件中的联系人文件... 打开的联系人文件

7)然后“创建新联系人”,你就快到了…… 联系已保存!!!

在 Apple 让你跳过的圈子里,保存联系并在你的呼吸下诅咒!

现在,根据我在 HTML5 Web 应用程序上使用此技术的经验,我想在此提及几点:

使用缓存清单 - 如果日历文件 (iphonecontact.ics) 已被缓存,我会遇到一些意外的行为/问题 - 我只是无法让它工作,所以我将它从清单中排除,这意味着它总是被下载- 源代码包含在此 zip 文件 iphonecontact-source-code 中。

您当然可以做一些用户代理嗅探来检测“vcal.php”PHP 文件中是否将 VCALENDAR 文件提供给 iPhone 并将 VCARD 文件本身提供给所有其他浏览器。它是一个足够简单的检查,并且通过谷歌搜索得到了很好的记录,所以如果你需要的话,我会留给你来弄清楚,如果你需要,可以随时在此处发布代码。

我认为就是这样 - 总结一下:

移动 Safari 不直接支持 VCARD (.vcf) 文件,但支持 VCALENDAR (.ics) 文件。

  • 当前的最佳解决方案是通过请求用户电子邮件地址向联系人发送电子邮件,或将联系人嵌入谷歌地图链接或下载处理 VCARDS 的应用程序。
  • Apple 确实支持日历文件的附件,但并不容易,所以一旦我们知道这是如何完成的,我们就可以在 PHP 中完成。
  • 将 VCARD 嵌入到 VCALENDAR 文件中,用户只需单击一两次,即可将联系人保存到他们的通讯录中。

我希望你喜欢这个解决方案——它和我想的一样好,直到 Apple 让步并允许 Mobile Safari 接受 VCARD 文件。

直到下一次...

于 2012-07-10T00:55:00.780 回答
9

苹果使用:

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

用于 VCALENDAR 文件中的嵌入式 VCARD。创建一个 VCALENDAR 文件,然后在其中对您的 VCARD 进行 base64 编码 - 下面的代码片段(我的博客上的完整详细信息)

<?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";
?>
于 2012-07-09T19:05:39.370 回答