使用iOS6 SDK在社交媒体网站分享

Christine Abernathy,2012年10月15日

Facebook开发者关系团队的工程师Christine Abernathy非常慷慨地写了这篇关于在iOS 6上通过Facebook分享内容的优秀文章。请在评论中告诉我们您的想法。

另外,如果您这是我们第一次来到这里,我们提供了最好收集的开源iOS应用组件。看看我们有什么要提供的!查看我们的阵容

— Aaron

顺便说一句,如果您喜欢这篇文章,请花点时间在Hacker News上给它投票:投票


苹果发布的iOS6 SDK增强了其社交框架,允许您将内容分享到除Twitter之外的其他社交媒体网站。现在,您可以使用苹果SDKs提供内置的UI将内容、图片和图片分享到社交网站,如Facebook和新浪微博。

在这篇教程中,我将向您介绍Facebook分享功能以及如何使用苹果提供的框架来实现它们。


概述:社交功能

您可以通过三种方式将内容分享到社交媒体网站

  1. UIActivityViewController 类允许您的应用程序在上下文中提供多项服务,其中包括将内容发布到社交媒体网站。
  2. SLComposeViewController 类更多地针对社交媒体网站,允许您的应用程序用户为这些网站编写帖子。
  3. SLRequest 是您可以用来与社交媒体网站集成的第三种方式。它提供了一种方式,可以将HTTP请求包装到这些网站,以便执行服务器操作,例如通过网站提供的API直接通过API分享内容。例如,将内容发布到Facebook需要您将HTTP POST发送到http://graph.facebook.com/[FacebookUserId>/feed端点,并包含您希望发布的数据。使用此类需要比前面两个更多的工作,但提供更多功能。

我将通过如何使用每个类来发布Facebook和Twitter上的内容进行指导。以下是我会涵盖的主题领域

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

通过分享表单分享

使用UIActivityViewController是实现分享的最简单方法。它的范围很广,使用户能够根据内容类型进行分享。例如,如果您传递的是文本分享的信息,用户将看到通过电子邮件、短信、Twitter、Facebook等进行分享的选项。优点在于实现简单。

第一步:在视图中添加一个启动分享表单的按钮。

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

第二步: adding the logic behind the button

  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类来缩小分享网站的选择,只保留社交网络。


通过作曲家分享

如果你寻找一种易于实现针对一个或多个社交网站的定向用户分享的方法,那么请看看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提供API允许你将信息写入其社交图谱。更多详情请访问Facebook开发者网站

步骤 1:创建Facebook应用

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


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


  4. 在Xcode中打开你的.app的.plist文件,确保你的bundle identifier与Facebook应用设置中的Bundle ID字段的条目相匹配。


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

  1. 在Xcode中转到你的目标,然后点击"构建过程"标签。
  2. 打开“链接二进制与库”部分。
  3. 添加Accounts.framework。

步骤 3:将按钮添加到你的视图中,以触发通过Facebook API进行分享。

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

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

当用户点击该按钮时,你将允许用户将状态更新发布到Facebook。此流程将向您展示集成的关键部分。您将为状态输入创建一个非常简单的用户界面,使用配置为显示文本输入的UIAlertView实例。该UIAlertView将有一个提交和取消按钮。当用户点击提交时,您将请求发布帖子的额外权限,然后使用SLRequest类调用Facebook Graph 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. 设置一个私有属性,你将稍后使用它来指示FacebookAPI请求。这为Twitter示例设置了基础。同样生成这个新属性。
    // ....
    
    @property (strong, nonatomic) ACAccount *fbAccount;
    @property (strong, nonatomic) NSString *slService;
    
    // ....
    
    @synthesize fbAccount = _fbAccount;
    @synthesize slService = _slService;
  5. 查找上一步预填充的FacebookAPI分享的动作。
  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:
                          @"&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(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. 在设置>alert视图时,配置你的视图控制器实现文件成为代理。这样你就可以响应提交动作并发布状态更新。现在,设置你的视图控制器实现类以符合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. 就像你之前添加的相似代码一样,将<YOUR_APP_ID>替换为你的Facebook应用ID。请注意,这段代码与你之前用户点击你的视图时添加的代码非常相似。iOS6 Facebook集成要求你最初请求读取类型权限。你不能第一次请求写入或发布类型权限。SDK将返回一个错误。因此,你需要在实际上下文中请求publish_actions权限,在这种情况下,当你用户明确选择分享时,用户将看到一个一次性权限请求警报。除非他们从iOS设置应用中删除Facebook登录信息或撤销你的应用的权限,否则他们不会在设备上再次看到权限弹出窗口。如果他们使用另一台设备,他们将再次看到权限提示。
  11. 定义辅助方法sendFacebookRequest,它通过向Facebook发布用户授予应用访问权限时执行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模拟器上构建并运行该项目。点击FacebookAPI分享按钮。你应该看到一个带文本输入的警报弹出。输入一些文本然后点击提交按钮。你的流程应该如下所示


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

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

步骤1:在你视图中添加一个按钮,该按钮将触发通过TwitterAPI分享的事件。

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

第二步: adding the logic behind the button

当用户点击该按钮时,你将允许用户将状态更新发布到Twitter。你将重用为FacebookAPI分享创建的相同的UI流程。你将在显示的UIAlertView中进行微小的UI调整。你还将使用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示例代码和代码片段。