1
votes

I am just getting started with RestKit and have arrived just as Rk 0.20 is going live and the documentation and demo's are a step behind. Most stuff on the web is for RK 0.10 and there are big changes in the 0.20 version.

I don't want to fall back to an earlier version when the new one will very soon be up and running.

I have a JSON resource at a URL "test.myserver.com" that returns a simple datagram - { "id_user": "4401", "datalocation": "4401", "country": "Great-Britain", "data": "testdata", "login": "Fred Bloggs", "password": "579c0cb0ed2dc25db121283f7a98cc71", "accessLevel": "2", "timestamp": "1012", "datahash": "2749da29f20ce7a85092323f193adee8" }

I am pretty sure I have the Mappings etc sorted but my service requires authentication so I need to pass a user name and password in the request to the server.

I have got this so far

NSURL *url = [NSURL URLWithString:@"http://test.myserver.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
RKObjectRequestOperation *objectRequestOperation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[ responseDescriptor ]];

[objectRequestOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
RKLogInfo(@"Load collection of Articles: %@", mappingResult.array);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(@"Operation failed with error: %@", error);
}];

         [objectRequestOperation start];

Which appears to contact the server but inevitably logs the following error

restkit.network:RKObjectRequestOperation.m:296 Object request failed: Underlying HTTP request operation failed with error: Error Domain=org.restkit.RestKit.ErrorDomain Code=-1011 "Expected status code in (200-299), got 401" UserInfo=0x7884030 {NSLocalizedRecoverySuggestion={ "error": { "code": 401, "message": "Unauthorized: Authentication required" } }, AFNetworkingOperationFailingURLRequestErrorKey=http://elancovision.umfundi.com>, NSErrorFailingURLKey=http://elancovision.umfundi.com, NSLocalizedDescription=Expected status code in (200-299), got 401, AFNetworkingOperationFailingURLResponseErrorKey=}

The question of course is how I add the user name and password into the request.

Sorry for the noob question!

2
You need to know which protocol is used for authentication to the API. Could you precise it in your question? RESTKit relies on AFNetworking for its network layer. So you will have to deal with this library as far as authentication is concerned.JD_
Best I can tell you is that the server side was written in PHP using the restler libraries.nimbusgb
using 'BasicAuthenticaton'nimbusgb

2 Answers

6
votes

With basic HTTP authentication, username and password should be inserted into the HTTP request authorization header field for each request.

First, I suggest you to use RKObjectManager to centralize configuration for requests and mappings. http://restkit.org/api/latest/Classes/RKObjectManager.html RKObjectManager can store network parameters (through AFNetworking Library), then build appropriate http query based on username/password, paths, objectmapping.

Adapting your example, it would give something like :

NSURL* url = [[NSURL alloc]initWithString:@"http://test.myserver.com"];
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURL:url];
[objectManager.HTTPClient setAuthorizationHeaderWithUsername:@"username" password:@"password"];

//NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLRequest *request = [objectManager requestWithObject:nil method:RKRequestMethodGET path:@"/yourAPI/yourmethod" parameters:nil];

RKObjectRequestOperation *objectRequestOperation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[ responseDescriptor ]];

[objectRequestOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        RKLogInfo(@"Load collection of Articles: %@", mappingResult.array);
    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        RKLogError(@"Operation failed with error: %@", error);
    }];

[objectRequestOperation start];

If authentication works, having a look at the RESTKit wiki should give you the next hints to build correct mappings : https://github.com/RestKit/RestKit/wiki/Object-mapping

1
votes

My solution here:

// Build a RestKit manager object to look after the restful stuff
RKObjectManager *manager =  [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://test.myserver.com"]];;

// Hash the GUI input password string and pass the username in plain text
NSString *md5PW = [umfundiCommon md5:passwordField.text];           
[manager.HTTPClient setAuthorizationHeaderWithUsername:userField.text password:md5PW];

RKObjectMapping *WebResponse = [RKObjectMapping mappingForClass:[WSObject class]];

        [WebResponse addAttributeMappingsFromDictionary:@{@"id_user":@"id_user", @"datalocation": @"datalocation", @"country":@"country", @"data": @"data", @"login": @"login", @"password": @"password", @"accessLevel": @"accessLevel", @"timestamp": @"timestamp", @"datahash": @"datahash"}];

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:WebResponse pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
// Add the above response descriptor to the manager
[manager addResponseDescriptor:responseDescriptor];

// the getObject makes the call using the stuff assembled into the manager Object and drops into either the success or the failure routines.
[manager getObject:nil path:@"" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *result)
{
NSLog (@"Server WS call success:");

NSArray *theresults = [result array];              
for (WSObject *item in theresults) {
    NSLog(@"datahash=%@",item.datahash);
    NSLog(@"user_id=%@",item.id_user);
    }
}  failure:^(RKObjectRequestOperation * operation, NSError * error)
    {
    NSLog (@"Server WS call failure: operation: %@ \n\nerror: %@", operation, error);
    }];

........