How to download contact (vcard .vcf) from a webpage direct to iPhone in Mobile Safari [iOS7 UPDATE! - now supported Sept 18th 2013]

Well I never thought I would see the day but finally, iOS7 now supports import of VCARDs from web pages directly.  Check it out for yourself from http://iphone.mobicontact.info and click “Download VCARD directly” which links to http://iphone.mobicontact.info/iphonecontact.vcf.

And even better you can have it as a QR code now on your business cards… see iOS7 supports VCARD .vcf download – AT LAST!!!

The solution below should still work for older versions of iOS but it looks like they may have broken it in iOS7. Some extra user agent sniffing solves the problem and demo has been updated accordingly.

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();
}

=== ORIGINAL POST ===

So apparently it is not possible to download contact files (VCARD) direct to your iPhone (BUT IT IS NOW WITH iOS7) from a web page using Mobile Safari.  Think again – what if you attached a VCARD to a calendar appointment from the same web page?  iOS 5+ handles VCALENDAR!!! It’s not a perfect solution but pretty close so what follows is a full description of an alternative method for downloading contacts from a web page to an iPhone via Mobile Safari. The basic idea is to attach the required contact information as a file in a calendar event which IS handled by mobile safari.  The contact file itself is base64 encoded in the calendar file on the fly using a simple PHP script. Full source code Included with Mobile Safari and Mobile Chrome support from a single download PHP file.

Just want the source code? Download it here [iphone-contact-download-demo] (jQuery Mobile version) and here [iphone-contact-download-demo-html] (HTML) for a fully working HTML5 Web App that you are free to copy and reproduce or go to http://iphone.mobicontact.info and http://demo.mobicontact.info for the working demos.  The first demo uses jQuery Mobile and the HTML5 cache manifest which downloads the content to your iphone or HTML5 supporting browser for use when offline.  Please google for more details about “offline web apps” if you want to know more.

File content layout
Embedded VCARD in VCALENDAR for iPhone download

You may have read that it is not possible to download contact files (VCARD format data as .vcf file) direct to your iPhone from a web page using Mobile Safari.  The browser just does not recognise the .vcf extension and mime type (text/x-vcard) as something it should handle.  As an aside, Android and most other mobile devices should be able to handle VCARD files easily enough – the standard itself is as old as the hills!

You may also have read that it IS possible to achieve something workable by requesting the users email address and then email them the contact file OR creating a link to a Google Map entry and extract the contact information from that (Google Map entry requires weeks to attain in the UK).

Whilst these are both viable solutions, they are not what I would call user friendly and I tried, unsuccessfully, to get a client of mine to accept either one of them for their contact download on a mobile web app.

Now at this point I should also mention that you CAN download some third party apps that add support for VCARD (.vcf) files – such as QRAFTER and VCARD GETTER both from Kerem Erkan‘s excellent QR reader and his blog on the subject and iPad solution, and HIPSCAN vcard importer.  But assuming your readers have these apps installed is one step too far in my opinion so I searched for an alternative solution to email, google maps and third party apps.

Before I continue, here are some reference links describing the problem in more detail:

Stack overflow has several threads on the subject – like this one and this and this and this.

Forcing vCard download (thesheep.co.uk)

The EMAIL solution and associated blog from the Code Train here vCard options for download

There is also a possible solution using Google Maps here.  And this is also covered by this article from Dataplex.

Jonas Schmid talks about serving the file types correctly.

MacRumours thread


Then I got thinking, iPhone DOES support vcalendar files downloaded from a webpage as of IOS5.  The VCALENDAR files usually have a .ics extension and are handled by mobile safari bringing up a window where the file can be opened and saved to the calendar.  I find it unbelievable that Apple and Mobile Safari support VCAL files but not VCARD files but that is just how it is.  So what IF I could attach a VCARD file to a VCALENDAR file?

First obstacle is getting an attachment on a calendar event…

Initially I tried adding an attachment to an Outlook calendar appointment in Windows which whilst possible did not download correctly when linked from a webpage and certainly didn’t yield the result I was after.  So, I decided to try using Apple software as, after all, we are trying to download onto an iPhone.  Using Apple’s default calendar application “iCal” presents one fundamental problem – you can’t add attachments to an event/calendar appointment!  So I googled “adding attachments to calendar events in OSX” or similar and found this excellent article which pointed me in the right direction.

Adding attachments to calendar appointments in OSX.

So a few minutes later and with a copy of BusyCal installed, I was able to create an event and attach a VCARD file to it (previously saved/exported from my contacts in OSX).  This step is only necessary to understand the format of the file created when an attachment is added to a calendar item – you DO NOT need to install BusyCal to implement the solution described below but I include it for reference so that you can see how the VCARD is embedded in the VCALENDAR/VEVENT (.ics) file.

The steps I used were on an Apple iMac running OSX Lion:

  1. Export a contact from your Contacts/Address Book to create a VCARD file (.vcf) – you can edit this file with a text editor to strip out all the extra stuff such as UID and PROD-ID if you like.
    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
  2. Create a new calendar – call it what you like, I used “vcal”- in the “On my Mac” area so that when you export this calendar to generate the .ics file, all you get is the single event with the attached card rather than all the events you might have if you use an existing calendar.
  3. Create a new event – call it anything you like – and give it an arbitrary time and date.
  4. Attach the VCARD file from (1) to this new event – see screenshotNew event showing where to attach files.
  5. Save the event to the calendar.
  6. From the main menu of BusyCal, export the calendar to an .ics file on your local disk – download the zip file here –> Apple calendar event with attached contact file.
  7. You can now use your favourite text editor to examine how Apple store attachments in calendar events and the result is using:
    ATTACH;VALUE=BINARY;ENCODING=BASE64;FMTTYPE=text/directory;
    X-APPLE-FILENAME=iPhone Contact.vcf:
    QkVHSU46VkNBUkQNClZFUlNJT046M…etc… [base64 encoded VCARD]
  8.  So I then stripped out all the extra stuff I didn’t need (trial and error here) until I had the absolute minimum that was still recognised by the iPhone as a valid calendar event with attachment.  The reason for doing this is to make the PHP file that creates the calendar event on the final webpage as easy as possible – here is the vcal-minimal of what I reduced it to.
So all of the above, as I said, is not necessary to implement the contact download solution – I just wanted to show you how I got to understanding how Apple attach files using the X-APPLE-FILENAME contact line.  And of course, how they encode the VCARD data using base64 encoding.  So now we have all the info we need to create VEVENTs on the fly and attach VCARDs to them that can be downloaded direct to an iPhone via Mobile Safari.
  1. Upload the contact file (.vcf) you want to be downloaded – you’ll need this file so that you can either download it direct to non-iphones or base64 encode it for the iPhone.
  2. Create a link to a PHP file that will generate the calendar event on the fly such as:
    <a href=”download.php”>Download Contact to ANY phone</a> perhaps in a HTML5 mobile app like below:
  3. Create or upload the “download.php” with the code here iphone-contact-download-demo. This PHP file applies the correct header/content type for the calendar file to be downloaded then you have a choice of either getting the calendar file contents by generating the calendar on the fly as shown in “download.php”.  This way you get a nice timestamped calendar event showing the time and date of the download.
  4. That’s it!  You’re all set – now browse to the web page on your iphone and click the link to execute “download.php”.  Your browser might now show the iphonecontact.ics file and ask you to open it in the iPhones Calendar application (image below) or it may open it automatically (see step 5)
  5. Select “Open in Calendar” and you will be presented with the calendar appointment and the attached contact file.
  6. Notice how I set the title of the calendar event to something useful to tell the user what to do with the embedded contact file (you can see the line in “download.php” that sets the SUMMARY field for the event).  So now click the attached contact file…
  7. And then “Create New Contact” and you’re nearly there
  8. Save the contact and curse under your breath at the hoops Apple made you jump through!

Now there are a couple of points I’d like to mention here based on my experiences using this technique on HTML5 web apps:
  1. Using the cache manifest – I had some unexpected behaviour/problems serving the the calendar file (iphonecontact.ics) if it had been cached – I just couldn’t get it to work so I exclude it from the manifest which means it is always downloaded – source code is included in this zip file iphone-contact-download-demo.
  2. [UPDATE Jan 2013 - I have added the user agent sniffing and mobile safari detection and the demo site and source code now reflect the complete solution]
  3. [UPDATE Feb 2013 - I have tightened the code for Mobile Safari detection in download.php as I had missed that Chrome for iPhone is available that differs only in the Version part of the user agent string and Chrome does not support .vcf or .ics files at all. (Thanks Frank)]
I think that’s about it – so to summarise:
  • Mobile safari doesn’t support VCARD (.vcf) files directly but does support VCALENDAR (.ics) files.
  • Current best solutions are to email the contact by requesting the users email address OR to embed the contact in a google map link OR download an app that handles VCARDS.
  • Apple does support attachments to calendar files but not easily so once we know how this is done we can do it in PHP.
  • Embed a VCARD into a VCALENDAR file to allow a user to save a contact to their address book with just an extra click or two.
  • Check for iPhone/iPad in the download script and only return the VCAL if Apple device detected.
  • Add a further check for Mobile Safari to prevent the “Frame Load interrupted” bug when viewing content from within a native App using UiWebView and render instructions to view in Mobile Safari – some QR readers allow you the choice (my favourite is QRafter).
I hope you like this solution – it is as good as I think we are going to get until Apple relent and allow Mobile Safari to accept VCARD files.
Until next time…

64 thoughts on “How to download contact (vcard .vcf) from a webpage direct to iPhone in Mobile Safari [iOS7 UPDATE! - now supported Sept 18th 2013]

  1. Nice solution! Stays within the Apple calendar then contact framework for the whole process which is much easier cleaner IMHO than the email solution I used to rely on.

    Let’s hope Apple don’t close this loophole and stop allowing calendar events to be downloaded just to spite you :-)

    Will up vote the answer on Stack Overflow too.

  2. Hey Great article,

    Could you provide me the code? I need to do something similar. I need the users ability to download the contact directly to address book but safari doesn’t understand vcf file.

    It would be great if you can share the code with me.

    Thanks in advance.

    1. I don’t think so. Of course, you could make it even clearer perhaps in the title text of the “dummy” appointment. The demo app includes such text to ask the user to click the contact file. I have tried turning off all calendars and it still shows that button. Still – I hope you like the solution – if you ever use it in anger, feel free to post back here so that others can see it being used as a viable solution in the big wide world…

  3. I like you solution, …

    But unfortunately QR scanners on iOS devices can’t open that .ics in their UIWebView (“frame load interrupted” bug).

    Possible solution:
    You need to fetch ipad/ipod/iphone devices, show them a page saying the following:
    1. Click on the link to open (link to the .ics file)
    –> This triggers the following error in all QR scanners: “frame load interrupted”
    2. Then click on “open in Safari”

    Disadvantage:
    In some QR scanners the “open in Safari” functionality is hidden.
    So make sure that your text explains this error in Safari on iOS devices…

    1. Hi Jeroen,

      You are right – I hadn’t considered scanning the vcal.php link directly via a QR Reader. I can see why you might want to do that – you would be able to circulate a QR code that takes you to a contact download rather than hardcoding the contact details in the QR code itself – which is what most people do but, of course, means you are stuck if you need to change your contact details in the future (as we all do!)

      I use QRafter which does have the “Open In Safari” option shown – I will publish an update with the points you mention plus provide the code for auto-detecting iPhone.

      Thanks for your comment and please feel free to upvote the answer on StackOverflow.com which will drive more people here and help us get Apple to solve this once and for all.

      1. Hi Jeroen,

        As of Jan 2013, I have updated the source code to include user agent sniffing and checks for mobile safari (UiWebView does not send “Safari” in its user agent string). If the download.php script determines we are not using Mobile Safari then it assumes a UiWebView or similar and presents a page requesting the user to reopen in Safari. I think that is as good as I can make it.

  4. Thank you so much for posting this. It saved me a huge amount of time and aggravation! I know it not only took you a long time to figure this solution out, but to then post it for the rest of us. Very much appreciated!

    1. Glad to help. Please up vote the same answers on the Stack Overflow questions linked in the article so others can get find this too. Good luck with whatever you are going to use it for…

  5. I just wanted to say thank you for your code. I have been playing with it for the past couple of days (not really a programmer) I added some code that you might be interested in for the default vcal.php script.

    1) I pass it the employees name, if the name.vcf file doesn’t exist I give them the default company.vcf file
    2) I check the HTTP_USER_AGENT and if it is IPAD or IPHONE, I use the ICAL otherwise I give them the name.vcf directly.
    3) If it is a IPAD or IPHONE, I check to see if their browser is Safari, if it is not. I create a webpage that tells them to open in Safari. Which reloads the page and pulls it up with the iCAL.

    Thanks again, and if you want my code, I am more that happy to share it. I wouldn’t have gotten this far without your example.

    1. Hi John,

      Thanks for the support – makes it worthwhile writing these kind of blog entries when I see someone making some real use of it and I’d be very grateful for your updated code and I’ll include a .zip file with it alongside the simple demo already there. You can email it directly if you like to the email address included in the demo app.

      P.S. this blog getting a 1000 hits a month now – so I think you can be assured that we’ll see many more examples of this workaround and hopefully with your new code in place.

  6. Hi Steve,

    Thanks for the update and I will use it, but I am mainly using the vCard link in my eMail signature to pull my vCard down from my web site. It would appear that I will have to create an extra iPhone-vCard link in my eMail signature to use your solution.

    But just also found out through trial on using the vCard link on my web site that my iPhone 4 gets the vCard OK but just does not give the option to save to the iPhone Address Book. But if you have dropbox installed on your iPhone, you can just save it to there, then pull it straight out of dropbox into the Address Book – which is also pretty quick and easy and saves on the separate iPhone-vCard link.

    My initial problem was not with iPhone Safari but with the desktop version, as it just pulled the vCard in as text, whereas Firefox did open the vCard correctly.

    I found that putting “AddType text/x-vcard .vcf ” into the .htaccess file got things working correctly in the desktop Safari and FWIW this may have also helped to get a useable download onto the iPhone.

    Thanks again.

    – Neil

    1. Hi Neil,

      Thanks for your support. I recently updated the demo code to replace vcard.php with a download.php that includes all the user agent sniffing so you only need one link in your signature. The Demo App has been updated to include all types of download option and the one you want is “Download to Any Phone”. Goto Demo App and see it in action – source code also available.

      Regarding your other comments: you are correct that there are third party tools that will handle the vcard when downloaded (Dropbox, VCARD getter, QRafter, Hcard etc.) but the point of this solution is that you don’t need any apps to be installed – it uses only native apple software as shipped from the factory.

      As for content-type – I think I covered all that here but possibly not in htaccess – instead, I server the correct content type in the PHP file itself by sending the appropriate headers.

      Good luck,

      Steve

  7. Very nice tutorial and sample code! :-)

    One note:
    If you add && strstr($user_agent, " Version/") to the Mobile Safari browser check (download.php, line 28), then also users with iPhone + Chrome will be redirected to the “Please reopen this page in Mobile Safari.“ page. Otherwise Chrome for iPhone gives error 102 “unknown file type“, because it doesn’t handle .ics or .vcf files. Chrome’s user agent string contains “CriOS/“ instead of “Version/“.

    1. Thanks Frank – have just installed Chrome for iPhone and updated the code as you suggested. It didn’t even occur to me that Google would make such a hash of it too – and they don’t support either .vcf or .ics files – perhaps they are using a UiWebView themselves I guess.

  8. I can’t get this to work dynamically. I set this up to dynamically load the .vcf into the vcal.php and that part works great. It even initiates the download properly on the desktop, so I know it has to be near what it needs to be. But for some reason, it doesn’t open the prompt on an iPhone. I even tried to switch the header type to application/octet-stream. That didn’t work. Any ideas on where to start?

    1. Hi Ryan,

      Have you used the latest download file – the reason I ask is that this uses a renamed file “download.php” which has a whole lot more code in to check user agent etc.

      How are you initiating the transfer? From a link on a web page which should download either a .vcf file or vcal.php depending on user agent. The demo app at http://iphone.mobicontact.info I thought handled all the situations I am currently aware of but perhaps you have a case that is not handled.

      Let me know and I’ll try to help,

      Steve

      1. I grabbed the code from here: http://mobicontact.info/wp-content/uploads/2012/07/iphone-contact-download-demo.zip a few days ago. I’m hoping that’s the code I need. Your demo app obviously works. However, we were using the vcal.php code, not the download code? Now I’m a bit confused as the vcal.php file in that demo zip doesn’t call the download.php file, so how does that get initiated. I believe that is the source of my issues.

        1. I think I should probably remove the vcal.php as it has been superseded by the download.php which does all t he detection itself so you only need to link to download.php and it will figure out how to serve the correct file type and with what headers. I have updated the zip file to remove them and updated the link.

          Hope this helps – if not let me know.

          Steve

          1. I have updated the post and removed all old links references to vcal.php – I was leaving them in as a reference but now that “download.php” does all t he work they only confuse the issue and are something else I need to maintain.

            Good luck.

            PS : I see you do a lot of Joomla development – if you put this into a plugin/module or whatever for Joomla I’d gladly post the solution and credit your company.

  9. I can’t seem to get the demo ‘download.php’ to work for iphone 4s io6.1.2.
    But it work great from your demo site.

    I don’t even know where to start, cause when I try to use the download.php it spits out a blank webpage to Safari. no errors to view.

    Any suggestions? can I see the download.php code on this website for caomparison?

  10. Ok.. After hours of searching I came up with this…I have to use the following code and it work perfectly.


    Add to Contacts from iPhone

    Otherwise i get a blank page with UNDEFINED at the top of the page and nothing else when using download.php or vcal.php.
    But, when I refresh the page with the correct URL (www.somepahe.com/vcal.php) te v-card downloads??!!!

    Tired and going to bed. gnite and thanks for the script.

  11. I must have been working to late cause I found the problem!

    First – This is a great solution for me and my iphone clients. Thanks.
    Second – I used download.php. Just had changed DTSTART to my timezone and thats where I made a bug, that I now fixed.

    Thanks for your great work. Paypal Donation?

    1. Thanks – please post some more details if you find something up with IE. I don’t use it in day to day stuff but do cross browser test for my clients (just probably not so much for this blog)

  12. Your solutions for adding contact information is great – it works both on my iPhone and Android. I’d like to offer a website link to both email or text message a vCard to an address/number they can enter. You have mentioned that emailing a vcf attachment has been done; do you have a link you think best describes how so that I can incorporate it into your code?

    Thank you for making your discovery and code available to the community.

  13. Hi

    I just tested your demo on my old iPhone 3 and your solution doesn’t seem to work. I only get a popup with “Download failed – Safari can’t download this file” (roughly translated from the actual German error message).
    Does your fix only work on newer iOS versions?

    Would be great to hear from you. Currently you are my only hope.

    Thanks in advance,
    Konrad

    1. Hi Konrad,

      From what you say it does look like the old 3G iphone does not allow my approach to work. I have tested the user agent string for an iPhone 3G running iOS4 and the PHP user agent sniffer returns the calendar event as expected so I guess the iOS4 is not able to handle these. If/when I get hold of an iPhone 3 or run it up in a simulator on my Mac I will get back to you.

      User agent string I used for testing…

      Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A306 Safari/6531.22.7

      Regards,

      Steve

  14. Hello Steve,

    Your approach is brilliant – it lead me to a solution for non-Apple browsers as well. I did have one question: does the calendar-based VCARD entry works on Androids as well? When I use it, the calendar entry appears and is inserted, but the VCARD is not displayed. Not a big deal since I can pop VCARD from a direct file download onto Android, but it would be nice to “understand” why it works/looks differently.

    BTW, I had to translate your .php into ASP.NET MVC for my project, and so if you are interested, I’ll be happy to send you my code so that other poor souls will have easier time implementing what should have been trivial functionality (thanks, Apple!).

    Cheers,

    Roman

    1. Sure – I’d be happy to host your ASP version. I need to do some updates anyway to publish the Joomla solution which has been requested many times over. If you want to supply the text/description to go with it then feel free or I’ll try my best to comment for others. Thanks for your support.

    2. I would love to get this part translated if you don’t mind:

      $b64vcard = base64_encode($vcard);
      $b64mline = chunk_split($b64vcard,74,”\n”);
      $b64final = preg_replace(‘/(.+)/’, ‘ $1′, $b64mline);

      please write back as this would be a waste of time since you already did it.

  15. Steve –

    Great post and excellent resource. This took me about an hour to integrate into a WordPress plugin that I made to display vCards uploaded to a website and all I had to do was replace the file paths to the uploaded content!

    Thanks a ton!

    1. Glad it helped. I wouldn’t mind that plugin myself to use here ;-) Any chance you could send me the code and I’ll credit you with all the work plus hopefully show people how to do it on this site too.

    2. I’d like to second what Steve said: Is there any chance you could share the plugin, Patrick?

      It would help me solve a problem that has caused me a considerable amount of annoyance for roughly two months now :P .

      A WordPress plugin is exactly, spot on, what I’m looking for!

    1. Hi butch,

      I know – nothing I can do about that. I do mention that it should redirect the user to open in Mobile Safari by “sniffing” the user-agent string that comes down from a UiWebView request but that is the best I can do.

      All the best,

      Steve

  16. Will this work from a Google Apps Calendar – you can attach the VCard there as well.
    I ask because I don’t have a Mac to make this work with your solution.

    1. Hi Jim,

      I think you have misunderstood some of the article. You don’t need a Mac or special calendar software at all. I just showed how I created the vcard attached to a calendar appointment for information.
      Having worked out how to format the vcard in the calendar, I wrote the necessary PHP code to do it all for you (download or browse the source code/demo app).

      Hope this helps,

      Steve

  17. HI thank you very much for your effort and for this post…

    I have to implement exactly the same behaviour of the Donwload Contact To ANy Phone button.
    I downloaded the code but when i click on the button , download.php page is opened into the browser and nothing is downloaded .

    What did I miss ??

  18. Please its urgent,

    The code worked once on my iphone but now when i click the button “Donwload to any Phone” the page is reloaded and nothing else happen

  19. Hi all;
    I opened the link in Safari but Safari.php page is shown. I remove function isSafari I have ( Frame load interrupted) error. :(

    Any help please

  20. Hi Steve,
    I have another problem : Donwloading the contact file works fine on simulator 6.1 but not on 5.1.
    On 5.1 there is an error prompt: (Safari cannot download this file)

    What I ‘m doing wrong ?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>