Objective-C custom resource-request implementation sample

An Objective-C sample for acquiring data from a protected resource by using the MobileFirst WLAuthorizationManager class.

The sample contains two methods of a class that implements NSURLConnectionDelegate. The sample implements a standard OAuth flow: first, a resource request is sent without an access token. This request is expected to fail with an authorization error. Then, WLAuthorizationManager is used to obtain an access token for the resource's protecting scope, and the request is sent again with the obtained access token as an authorization header. The resource request is created by using a standard NSMutableURLRequest object.

/**
 * Sends a request to access the specified protected resource.
 **/
- (void) sendRequest {
    // Set the resource URL
    NSString *resourceString = @"http://localhost:3000/MyResource/MyProtectedProcedure";
    
    // Create the request to access the resource URL
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:resourceString]];
    
    if(_accessToken) {
        // Add an access token to the request
        [request addValue:_accessToken.asAuthorizationRequestHeaderField forHTTPHeaderField:@"Authorization"];
    }
    
    // Create a URL connection that sends the request. The response is returned via the connection:didReceiveResponse delegate.
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

/**
 * NSURLConnectionDelegate didReceiveResponse method, which implements the MobileFirst OAuth authorization flow.
 **/
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    WLAuthorizationManager *authorizationManager = [WLAuthorizationManager sharedInstance];
    
    // Check whether access to the resource requires authorization
    if([authorizationManager isAuthorizationRequiredForResponse:response]) {
        
        // Get the status from the response
        int status = (int)[(NSHTTPURLResponse *)response statusCode];
        NSString *scope;
        
        switch (status) {
            case 401: // Invalid-token error (invalid_token)
                // Clear the access token (if exists)
                [authorizationManager clearAccessToken:_accessToken];
                break;
            case 403: // Insufficient-scope error (insufficient_scope)
                // Get the resource scope from response
                scope = [authorizationManager resourceScopeFromResponse:response];
                break;
            case 409: // Server-conflict error
                // Resend the request
                [self sendRequest];
                return;
            default: // Authorization-server error
                NSLog(@"%@",@"Error from the authorization server");
                return;        
        }
        
        // Obtain an access token for the scope from the authorization server
        [authorizationManager obtainAccessTokenForScope:scope withCompletionHandler:^(AccessToken *accessToken, NSError *error) {
            if (!error) {
                // Save the access token
                _accessToken = accessToken;
                [self sendRequest];
            } else {
                // Error obtaining an access token
                NSLog(@"%@",[error localizedDescription]);
            }
        }];
    }
    else { // The resource does not require authorization
        // Initialize an object that will be used to receive the response data from the resource
        _responseData = [[NSMutableData alloc] init];
        NSLog(@"Meta-data response from resource: %@",[response description]);
    }
}