练习 100 天:在移动 AIR 应用程序中构建社交功能

  • Ryan Stewart

2011 年 11 月 9 日

话题:Facebook架构

目录

需求

预备知识

ActionScript 和 Flex 知识。

需要的其他产品

用户水平

中级

需要的产品

将社交服务和功能(比如 Twitter 和 Facebook)整合到移动应用程序中,可以使你接触更多用户,同时迅速添加个性化特征。它还使您能够访问有关您用户的信息。您可以使用来自 Facebook 的真实用户姓名向用户祝贺,或者基于他们的兴趣自定义应用程序。与这些功能挂钩还使您能够将应用程序整合到他们的社交渠道中,发布到他们的公告栏或发布非他们的 Twitter 好友。我在我的应用程序“练习 100 天”中同时添加了对 Facebook 和 Twitter 的支持,希望分享我实现它们的方法,以便您也可以在您的应用程序中使用它们。

添加社交内容时的技巧

我希望与您分享以下技巧:

处理凭据

当添加 Facebook 和 Twitter 等社交内容时,您需要处理这些网站的用户名和密码。在几乎所有情况下,这些服务都不允许您仅从您的应用程序传递用户名 / 密码来验证用户。大部分服务都使用一种称为 Oauth 的服务的变体,该服务交换令牌,而不是直接交换用户名和密码。

Oauth 可能是一个非常深入的主题,但出于本文的用途。我将简短介绍一下它的工作原理。要做的第一件事是向您计划使用的服务(比如 Facebook)注册。然后,您将有一系列令牌和密钥,您将它们传递给登录 URL,以便该服务可确定您的应用程序是所请求的信息。然后会经历以下过程:

  • 用户使用他们的凭据登录服务的网站。
  • 用户授权应用程序访问他的数据。
  • 服务将用户重定向回拥有访问令牌的应用程序。
  • 应用程序保存访问令牌并代表用户访问服务。

此过程涉及到传递大量具体的 URL 参数并遵守 Oauth 的规范。Shannon Hicks为 ActionScript 开发人员创建了一个,可在此过程中提供很大帮助。我将在Twitter 集成一节中更详细地介绍。

使用 StageWebView

因为我们的应用程序无法直接登录服务,所以我们使用 StageWebView 提供直接登录服务的能力。这会阻止用户在我们的应用程序中键入用户名 / 密码,而直接在网站上键入它。

Facebook 集成

Adobe 与 Facebook 合作创建了一个 SDK,它专门用于在 Flash 和 Adobe AIR 应用程序内使用 Facebook Graph API。该 SDK 可帮助处理该过程的所有步骤,包括登录、询问具体的权限,以及发布到用户的 Facebook 公告栏。首先,访问Facebook 应用程序门户并创建一个新应用程序。Facebook 将为您提供一个应用程序 ID/API 密钥和一个应用程序秘密,您可以使用它们将 Facebook 与该 SDK 集成。

设置之后,使用上面的链接下载 Facebook ActionScript SDK,并将它添加到您的项目中。

连接到 Facebook

对于移动应用程序,您可以使用 FacebookMobile 类,它提供了用于从移动应用程序验证和访问数据的挂钩。在“练习 100 天”中,我有一个初始视图供用户用于连接 Facebook 和 Twitter。当加载该视图时,我调用 FacebookMobile 的 init() 方法传入我的应用程序 ID 并附加一个 onLogin 事件处理函数。

来自 Facebook 的事件比大部分 ActionScript 开发人员所习惯的事件更加通用。只有一个事件处理函数,它包含两个对象——success 或 fail。如果 success 为空,则表明初始化失败。否则,表明初始化成功。如果初始化调用成功,与用户相关的所有信息作为 success 对象的一部分返回,

我的“练习 100 天”中的代码仅仅检查我们是否已连接到 Facebook,如果是,我将禁用“Connect to Facebook”按钮并更改该标签。

protected function view1_viewActivateHandler(event: ViewNavigatorEvent): void {
    saveToDatabase(thisProfile);
    FacebookMobile.init("261265497221657", onLogin);
}
private function onLogin(success: Object,fail: Object): void {
    if (success) {
        btnFacebook.label = "Facebook Connected";
        btnFacebook.enabled = false;
    } else {
        trace('facebook error');
    }
} 

登录到 Facebook

整个过程最重要的部分是让用户登录。Facebook ActionScript SDK 采用的方式是,它创建一个 StageWebView 实例,该实例具有一个使用应用程序 ID 构建的特定 URL,所以它将该 Facebook 登录调用与您的应用程序相关联。然后用户使用在 SDK 中构造的 URL 直接登录到 Facebook。Facebook 处理授权过程并提示用户向您的应用程序授权。

在这里,您也可以请求具体的权限。默认情况下,一旦用户向您的应用程序授权,您就可以访问与用户相关的一些基本信息。对于任何提升的权限,比如发布到公告栏,您需要专门请求这些权限。这是使用传递给 login() 方法的权限数组完成的。这个页面描述了可请求的具体权限。

login() 方法也可获取 StageWebview 实例的一个特定的视口。默认情况下,StageWebview 会占据整个屏幕,但如果您出于任何原因(比如显示 ActionBar)而需要修改它,可以创建一个具体的视口矩形,FacebookMobile 窗口将使用该矩形。

因为 init() 函数已调用,所以应用程序已注册,您可以继续调用 login() 函数。Facebook ActionScript SDK 将创建正确的登录 URL,以便登录页面与应用程序相关联。以下是登录代码:

protected function view1_viewActivateHandler(event: ViewNavigatorEvent): void

{

    facebookWebView = new StageWebView();

    var view: Rectangle = new Rectangle(0, actionBar.height, stage.width, stage.height - 100 - actionBar.height);

    facebookWebView.viewPort = view;

    var permissions: Array = ["publish_stream"];

    FacebookMobile.login(onLogin, this.stage, permissions, facebookWebView);

}

上面的代码首先创建 StageWebView,然后创建一个矩形,该矩形考虑了 actionBar 的高度,所以 FacebookLogin 不会将它占满。然后我创建了一个权限数组,在本例中,我想要的唯一的提升权限是能够发布到用户的公告栏,我最后使用 FacebookMobile 类并调用 login() 方法。登录函数接受一个事件处理函数 onLogin,然后是 StageWebView 实例(也就是舞台)的父对象的引用,最后是我请求的任何提升的权限和一个具体的 StageWebView 实例。

onLogin 方法具有相同的输入,那就是 success/fail 对象,所以我可以检测登录是否成功。这个登录函数只有在整个过程完成后才会调用,所以用户必须登录到 Facebook,然后向应用程序授权。如果它们单击“Allow”按钮,onLogin 方法将使用一个 success 对象触发。如果它们单击“Deny”,那么它将使用 fail 对象触发。

private function onLogin(success: Object,fail: Object): void {
    if (success) {
        thisProfile.facebookConnected = true;
        thisProfile.facebookAccessToken = success.accessToken;
    } else {
        trace('error logging into Facebook');
    }
    btnContinue.enabled = true;
    btnContinue.label = "FINISHED";
}

如果验证成功,success 对象将包含一个 accessToken。这个 accessToken 就是您用于对 Facebook API 进行经过验证的调用的信息,包括发布到用户的公告栏。在“练习 100 天”中,我将 accessToken 存储在一个本地数据库中,以便我可以继续调用 Facebook API,而无需用户再次登录。

发布到用户的公告栏

用户验证并授权您的应用程序执行它需要的操作之后,您就可以开始直接调用 Facebook API 并与内容交互了。SDK 中支持完整的图形 API,但我将展示的发布到 Facebook 公告栏。

SDK 使用 api() 方法构造正确的 Facebook URL 并调用该 API。在本例中,我使用 /me/feed API 来发布到用户的源。以下是您调用的API 的完整列表。api() 方法还接受一个事件处理函数来处理调用的剩余部分,以及一个 params 对象。这个 params 对象使您确保 API 需要的任何参数(在本例中为公告栏发布的消息对象以及访问令牌)都已包含的地方。

var params: Object = new Object()
params.message = taStatus.text;
params.action_token = thisProfile.facebookAccessToken;
FacebookMobile.api("/me/feed", onPostStatus, params, "POST");

事件处理函数 onPostStatus 与您目前应该熟悉的监听器属于同一类型。它有两个相同的对象,success 和 fail,调用的结果就是哪个对象为空。

Twitter 集成

有许多用于 ActionScript 的第三方 Twitter 库,但因为 Twitter 仅适用标准的 OAuth 协议,所以 Shannon 创建的 oauth-as3 库的使用最简单。它可以完美地运行,可应用于使用 OAuth 的任何网站。

登录到 Twitter

取决于您使用移动 / 桌面应用程序还是 Web 应用程序,Twitter 验证可采用一些不同的形式。我使用的解决方案不一定是最完美的,但我感觉它是最符合 OAuth 协议的方式,同时也是一种不错的用户体验。在这个示例中,我使用 Twitter 基于 PIN 的验证,创建一个 StageWebView 窗口来登录并处理授权。然后用户将 PIN 键入到 StageWebView 上的一个 TextInput 框中,对 Twitter 进行一次 API 调用来获得一个可用于执行操作的 accessToken。

当您在Twitter 开发网站上设置一个 Twitter 应用程序时,您会获得一系列 API URL 和密钥,在验证过程中需要使用它们。我在我的代码中将它们设置为静态变量:

private var consumerKey:String = ""; private var consumerSecret:String = ""; private var twitterRequestURL:String = "https://api.twitter.com/oauth/request_token"; private var twitterAuthURL:String = "https://api.twitter.com/oauth/authorize"; private var twitterTokenURL:String = "https://api.twitter.com/oauth/access_token"; private var requestToken:OAuthToken; 

然后使用这些变量,您可以使用 oauth-as3 API 生成一个 OauthConsumer,它将为您提供一个可供用户用于登录的用户令牌。设置用户也就是使用从 Twitter 指定的 consumerKey 和 consumerSecret 创建一个 OauthConsumer 实例。然后您可以使用一个请求加载器构建请求并调用它。

consumer = new OAuthConsumer(consumerKey,consumerSecret);
var oauth:OAuthRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_GET,twitterRequestURL,null,consumer);
var request:URLRequest = new URLRequest(oauth.buildRequest(new OAuthSignatureMethod_HMAC_SHA1()));
var loader:URLLoader = new URLLoader(request);
loader.addEventListener(Event.COMPLETE,onLoaderComplete);

如果调用成功,返回对象包含构建 requestToken 所需的信息。使用该 requestToken,应用程序可构建一个授权请求,它将用户转到Twitter.com并要求它们登录。当它们登录时,它们将被提示向应用程序授权,然后将显示 PIN 编号。

protected function onLoaderComplete(event: Event): void {
    requestToken = OAuthUtil.getTokenFromResponse(event.currentTarget.data);
    var authRequest: URLRequest = new URLRequest('http://api.twitter.com/oauth/authorize?oauth_token=' + requestToken.key);

    twitterWebView = new StageWebView();
    twitterWebView.viewPort = new Rectangle(0, baseHeight, stage.width, stage.height - baseHeight);
    twitterWebView.stage = this.stage;
    twitterWebView.assignFocus();
    twitterWebView.loadURL(authRequest.url);
}

在这个函数中,我设置将显示 Twitter 网站的 StageWebView。使用 requestToken,我构建用于授权的 URL,并将该 URL 加载到 StageWebView 实例中。

现在,验证过程无需我们负责了。用户将通过 Twitter 网站上的步骤授权应用程序访问它们的数据,当该过程完成时,Twitter.com将显示一个 PIN 编号。用户必须将该 PIN 键入到应用程序中,然后应用程序使用该 PIN 调用 Twitter,以显示用户已授权它。

var params:Object = new Object();
params.oauth_verifier = tiPinNumber.text;

accessRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_GET,twitterTokenURL,params,consumer,requestToken);
var accessUrlRequest:URLRequest = new URLRequest(accessRequest.buildRequest(new OAuthSignatureMethod_HMAC_SHA1()));
var accessLoader:URLLoader = new URLLoader(accessUrlRequest);
accessLoader.addEventListener(Event.COMPLETE,onAccessRequestComplete);

我使用来自一个 TextInput 框(用户在其中键入 PIN)的文本值创建了一个 params 对象。然后,我使用该 params 对象、用户信息和请求令牌调用 twitterTokenURL。如果调用成功,Twitter 将为我们提供一个访问令牌,我们可以存储它并在后续 API 调用中使用它访问 Twitter。

protected function onAccessRequestComplete(event: Event): void {
    accessToken = OAuthUtil.getTokenFromResponse(event.currentTarget.data);
    thisProfile.twitterAccessKey = accessToken.key;
    thisProfile.twitterAccessSecret = accessToken.secret;
}

在“练习 100 天”中,我将访问密钥和访问秘密存储在数据库中,所以我随时可以在应用程序中使用它。下一步是使用这些信息向用户的 Twitter 渠道发布应用程序。

发布到 Twitter

发布到 Twitter 的过程需要构建一个用户(提供我们的应用程序特定的信息)和一个访问令牌(使用来自上面的调用的访问密钥和访问秘密),然后使用该信息创建一个 OAuthRequest。在该 OAuthRequest 内,您还需要传入状态更新文本。

params.status = taStatus.text;
var consumer:OAuthConsumer = new OAuthConsumer(consumerKey,consumerSecret);
var token:OAuthToken = new OAuthToken(thisProfile.twitterAccessKey,thisProfile.twitterAccessSecret);
var postRequest:OAuthRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_POST,twitterPostUrl,{status:taStatus.text},consumer,token);

var urlRequest:URLRequest = new URLRequest(postRequest.buildRequest(new OAuthSignatureMethod_HMAC_SHA1()));
urlRequest.method = URLRequestMethod.POST;

urlRequest.url = urlRequest.url.replace("&status=" + URLEncoding.encode(params.status),"");
urlRequest.data = new URLVariables( "status=" + taStatus.text );

var loader:URLLoader = new URLLoader(urlRequest);
loader.addEventListener(Event.COMPLETE,onTwitterPostComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR,onTwitterIOError);
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,onTwitterHttpStatus);

上面的代码中包含大量信息,但首先是设置 OAuth 调用。为了使该调用生效,您必须将状态变量添加到一个 URLVariables 对象中,所以我剥离出 URL 加密的状态,然后作为一个 URLVariable 附加到 URLRequest 的数据对象。

延伸阅读

现在您应该掌握了如何将 Facebook 和 Twitter 功能集成到您的移动应用程序中。验证工作流可能稍微有点复杂,但借助 Facebook,该 SDK 抽象了它的大部分内容,oauth-as3 库会负责 Twitter 的主要工作。

以下是一些有用的链接:

clip_image004+clip_image005

本作品依据Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License授权。与本作品中包含的示例相关,但超出本许可的权限可在Adobe上找到。

查看原文:100 Days of Exercise: Building social features into mobile AIR apps

Facebook架构