使用iOS6 SDK在社交网站分享

Christine Abernathy,2012年10月15日

Christine Abernathy,Facebook开发者关系团队的工程师,非常友好地撰写了这篇关于如何在iOS 6上通过Facebook分享内容的好文章。让我们和她在评论区分享您的看法。

此外,如果您是第一次来到这里,我们提供的是iOS应用程序的最佳精选开源组件库。 查看我们的产品

— Aaron

顺便说一句,如果您喜欢这篇文章,请在Hacker News上 投票


苹果公司发布的iOS6 SDK增强了社交框架,允许您在Twitter以外的社交网站上分享。现在,您可以使用Apple SDK提供内置UI将内容、图片和图像分享到像Facebook和新浪微博这样的社交网站。

在本教程中,我将带您了解Facebook分享功能以及如何使用苹果提供的框架实现这些功能。


概述:社交功能

您有三种方式可以将内容分享到社交网站

  1. UIActivityViewController 类允许您的应用程序在上下文中提供多个服务,其中一个服务是向社交网站发布内容。
  2. SLComposeViewController 类更多针对社交网站,允许您的应用程序用户向这些网站撰写帖子。
  3. SLRequest 是您可以通过的第三种与社交网站集成的途径。这为您提供了针对这些网站的HTTP请求的包装方法,以执行类似于通过该网站提供的API直接通过API发布内容的服务。例如,发布到Facebook需要您向 http://graph.facebook.com/[FacebookUserId]/feed 端点发送HTTP POST 请求,其中包含您希望发布的数据。使用该类比前两种方法需要更多工作,但提供了更多的功能。

我将向您展示如何使用这些类将内容发布到Facebook和Twitter。以下是我会涵盖的主题领域

  • 通过分享表单分享
  • 通过composer分享
  • 通过社交媒体网站API(Facebook)分享
  • 通过社交媒体网站API(Twitter)分享

通过分享表单分享

使用 UIActivityViewController 是实现分享的最简单方法。它的范围很广,根据内容的类型提供分享内容的选项。例如,如果您传递共享文本的信息,用户将看到通过电子邮件、短信、Twitter、Facebook等方式共享的选项。再次强调,这是实现起来最简便的优势。

步骤 1:为您要将它启动的分享表单添加一个按钮。

  1. 前往您的 .xib 文件,并在视图中添加一个圆形矩形按钮。
  2. 在视图控制器实现文件中为此按钮添加一个操作。

步骤 2: 添加按钮后面的逻辑。

  1. 让我们找到一个你将用于分享的图片。找到你喜欢的图片(PNG 格式),下载它并将它拖入你的项目中。
  2. 找到在前面步骤中预先填充的操作方法。
  3. 添加以下代码
    NSString *message = @"Hello World!";
    UIImage *imageToShare = [UIImage imageNamed:@"test.jpg"];
    
    NSArray *postItems = @[message, imageToShare];
    
    UIActivityViewController *activityVC = [[UIActivityViewController alloc]
                                      initWithActivityItems:postItems
                                      applicationActivities:nil];
    
    [self presentViewController:activityVC animated:YES completion:nil];

步骤 3: 构建 & 测试

在 iOS6 模拟器上构建和运行项目。如果你是第一次使用模拟器,请登录你的 Facebook 和 Twitter 账户以测试这些社交网络的分享功能。你可以通过转到设备的“设置”应用并输入 Twitter 和 Facebook 的登录信息来登录。返回应用并重新启动它。点击按钮。当你点击按钮并选择 Facebook 然后 Twitter 时,你应该会看到类似以下内容

这是最简单的分享形式。现在让我们继续进行下一个步骤,使用 SLComposeViewController 类来限制分享网站选项仅为社交网络。


通过composer分享

如果你正在寻找一种简单的方法来实现针对一个或多个社交网站的用户分享,那么请查看 SLComposeViewController 类。你可以添加代码以直接分享到 Facebook、Twitter 和其他支持网站。

步骤 1: 添加额外的框架。

  1. 在 Xcode 中转到你的目标,然后点击 构建阶段 选项卡。
  2. 打开 链接二进制与库 部分。
  3. 添加 Social.framework。

步骤 2: 向你的视图添加要启动作曲家的按钮。

  1. 转到你的 .xib 文件,并在视图中添加两个圆角矩形按钮对象。一个将启动 Facebook 作曲家。第二个按钮将启动 Twitter 作曲家。
  2. 向你的视图控制器实现文件添加对两个按钮的操作。

步骤 3: 添加按钮后面的逻辑

  1. 找到在前面步骤中预先填充的操作方法,将其与 Facebook 绑定。
  2. 添加以下代码
    SLComposeViewController *fbVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
    
    [fbVC setInitialText:@"Hello Facebook"];
    [fbVC addURL:[NSURL URLWithString:@"https://developers.facebook.com/ios"]];
    [fbVC addImage:[UIImage imageNamed:@"test.jpg"]];
    
    [self presentViewController:fbVC animated:YES completion:nil];
  3. 找到在前面步骤中预先填充的操作方法,将其与 Twitter 绑定。
  4. 添加以下代码
    SLComposeViewController *twitterVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
    
    [twitterVC setInitialText:@"Hello Twitter"];
    [twitterVC addURL:[NSURL URLWithString:@"https://dev.twitter.com/docs"]];
    [twitterVC addImage:[UIImage imageNamed:@"test.jpg"]];
    
    [self presentViewController:twitterVC animated:YES completion:nil];

步骤 4: 构建 & 测试

在 iOS6 模拟器上构建和运行项目。点击 Facebook 作曲家按钮。你应该会看到类似以下内容

点击 Twitter 作曲家按钮。你应该会看到类似以下内容


通过社交媒体网站API(Facebook)分享

Facebook 提供了 APIs,允许你向其社交图谱写入数据。更多信息请访问Facebook 开发者网站

步骤 1: 创建一个 Facebook 应用

  1. Facebook 应用仪表板中创建一个新的应用,输入你的应用的基本信息。


  2. 创建后,注意在仪表板页面顶部显示的应用 ID。你稍后会用到它。
  3. 配置仪表板页面上的本地 iOS 应用设置。


  4. 在 Xcode 中打开你的应用的 .plist 文件,并确保你的束标识符与 Facebook 应用设置中的 Bundle ID 字段中的条目匹配。


步骤 2: 添加额外的框架。

  1. 在 Xcode 中转到你的目标,然后点击 构建阶段 选项卡。
  2. 打开 链接二进制与库 部分。
  3. 添加 Accounts.framework。

步骤 3: 添加一个按钮到你的视图,用于触发通过 Facebook API 的分享。

  1. 前往您的 .xib 文件,并在视图中添加一个圆形矩形按钮。
  2. 在视图控制器实现文件中为此按钮添加一个操作。

步骤 4: 添加按钮后面的逻辑。

当用户点击按钮时,你将允许用户向 Facebook 发布状态更新。这个流程将向您展示集成的基本部分。你将创建一个用于状态输入的非常简单的用户界面,使用配置为显示文本输入的 UIAlertView 实例。该 UIAlertView 将有一个提交和取消按钮。当用户点击提交时,你将要求额外的权限来发布帖子,然后使用 SLRequest 类调用 Facebook 图图谱 API 状态帖端点,传入状态消息的参数。

让我们继续添加代码来完成所有这些。

  1. ACAccountStore类提供对社交媒体网站帐户的访问。首先,在实现文件中为帐户存储设置一个私有属性,并生成该属性。
    // ....
    
    @interface ViewController ()
    @property (strong, nonatomic) ACAccountStore *accountStore;
    
    // ....
    
    @implementation ViewController
    @synthesize accountStore = _accountStore;
  2. 在你的viewDidLoad方法中初始化帐户存储实例。
    //....
    
    [super viewDidLoad];
    
    self.accountStore = [[ACAccountStore alloc] init];
  3. 在帐户存储中设置一个私有属性,该属性将代表Facebook用户。生成此新属性。
    // ....
    @property (strong, nonatomic) ACAccountStore *accountStore;
    @property (strong, nonatomic) ACAccount *fbAccount;
    
    // ....
    
    @synthesize accountStore = _accountStore;
    @synthesize fbAccount = _fbAccount;
  4. 设置一个私有属性,您稍后将其用于指示Facebook API请求。这为Twitter示例设置了基础。同时,生成此新属性。
    // ....
    
    @property (strong, nonatomic) ACAccount *fbAccount;
    @property (strong, nonatomic) NSString *slService;
    
    // ....
    
    @synthesize fbAccount = _fbAccount;
    @synthesize slService = _slService;
  5. 查找之前步骤中为Facebook API分享预先填充的动作。
  6. 将以下代码添加到该方法中,将<YOUR_APP_ID>替换为您的Facebook应用ID。
    // Set some default permissions
    
    NSArray *permissions = @[@"email"];
    
    // Set the dictionary that will be passed on to request account access
    
    NSDictionary *fbInfo = [NSDictionary dictionaryWithObjectsAndKeys:
                          @"<YOUR_APP_ID>", ACFacebookAppIdKey,
                          permissions, ACFacebookPermissionsKey,
                          ACFacebookAudienceOnlyMe, ACFacebookAudienceKey,
                          nil];
    
    // Get the Facebook account type for the access request
    
    ACAccountType *fbAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
    
    // Request access to the Facebook account with the access info
    
    [self.accountStore requestAccessToAccountsWithType:fbAccountType options:fbInfo completion:^(BOOL granted, NSError *error) {
       if (granted) {
           // If access granted, then get the Facebook account info
    
           NSArray *accounts = [self.accountStore accountsWithAccountType:fbAccountType];
    
           self.fbAccount = [accounts lastObject];
    
           // Set the service type for this request. This will be
           // used by the share input flow to configure it's UI.
    
           self.slService = SLServiceTypeFacebook;
    
           // Since this handler can be called on an arbitrary queue
           // will show the UI in the main thread.
    
           [self performSelectorOnMainThread:@selector(showSimpleTextInput) withObject:nil waitUntilDone:NO];
       } else {
           NSLog(@"Access not granted");
       }
    }];
  7. 请注意,当用户授予您的应用访问权限时,您将调用一个尚未定义的方法showSimpleTextInput。这是您向用户提供简单用户界面以输入状态更新的地方。在您的实际应用中,您可能会创建新的视图,以便使用户界面与Apple内置的UI相匹配。定义私有辅助方法,showSimpleTextInput
    - (void) showSimpleTextInput {
    
      // Define the alert view parameters
      // that depend on the service type
    
      NSString *title;
      NSString *shareButtonText;
    
      if ([self.slService isEqualToString:SLServiceTypeFacebook]) {
          title = @"Facebook";
          shareButtonText = @"Post";
      } else {
          title = @"Twitter";
          shareButtonText = @"Send";
      }
    
      UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:@"" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:shareButtonText, nil];
    
      // Set the alert view property to display a text input
      alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
    
      [alertView show];
    }
  8. 当您设置警报视图时,您将视图控制器实现文件配置为代理。这样,您就可以响应提交动作并发布状态更新。现在,将视图控制器实现类设置以符合UIAlertViewDelegate代理。
    @interface ViewController () <UIAlertViewDelegate>
  9. 实现响应按键点击的代理方法。在实现中,您将请求必要的publish_actionsFacebook权限进行状态发布。如果权限被授予,您将在定义下一个方法中进行实际请求。
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
      // Share button is index=1
    
      if (buttonIndex == 1) {
    
          if ([self.slService isEqualToString:SLServiceTypeFacebook]) {
    
              NSArray *permissions = @[@"email", @"publish_actions"];
    
              // Set the dictionary that will be passed on to request
              // account access
    
              NSDictionary *fbInfo = [NSDictionary dictionaryWithObjectsAndKeys:
                                      @"&lt;YOUR_APP_ID&gt;", ACFacebookAppIdKey,
                                      permissions, ACFacebookPermissionsKey,
                                      ACFacebookAudienceOnlyMe, ACFacebookAudienceKey,
                                      nil];
    
              // Get the Facebook account type for the access request
    
              ACAccountType *fbAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
    
              // Request access to the Facebook account with the access info
    
              [self.accountStore requestAccessToAccountsWithType:fbAccountType options:fbInfo completion:^(BOOL granted, NSError *error) {
                   if (granted) {
                       // If access granted, then get the Facebook account info
    
                       NSArray *accounts = [self.accountStore accountsWithAccountType:fbAccountType];
    
                       self.fbAccount = [accounts lastObject];
    
                       // Set the service type for this request. This will be
                       // used by the share input flow to configure it's UI.
                       self.slService = SLServiceTypeFacebook;
    
                       // Since this handler can be called on an arbitrary queue
                       // will show the UI in the main thread.
    
                       [self performSelectorOnMainThread:@selector(sendFacebookRequest:) withObject:[[alertView textFieldAtIndex:0] text] waitUntilDone:NO];
                   } else {
                       NSLog(@"Access not granted");
                   }
               }];
          }
      }
    }
  10. 与您之前添加的类似代码一样,将&lt;YOUR_APP_ID&gt;替换为您的Facebook应用ID。请注意,此代码与用户点击您的视图时添加的代码非常相似。iOS6 Facebook集成要求您最初请求读取类型权限。您无法在第一次请求时请求写入类型或发布类型权限。如果SDK返回错误,因此您需要在上下文中请求publish_actions权限,在这种情况下,当用户选择分享时,您会做到这一点。用户将看到一次性的权限请求警报。除非他们从iOS设置应用中删除Facebook登录信息或撤销对您的应用的权限,否则他们不会在设备上再次看到该权限弹出。如果他们使用另一个设备,他们将再次看到权限提示。
  11. 定义辅助方法sendFacebookRequest,该方法执行当用户授予您的应用访问权限时的API分享请求。
    - (void) sendFacebookRequest:(NSString *)message {
      // Put together the post parameters. The status message
      // is passed in the message parameter key.
    
      NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:message, @"message", nil];
    
      // Set up the Facebook Graph API URL for posting to a user's timeline
      NSURL *requestURL = [NSURL URLWithString:@"https://graph.facebook.com/me/feed"];
    
      // Set up the request, passing all the required parameters
      SLRequest *fbShareRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:requestURL parameters:params];
    
      // Set up the account for this request
      fbShareRequest.account = self.fbAccount;
    
      // Perform the request
      [fbShareRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
           // In the completion handler, echo back the response
           // which should the Facebook post ID
    
           NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
           NSLog(@"returned info: %@", response);
       }];
    }

步骤5:构建和测试

在iOS6模拟器上构建和运行项目。点击Facebook API分享按钮。您应该看到一个带有文本输入的警告弹出。输入一些文本并单击提交按钮。您的流程应如下所示


通过社交媒体网站API(Twitter)分享

Twitter提供了一组丰富的API,包括允许您更新当前用户状态API。更多信息请访问Twitter API资源

步骤1:向您的视图添加一个按钮,该按钮将通过Twitter API触发分享。

  1. 前往您的 .xib 文件,并在视图中添加一个圆形矩形按钮。
  2. 在视图控制器实现文件中为此按钮添加一个操作。

步骤 2: 添加按钮后面的逻辑。

当用户点击按钮时,您可以使用同样的UI流程来允许用户将状态更新发布到Twitter。您将重用为Facebook API分享创建的同一个UI流程。您将微调显示的UIAlertView。您还将使用SLRequest类调用Twitter API的状态更新端点,并传入状态消息的参数。

让我们继续添加这些修改的代码。

  1. 在帐户存储中设置一个私有属性,该属性将代表Twitter用户。生成此新属性。
    // ....
    @property (strong, nonatomic) NSString *slService;
    @property (strong, nonatomic) ACAccount *twitterAccount;
    
    // ....
    
    @synthesize slService = _slService;
    @synthesize twitterAccount = _twitterAccount;
  2. 找到上一步预先填充的用于Twitter API分享的动作。你添加的代码将请求账户存储中Twitter账户的访问权限。访问权限被授予后,你将调用之前定义的showSimpleTextInput方法来显示弹出窗口,用户可以在其中输入状态更新
    // Get the Twitter account type for the access request
    
    ACAccountType *twitterAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
    
    // Request access to the Twitter account with the access info
    [self.accountStore requestAccessToAccountsWithType:twitterAccountType options:nil completion:^(BOOL granted, NSError *error) {
       if (granted) {
           // If access granted, then get the Twitter account info
           NSArray *accounts = [self.accountStore accountsWithAccountType:twitterAccountType];
    
           self.twitterAccount = [accounts lastObject];
           self.slService = SLServiceTypeTwitter;
    
           // Since this handler can be called on an arbitrary queue
           // will show the UI in the main thread.
    
           [self performSelectorOnMainThread:@selector(showSimpleTextInput) withObject:nil waitUntilDone:NO];
       } else {
           NSLog(@"Access not granted");
       }
    }];
  3. 修改你之前实现的alertView:clickedButtonAtIndex方法,以检测来自Twitter的选择的更新。调用你将要定义的方法来发起Twitter API请求
    // ....
                       NSLog(@"Access not granted");
                   }
               }];
          } else if ([self.slService isEqualToString:SLServiceTypeTwitter]) {
              // Make a call to send the Twitter status update
              [self sendTwitterRequest:[[alertView textFieldAtIndex:0] text]];
          }
      }
    }
  4. 定义辅助方法sendTwitterRequest,该方法执行API状态更新
    - (void) sendTwitterRequest:(NSString *)message {
    
      // Put together the send parameters. The status message
      // is passed in the status parameter key.
    
      NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:message, @"status", nil];
    
      // Set up the Twitter API URL for posting to a user's timeline
      NSURL *requestURL = [NSURL URLWithString:@"https://api.twitter.com/1.1/statuses/update.json"];
    
      // Set up the request, passing all the required parameters
      SLRequest *twitterShareRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:requestURL parameters:params];
    
      // Set up the account for this request
      twitterShareRequest.account = self.twitterAccount;
    
      // Perform the request
      [twitterShareRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
    
           // In the completion handler, echo back the response
           // which should the Tweets object
    
           NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
           NSLog(@"returned info: %@", response);
       }];
    }

步骤 3: 构建 & 测试

在iOS6模拟器上构建和运行项目。点击Twitter API分享按钮。你应该会看到一个带有文本输入的弹出警告窗口。输入一些文本,然后点击提交按钮。你的流程应该如下所示


资源

访问Facebook开发者网站下载iOS的Facebook SDK,以及深入的iOS示例和代码片段。