- Finish setting up the OAuth2 protocol to access a user's GitHub account
- Add the following five files to this project from your completed version of the part one lab:
- AppDelegate.swift
- GitHubAPIClient.swift
- Info.plist
- LoginViewController.swift
- Secrets.swift
- Add the following methods to the GitHubAPIClient extension marked "OAuth"
// Start access token request process
class func startAccessTokenRequest(url url: NSURL, completionHandler: (Bool) -> ()) {
}
// Save access token from request response to keychain
private class func saveAccess(token token: String, completionHandler: (Bool) -> ()) {
}
// Get access token from keychain
private class func getAccessToken() -> String? {
return nil
}
// Delete access token from keychain
class func deleteAccessToken(completionHandler: (Bool) -> ()) {
}
At the end of the last lab you received a temporary code back from GitHub. You are going to use that code to make a request to GitHub for the access token.
- Inside the
safariLogin(_:)
method of theLoginViewController
, call thestartAccessTokenRequest(url:completionHandler:)
method from theGitHubAPIClient
. - Pass the URL received back from GitHub to the url parameter of the
startAccessTokenRequest(url:completionHandler:)
method. - Hint: Remember the notification argument passed in from
safariLogin(_:)
has the url stored in the object property. - Head over to the
GitHubAPIClient
class to define thestartAccessTokenRequest(url:completionHandler:)
method. - Use this order of tasks to define the method:
- Use the
NSURL
extension from theExtensions
file to extract the code. - Build your parameter dictionary for the request.
- "client_id": your client id
- "client_secret": your client secret
- "code": temporary code from GitHub
- Build your headers dictionary to receive JSON data back.
- "Accept": "application/json"
- Use
request(_:_:parameters:encoding:headers:)
from Alamofire to make a POST request using the.token
string from theURLRouter
, the parameter dictionary, and the header dictionary. - If the request is successful, print response and call
completionHandler(true)
, elsecompletionHandler(false)
.
- Use the
- Run the application to see if you are getting a successful response.
- Use
SwiftyJSON
to get the access token from the response you were working with in the previous step. - Call
saveAccess(token:completionHandler:)
to pass the access token you retrieved from the JSON data. - Define the
saveAccess(token:completionHandler:)
method using the Locksmith pod. Use the method,try Locksmith.saveData(["some key": "some value"], forUserAccount: "myUserAccount")
.- Key is "access token". Value is "token from response". User account is "github".
- The
completionHandler
should callback with true or false depending on whether the access token is successfully saved.
- Back inside the response section of the
startAccessTokenRequest(url:completionHandler:)
method, update the order of events to be:- Receive response
- Serialize JSON data using SwiftyJSON
- Call
saveAccess(token:completionHandler:)
method - If save succeeded, call the completion handler of
startAccessTokenRequest(url:completionHandler:)
with the appropriate response. - Run the application using print statements accordingly to see that everything is working correctly.
- Use the Locksmith method,
Locksmith.loadDataForUserAccount()
to retrieve the access token and return it. - Update the
starred(repoName:)
static function defined in theURLRouter
enum.starredURL
needs to be combined with the access token for user account requests.
- Update the
hasToken()
method to check if there is a token saved.- Use
getAccessToken()
to determine whether the method should returntrue
orfalse
.
- Use
- Reset the simulator and run the application. At this point you should be able to log in again. Stop the application. Run it again and you should be directed to the table view controller containing a list of repositories.
Resetting the simulator and rerunning the application will indicate if everything is working correctly but it's not ideal. There are a few more pieces to this puzzle that can make it complete. Here's what's left:
-
Login
- The
LoginViewController
starts the login process BUT theAppController
doesn't know about the outcome of the process. That means it doesn't know whether it should display the table view controller or not.startAccessTokenRequest(url:completionHandler:)
is called inside theLoginViewController
with a callback about whether the process succeeded. If it succeeds, post a notification using the appropriateNotification
name. TheAppController
already has the observer set up.
- The
-
Logout
- The
ReposTableViewController
has an IBAction for the log out button. This method needs to calldeleteAccessToken(_:)
fromGitHubAPIClient
and use the completion handler to determine whether to post a notification to theAppController
to close the table view controller.deleteAccessToken
still needs to be defined. It should delete the token and call back with the outcome.
- The