IOS 7 Facebook and Twitter Integration using SLRequest

From Techotopia
Revision as of 18:06, 11 May 2016 by Neil (Talk | contribs) (Text replacement - "<htmlet>ezoicbottom</htmlet>" to "")

Jump to: navigation, search
PreviousTable of ContentsNext
An iOS 7 Facebook Integration Tutorial using UIActivityViewControllerAn iOS 7 Twitter Integration Tutorial using SLRequest


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


Whilst the UIActivityViewController and SLComposeViewController classes provide a quick and easy way to integrate social network interaction into iOS applications, these classes lack the flexibility that might be required to implement more advanced integration. Perhaps the most significant shortcoming of these classes is the fact that they implement one-way communication with social networks. In other words, they can be used to post information to a social network, but do not provide a way to receive information, such as the entries in the timeline of a Twitter or Facebook account.

In recognition of this fact, Apple introduced the SLRequest class as part of the Social Framework included with iOS 7. Using the SLRequest class, in conjunction with the Accounts framework, it is possible to construct HTTP based requests and send them to the application programming interfaces (APIs) of Twitter, Facebook and Sina Weibo and receive data in response. This, in essence, allows an iOS application to perform just about any task allowed by the API of the respective social network service.

This chapter will provide an overview of the way in which the SLRequest class and the Accounts framework interact to provide social media integration. Once these basics have been covered, the next chapter will work through the implementation of an example application that uses SLRequest to query the entries in a Twitter timeline.


Contents


Using SLRequest and the Account Framework

Both the SLRequest class and the Accounts framework are required in order to interact with the API of a social network. Implementation follows a standard sequence of events which can be summarized as follows:

1. The application requests access to one of the user’s social network accounts as configured in the Settings app. This is achieved via a call to the requestAccessToAccountsWithType method of the ACAccountStore class, passing through as an argument the type of social network for which access is being requested together with a range of options depending on the target service.

2. An SLRequest instance is created and initialized with the URL required by the service for interaction, the HTTP request type to be used (GET, POST etc) and any additional parameters required by the API of the service.

3. The account object created in step 1 above is assigned to the account property of the SLRequest object created in step 2.

4. The request is sent to the target social network service via a call to the performRequestWithHandler method of the SLRequest object. The results from the request are passed to the handler code together with an Error object containing information about the reason for any failure.

Twitter Integration using SLRequest

Integration with the Twitter API begins with gaining access to an account, and is based on the assumption that at least one Twitter account has been configured via the Settings app on the device. Since iOS supports different social networks, the request must also include the type of social network for which access is being requested. This, in turn, is represented by an appropriately configured ACAccountType object.

The following code, for example, seeks access to the Twitter accounts configured on the device:

ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:   
		ACAccountTypeIdentifierTwitter];
        
[account requestAccessToAccountsWithType:accountType 
               options:nil 
               completion:^(BOOL granted, NSError *error)
{
             if (granted == YES)
             {
                  // Get account and communicate with Twitter API
             }
         }];
}

In the event that access is granted, an array of Twitter accounts on the device can be obtained via a subsequent call to the accountsWithAccountType method of the account object used for the request. The required account may then be extracted from the array of accounts for use in constructing an SLRequest object. The following code accesses the array of accounts, selects the last account entry and assigns it to twitterAccount:

ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:   
		ACAccountTypeIdentifierTwitter];
        
[account requestAccessToAccountsWithType:accountType options:nil 
               completion:^(BOOL granted, NSError *error)
{
     if (granted == YES)
     {
          NSArray *arrayOfAccounts = [account 
                 accountsWithAccountType:accountType];

          if ([arrayOfAccounts count] > 0)
          {
              ACAccount *twitterAccount = 
                    [arrayOfAccounts lastObject];
          }
     }];
}

The next task is to request an SLRequest object for Twitter access. This is achieved via a call to the requestForServiceType class method of the SLRequest class, passing through the following values:

  • The type of social network service for which the SLRequest will be used (in this case SLServiceTypeTwitter)
  • The HTTP request method type (SLRequestMethodPOST, SLRequestMethodGET or SLRequestMethodDELETE)
  • The URL required by the social network API for interaction
  • An NSDictionary object containing any parameters required by the social network API to complete the transaction.

The following code changes request an SLRequest instance configured for sending a Twitter update containing the text “My first Twitter post from iOS 7”:

ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:   
		ACAccountTypeIdentifierTwitter];
        
[account requestAccessToAccountsWithType:accountType options:nil 
               completion:^(BOOL granted, NSError *error)
{
     if (granted == YES)
     {
          NSArray *arrayOfAccounts = [account 
                 accountsWithAccountType:accountType];

          if ([arrayOfAccounts count] > 0)
          {
            ACAccount *twitterAccount = 
                     [arrayOfAccounts lastObject];

            NSDictionary *message = @{@"status": @”My First Twitter post from iOS 7”};
            
            NSURL *requestURL = [NSURL 
       URLWithString:@"http://api.twitter.com/1/statuses/update.json"];

            SLRequest *postRequest = [SLRequest 
                requestForServiceType:SLServiceTypeTwitter
                       requestMethod:SLRequestMethodPOST
                       URL:requestURL parameters:message];
          }
     }];
}

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

Finally, the account object needs to be assigned to the SLRequest object, and the request posted to the Twitter API:

ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:   
		ACAccountTypeIdentifierTwitter];
        
[account requestAccessToAccountsWithType:accountType options:nil 
               completion:^(BOOL granted, NSError *error)
{
     if (granted == YES)
     {
          NSArray *arrayOfAccounts = [account 
                 accountsWithAccountType:accountType];

          if ([arrayOfAccounts count] > 0)
          {
            ACAccount *twitterAccount = 
                  [arrayOfAccounts lastObject];

            NSDictionary *message = @{@"status": @”My First Twitter post from iOS6”};
            
            NSURL *requestURL = [NSURL 
 URLWithString:@"http://api.twitter.com/1/statuses/update.json"];

            SLRequest *postRequest = [SLRequest 
                requestForServiceType:SLServiceTypeTwitter
                       requestMethod:SLRequestMethodPOST
                       URL:requestURL parameters:message];

            postRequest.account = twitterAccount;

            [postRequest 
               performRequestWithHandler:^(NSData *responseData, 
               NSHTTPURLResponse *urlResponse, NSError *error)
            {
                  NSLog(@"Twitter HTTP response: %i", 
                      [urlResponse statusCode]);
            }];
          }
      }
}];

For the purposes of this example, the handler for the performRequestWithHandler method simply outputs the HTTP response code for the request to the console.

The above coding example demonstrates the steps involved in posting an update to a Twitter account using SLRequest. In the next chapter, an example application will be created that requests entries from the timeline of a Twitter account and displays those results in the TableView object.

For more information about the Twitter API, refer to the online documentation at:

https://dev.twitter.com/docs


Facebook Integration using SLRequest

To all intents and purposes, the steps to integrate with Facebook are the same as those for accessing Twitter with one or two significant differences. Firstly, any iOS application requiring access to the Facebook API must first be registered in the Facebook developer portal (http://developers.facebook.com). Registration includes providing the iOS bundle ID of the application (as defined when the application was created in Xcode). Once registered, the app will be assigned a Facebook App ID which must be referenced when seeking account access.

Additionally, the application may also declare the access permissions it requires whilst interacting with the API. A full list of permission options is available in the Facebook developer documentation online at:

https://developers.facebook.com/docs/authentication/permissions/

These permissions are declared using the ACFacebookPermission key. When defining permissions, the ACFacebookAudienceKey value must also be declared and set to one of the following values:

  • ACFacebookAudienceEveryone
  • ACFacebookAudienceFriends
  • ACFacebookAudienceOnlyMe.

The following code demonstrates the steps involved in posting a message to the user’s Facebook page:

#import "socialAppViewController.h"
#import <Accounts/Accounts.h>
#import <Social/Social.h>

@interface socialAppViewController ()
@property ACAccount* facebookAccount;
@end

@implementation socialAppViewController
.
.
.
- (IBAction)postMessage:(id)sender {

    ACAccountStore *accountStore = [[ACAccountStore alloc] init];

    ACAccountType *accountTypeFacebook = 
            [accountStore accountTypeWithAccountTypeIdentifier:
                      ACAccountTypeIdentifierFacebook];

    NSDictionary *options = @{
              ACFacebookAppIdKey: @"<YOUR FACEBOOK APP ID KEY HERE>",
              ACFacebookPermissionsKey: @[@"publish_stream",
                                          @"publish_actions"],
              ACFacebookAudienceKey: ACFacebookAudienceFriends
    };

    [accountStore requestAccessToAccountsWithType:accountTypeFacebook
                    options:options
                    completion:^(BOOL granted, NSError *error) {

                 if(granted) {

                       NSArray *accounts = [accountStore 
                         accountsWithAccountType:accountTypeFacebook];
                       _facebookAccount = [accounts lastObject];

                       NSDictionary *parameters = 
           @{@"access_token":_facebookAccount.credential.oauthToken,
             @"message": @"My first iOS 7 Facebook posting"};

                        NSURL *feedURL = [NSURL 
              URLWithString:@"https://graph.facebook.com/me/feed"];

                        SLRequest *feedRequest = 
                                [SLRequest
                        requestForServiceType:SLServiceTypeFacebook
                requestMethod:SLRequestMethodPOST
                URL:feedURL
                parameters:parameters];

                [feedRequest 
                    performRequestWithHandler:^(NSData *responseData,
                    NSHTTPURLResponse *urlResponse, NSError *error)
                    {
                        NSLog(@"Request failed, %@", 
                            [urlResponse description]);
                    }];
        } else {
            NSLog(@"Access Denied");
            NSLog(@"[%@]",[error localizedDescription]);
        }
    }];
}

When incorporated into an iOS application, the above code will cause a message to be posted to the user’s Facebook account which reads “My first iOS 7 Facebook posting”. Additional information on the Facebook API can be found online at:

https://developers.facebook.com/docs

Summary

Whilst the SLComposeViewController and UIActivityViewController classes provide an easy path to social network integration, they lack the flexibility and two-way communication needed by many applications. In order to gain greater flexibility in terms of integration, iOS includes the SLRequest class.

The goal of this chapter has been to provide a low level overview of the way in which the Accounts framework and SLRequest class can be used together to access and interact with Twitter and Facebook accounts using the service APIs of those social networks.


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book



PreviousTable of ContentsNext
An iOS 7 Facebook Integration Tutorial using UIActivityViewControllerAn iOS 7 Twitter Integration Tutorial using SLRequest