从iOS端Facebook分享的预览效果到Open Graph Protocol(开放内容协议)

主要记录了在iOS端进行Facebook分享时遇到的一个问题.

设置Facebook分享的预览效果.

在iOS端将图片或链接分享至Facebook, 使用social框架即可非常方便地做到:

import social

func actionFacebookShare(sender: UIButton) {
    var controller: SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
    controller.setInitialText("分享的内容")
    controller.addURL(url) // 分享的网页
    // controller.addImage(imageToShare) // 分享的图片
    self.presentViewController(controller, animated: true, completion: nil)
}

然而, 在SLComposeViewController中, 却遇到了不能显示分享网页中的预览图片的情况.
一番搜索之后, 发现Facebook分享中的预览效果是通过在网页中设置一些特殊的meta数据来实现的.
参考如下链接:

facebook-sharing-best-practices

How does Facebook Sharer select Images and other metadata when sharing my URL?

其大意是:

Facebook has a set of open-graph meta tags that it looks at to decide which image to show.
The keys one for the Facebook image are:
and it should be present inside the <head></head> tag at the top of your page.

<meta property="og:image" content="http://ia.media-imdb.com/rock.jpg"/>
<meta property="og:image:secure_url" content="https://secure.example.com/ogp.jpg" />

即, 我们需要在网页中设置og:image作为预览图片, 另外, 还有og:title和og:description等其他所需的预览信息.
Facebook还贴心地提供了一系列的工具用于检测类似的情况.

tools-and-support

其中, Sharing Debugger专用于在FB上分享网页时的调试.
我们只需要输入分享链接, 即可查看分享的预览效果. 如下图:

facebook-share-debugger-1.png
facebook-share-debugger-2.png

可以看到关键的几个meta数据为og:title, og-description, og:image.
完整的meta数据如下:

<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0, user-scalable=no" />
<meta property="og:title" content="AirBrush: The Secret to a Perfect Selfie" />
<meta property="og:type" content="article" />
<meta property="og:description" content="Use Airbrush for a free, easy-to-use photo editor that lets you enhance your natural beauty without harsh filters." />
<meta property="og:image" content="http://xiuxiu.mobile.meitudata.com/tuiguang/airbrush/download/img/bg_en.jpg" />
<meta property="og:image:secure_url" content="http://xiuxiu.mobile.meitudata.com/tuiguang/airbrush/download/img/bg_en.jpg" />
<meta property="og:url" content="http://xiuxiu.mobile.meitudata.com/tuiguang/airbrush/download/en/" />

以上, 都是前端开发的同学需要在网页中添加的meta数据.
如果实在没办法添加呢, Facebook也在自己的分享SDK中添加了对应的解决方案:

FBLinkShareParams *params = [[FBLinkShareParams alloc] init];
params.link = [NSURL URLWithString:link];
params.name = title;
params.caption = title;
params.linkDescription = linkDescription;
params.picture = [NSURL URLWithString:pictureLink];

通过FBLinkShareParams可以添加分享网页的预览效果所需的meta数据.

那么, 看了这些后, 你肯定在想, 到底这个og是神马意思? 貌似之前接触的meta数据中没有这样的写法呢?
这就需要引入Open Graph Protocol了.

Open Graph Protocol

开放内容协议的主页: The Open Graph protocol.

The Open Graph protocol enables any web page to become a rich object in a social graph. For instance, this is used on Facebook to allow any web page to have the same functionality as any other object on Facebook.
While many different technologies and schemas exist and could be combined together, there isn't a single technology which provides enough information to richly represent any web page within the social graph. The Open Graph protocol builds on these existing technologies and gives developers one thing to implement. Developer simplicity is a key goal of the Open Graph protocol which has informed many of the technical design decisions.

即这种协议可以让网页成为一个"富媒体对象"。用了Meta Property=og标签,就是你同意了网页内容可以被其他社会化网站引用等,目前这种协议被SNS网站如Facebook、renren采用。
最基本的og标签有以下:

og:title - The title of your object as it should appear within the graph, e.g., "The Rock".
og:type - The type of your object, e.g., "video.movie". Depending on the type you specify, other properties may also be required.
og:image - An image URL which should represent your object within the graph.
og:url - The canonical URL of your object that will be used as its permanent ID in the graph, e.g., "http://www.imdb.com/title/tt0117500/".

此外, 还有一些标签如下:

og:audio - A URL to an audio file to accompany this object.
og:description - A one to two sentence description of your object.
og:determiner - The word that appears before this object's title in a sentence. An enum of (a, an, the, "", auto). If auto is chosen, the consumer of your data should chose between "a" or "an". Default is "" (blank).
og:locale - The locale these tags are marked up in. Of the format language_TERRITORY. Default is en_US.
og:locale:alternate - An array of other locales this page is available in.
og:site_name - If your object is part of a larger web site, the name which should be displayed for the overall site. e.g., "IMDb".
og:video - A URL to a video file that complements this object.

以及

og:image:url - Identical to og:image.
og:image:secure_url - An alternate url to use if the webpage requires HTTPS.
og:image:type - A MIME type for this image.
og:image:width - The number of pixels wide.
og:image:height - The number of pixels high.

Open Graph Protocol是Facebook主导的, 当然, 其他的一些公司可能有各自的一些格式, 如

<!-- for Google -->
<meta name="description" content="" />
<meta name="keywords" content="" />

<meta name="author" content="" />
<meta name="copyright" content="" />
<meta name="application-name" content="" />

<!-- for Facebook -->
<meta property="og:title" content="" />
<meta property="og:type" content="article" />
<meta property="og:image" content="" />
<meta property="og:url" content="" />
<meta property="og:description" content="" />

<!-- for Twitter -->
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="" />
<meta name="twitter:description" content="" />
<meta name="twitter:image" content="" />

因此, 再涉及到相关的使用场景时, 可去其各自的官网找寻.

其他问题

CDN

最后, 正确设置好了所有必须的Open Graph meta数据后, 还出现过Facebook分享预览效果不正确的情况, 诡异的是有的地区可以, 而有的地区却不行.
排查了之后, 发现是CDN相关的配置引起的, 可能需要做些网页部署相关的步骤.

可供参考的资料

facebook-sharing-best-practices
18 Meta Tags Every Webpage Should Have in 2013

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 167,395评论 24 706
  • 和煦:形容温暖的阳光。 版图:原指户籍和地图,今泛指国家的领土、疆域。 翩翩起舞:形容轻快地跳起舞来。载歌载舞、手...
    晨子超爱喝奶茶阅读 523评论 0 1
  • 今晚和我的男朋友聊了很多 突然才发现我和他之间的价值观实在是相差太多了,这个是我之前一直始料未及的。我总以为我们只...
    jinababy阅读 124评论 0 0
  • 服务器的多域名配置 1. 常用的WEB服务器有Apache和nginx,小编偏向使用nginx。日常开发机器使用的...
    OneTODO阅读 684评论 0 5
  • 忙碌,快节奏,往往会使人忘记快乐,忘记温柔。 做人一定要懂得关心身边的人,同事,普通人,陌生人…… 自己没付出爱是...
    成为富婆阅读 370评论 0 0