iOS 10 Facebook and Twitter Integration using SLRequest

From Techotopia
Revision as of 23:29, 9 November 2016 by Neil (Talk | contribs)

Jump to: navigation, search

PreviousTable of ContentsNext
An iOS 10 Swift Facebook Integration Tutorial using UIActivityViewControllerAn iOS 10 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 requestAccessToAccounts 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 perform(handler:) 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.

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

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:

let account = ACAccountStore()
let accountType = account.accountType(
        withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)

account.requestAccessToAccounts(with: accountType, options: nil, 
		completion: {(success, error) in

    if success {
	// 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 accounts(with:) 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:

let account = ACAccountStore()
let accountType = account.accountType(
        withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)

account.requestAccessToAccounts(with: accountType, options: nil, 
		completion: {(success, error) in

    if success {
        let arrayOfAccounts = 
		account.accounts(with: accountType)

        if arrayOfAccounts.count > 0 {
            let twitterAccount = arrayOfAccounts.last as! ACAccount
        }
    }
})

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

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 post from iOS 10”:

let account = ACAccountStore()
let accountType = account.accountType(
        withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)

account.requestAccessToAccounts(with: accountType, options: nil, 
		completion: {(success, error) in

    if success {
        let arrayOfAccounts = 
		account.accounts(with: accountType)

        if arrayOfAccounts.count > 0 {
            let twitterAccount = arrayOfAccounts.last as! ACAccount
	       let message = ["status" : "My first post from iOS 10"]
               let requestURL = URL(string: 
		  "https://api.twitter.com/1.1/statuses/update.json")

               let postRequest = SLRequest(forServiceType: 
			SLServiceTypeTwitter, 
			requestMethod: SLRequestMethod.POST, 
			URL: requestURL, 
			parameters: message)
        }
    }
})

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

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

let account = ACAccountStore()
let accountType = account.accountType(
        withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)

account.requestAccessToAccounts(with: accountType, options: nil, 
		completion: {(success, error) in

    if success {
        let arrayOfAccounts = 
		account.accounts(with: accountType)

        if arrayOfAccounts.count > 0 {
            let twitterAccount = arrayOfAccounts.last as! ACAccount
	       let message = ["status" : "My first post from iOS 10"]
               let requestURL = URL(string: 
		  "https://api.twitter.com/1.1/statuses/update.json")

               let postRequest = SLRequest(forServiceType: 
			SLServiceTypeTwitter, 
			requestMethod: SLRequestMethod.POST, 
			URL: requestURL, 
			parameters: message)

            postRequest.account = twitterAccount

	    postRequest?.perform(handler: {(responseData, urlResponse, 
				error) in

                if let err = error {
                    print("Error : \(err.localizedDescription)")
                }
                print("Twitter HTTP response \(urlResponse.statusCode)")
            })
        }
    }
})

For the purposes of this example, the handler for the perform(handler:) 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

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


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. First, 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 key which must be referenced when seeking account access.

Additionally, the application may also declare the access permissions it requires while 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:

let accountStore = ACAccountStore()
    let accountType = accountStore.accountType(
        withAccountTypeIdentifier: ACAccountTypeIdentifierFacebook)

let postingOptions = [ACFacebookAppIdKey:
                "<YOUR FACEBOOK APP ID KEY HERE>",
ACFacebookPermissionsKey: ["email"],
ACFacebookAudienceKey: ACFacebookAudienceFriends] as [String : Any]

accountStore.requestAccessToAccounts(with: accountType,
options: postingOptions as [NSObject : AnyObject]) {
    success, error in
    if success {

        let options = [ACFacebookAppIdKey:
            "<YOUR FACEBOOK APP ID KEY HERE>",
            ACFacebookPermissionsKey: ["publish_actions"],
            ACFacebookAudienceKey: ACFacebookAudienceFriends] as [String : Any]

        accountStore.requestAccessToAccounts(with: accountType,
            options: options as [NSObject : AnyObject]) {
                success, error in
                if success {
                    var accountsArray =
                    accountStore.accounts(with: accountType)

                    if (accountsArray?.count)! > 0 {
                        let facebookAccount = accountsArray?[0]
                                as! ACAccount

                        var parameters = Dictionary<String, AnyObject>()
                        parameters["access_token"] =
                            facebookAccount.credential.oauthToken 
						as AnyObject?
                        parameters["message"] = "My first Facebook post from iOS 10" as AnyObject?

                        let feedURL = URL(string:
                            "https://graph.facebook.com/me/feed")

                        let postRequest = SLRequest(forServiceType:
                            SLServiceTypeFacebook,
                            requestMethod: SLRequestMethod.POST,
                            url: feedURL,
                            parameters: parameters)

                        postRequest?.perform(handler: {(responseData, 
			urlResponse, error) in

                                print("Facebook HTTP response \(urlResponse?.statusCode)")
                        })
                    }
                } else {
                    print("Access denied")
                    print(error?.localizedDescription)
                }
        }
    } else {
        print("Access denied")
        print(error?.localizedDescription)
    }

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

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 Facebook post from iOS 10”.

Additional information on the Facebook API can be found online at:

https://developers.facebook.com/docs

Summary

While 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 10 Facebook Integration Tutorial using UIActivityViewControllerAn iOS 10 Twitter Integration Tutorial using SLRequest