Migrate restkit v0.20 - ios

Migrated to v0.20 and looks like RKClient deprecated.
Any idea how to set the user name and password? I used to do this in 1.0
[[RKClient sharedClient] setUsername:#"username"];
[[RKClient sharedClient] setPassword:#"password"];

Instead of the RKClient RestKit 0.20 now uses AFNetworking and it's client methods. However you can call the client of the RKObjectManager via HTTPClient, so setting the authorization header should be looking like
[[RKObjectManager sharedManager].HTTPClient setAuthorizationHeaderWithUsername:#"username"
password:#"password"];
For all other methods (authorization isn't listed there), check out the wiki document.

Related

Retrieving HTTPBody from RestKit response

I am using the postObject and putObject functions of restKit. I need to extract some info from the payload and put it in the header before sending it out.. any suggestions on how I can do that?
ex:
[[RKObjectManager sharedManager] postObject:object path:OBJECT parameters:nil success:success failure:failure];
I will probably have to do something like
// Create Payload for this request
// update header accordingly
// call postObject
I would like to avoid throwing away existing code..
I was able to do this by using all the params that I was passing before making the RK request.

Login form with AFNetworking 1.3

I am trying to login into a website through an HTML form using AFNetworking 1.3. I simply set my credentials and POST to the proper path. The problem is that I am not issued a cookie that states that I am logged in.
NSURL *baseURL = [NSURL URLWithString:#"https://mysite.edu"];
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:baseURL];
NSString *loginPath = #"/place/loginPage";
NSDictionary *loginParameters = #{#"sid" : #"username",
#"PIN" : #"12345678"};
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:#"POST"
path:loginPath
parameters:loginParameters
constructingBodyWithBlock:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success: %#", operation.responseString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", operation.responseString);
}];
[operation start];
The web server is returning a webpage that states that I do not have cookies enabled:
This system requires the use of HTTP cookies to verify authorization information.
Our system has detected that your browser has disabled HTTP cookies, or does not support them.
Please refer to the Help page in your browser for more information on how to correctly configure your browser for use with this system.
However, if I iterate through my issued cookies, I find that the website has issued me cookies, but not a session cookie. Therefore my AFNetworking client really is accepting cookies? Is there a setting that I must adjust to allow session cookies to properly work with AFNetworking 1.3?
I have edited my HTTP request header to match working browsers such as Chrome.
[Is] my AFNetworking client really [] accepting cookies? Is there a setting that I must adjust to allow session cookies to properly work with AFNetworking 1.3?
AFNetworking has no cookie-specific configuration. Cookies are solely the responsibility of the Foundation URL Loading system.
Some possible solutions:
Install AFHTTPRequestOperationLogger and configure it with AFLoggerLevelDebug to see all HTTP headers. This will let you see what's actually getting sent and received in your Xcode console.
The server may be dropping the cookie, for example if it's a Ruby server with protect_from_forgery enabled. Check your server logs and this solution for information on disabling or sending the appropriate token.
You control how requests use cookies with -[NSMutableURLRequest setHTTPShouldHandleCookies]. Make sure this is set to YES (the default.)
Other apps can alter the Cookie Accept Policy, so make sure -[NSHTTPCookieStorage cookieAcceptPolicy] is returning NSHTTPCookieAcceptPolicyAlways (or NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain if you need it.)
Since I came here while searching for a working solution for AFNetworking 2.0, not knowing that AFHTTPClient was removed from the Framework, I will post the new way to establish this connection here:
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://examplewebsite.com"]];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"userName" password:#"password"];

Can I use RestKit 0.20.3 to submit a request with OAuth parameters required by Yelp?

I am writing an iOS app that requests data from Yelp.
I currently have code that manages Yelp requests/responses and parses the JSON data returned internally. The current code builds the OAuth parameters for its requests using OAuthConsumer by Jon Crosby.
I came upon RestKit yesterday, and found it very appealing. It would probably eliminate much of the request submission and response parsing I am doing.
But I hit a roadblock, because I have not been able to figure out how to generate the OAuth parameters that Yelp requires with RestKit. I worked through the Ray Wenderlich RestKit tutorial at http://www.raywenderlich.com/13097/intro-to-restkit-tutorial, but it uses a client ID and client secret (as required by Foursquare).
Yelp requests need to have a consumer key, token, signature method, signature, timestamp and nonce. I have been unable to find an add-on for RestKit that can generate this particular set of OAuth parameters.
I am now generating my RestKit GET requests using an AFOAuth1Client developed by Matt Thompson. Now the Yelp API is returning an Invalid Signature error when I send a request.
I am puzzled because I have checked the fields in the HTTP Authorization header, and they look correct. The error seems to indicate that Yelp wants the oauth parameters in the URL, but the API documentation says that it is acceptable to send them in the authorization header.
Here is the Invalid Signature error I'm getting:
2013-08-26 15:34:54.806 RestKitYelpGroupon[2157:400b] E restkit.network:RKObjectRequestOperation.m:575 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 400" UserInfo=0xa876190 {NSLocalizedRecoverySuggestion={"error": {"text": "Signature was invalid", "id": "INVALID_SIGNATURE", "description": "Invalid signature. Expected signature base string: GET\u0026http%3A%2F%2Fapi.yelp.com%2Fv2%2Fsearch\u0026ll%3D32.893282%252C-117.195083%26oauth_consumer_key%3D(MY CONSUMER KEY)%26oauth_nonce%3DC0F25D91-B473-4059-B5F6-2D850A144A1D%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1377556409%26oauth_token%3D(MY OAUTH TOKEN)%26oauth_version%3D1.0%26term%3Dsushi"}}, AFNetworkingOperationFailingURLRequestErrorKey=http://api.yelp.com/v2/search?ll=32.893282%2C-117.195083&term=sushi>, NSErrorFailingURLKey=http://api.yelp.com/v2/search?ll=32.893282%2C-117.195083&term=sushi, NSLocalizedDescription=Expected status code in (200-299), got 400, AFNetworkingOperationFailingURLResponseErrorKey=}
Here is the code I am using to generate the requests:
NSURL *baseURL = [NSURL URLWithString:#"http://api.yelp.com/v2"];
AFOAuth1Client *oauth1Client = [[AFOAuth1Client alloc] initWithBaseURL:baseURL key:consumerKey secret:consumerSecret];
oauth1Client.accessToken = [[AFOAuth1Token alloc] initWithKey:tokenKey
secret:tokenSecret
session:nil
expiration:[NSDate distantFuture]
renewable:NO];
[oauth1Client registerHTTPOperationClass:[AFJSONRequestOperation class]];
// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[oauth1Client setDefaultHeader:#"Accept" value:#"application/json"];
RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:oauth1Client];
RKObjectMapping *couponMapping = [RKObjectMapping mappingForClass:[Coupon class]];
[couponMapping addAttributeMappingsFromDictionary:#{#"id" : #"id"}];
RKObjectMapping *businessMapping = [RKObjectMapping mappingForClass:[Business class]];
[businessMapping addAttributeMappingsFromDictionary:#{#"name" : #"name"}];
[businessMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"deals" toKeyPath:#"location" withMapping:couponMapping]];
RKResponseDescriptor * responseDescriptor = [RKResponseDescriptor
responseDescriptorWithMapping:businessMapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:#"response.venues"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
[objectManager getObjectsAtPath:#"http://api.yelp.com/v2/search"
parameters:queryParams
success:^(RKObjectRequestOperation * operaton, RKMappingResult *mappingResult)
Any further assistance is greatly appreciated!
Take a look at using AFOAuth2Client and setting it as the client when you init your RKObjectManager.

User Login With AFNetworking

I am building my first iOS app.
I have got the backend code done, but I am struggling with the Objective-C part of it.
I have a signup / login page.
But I don't know how to send that data to my server using Objective C.
I have read that AFNetworking is good, but I was wondering how I could use that for user login .
I have downloaded and added AFNetworking to my XCode Project and set up headers.
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://examplewebsite.com]];
[client setDefaultHeader:#"key" value:#"value"];
[client setAuthorizationHeaderWithUsername:#"username" password:#"password"];
[client setAuthorizationHeaderWithToken:#"token"];
NSURLRequest *request = [client requestWithMethod:#"someMethod" path:#"somePath" parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
but I am still lost.
Since you're trying to login to your own API, you don't want setAuthorization stuff. That's for basic HTTP auth. Instead you want to use getPath:parameters:success:failure or the postPath version, depending on if your backend is expecting HTTP GET or HTTP POST.
Pass your userid / password in the parameters argument. You should set parameterEncoding to be the correct format. You're probably using HTTP Forms url encoding, or JSON. Whatever your backend expects.
You don't want to set the authorization headers in this case, since this is for "basic access HTTP authentication", which is a method for a HTTP user agent to provide a user name and password when making a request to a server.
You want to use your own API and interact with a restful server and therefore, I would recommend, that you subclass AFHTTPClient -> interact with an API, Web Service, or Application. - Take a look at the examples in the AFNetworking zip archive, if you have difficulties in subclassing AFHTTPClient.
Since you want to create an app with user login, the app needs to send these information to your server, and the server should return if the login was succesful or not.
This can be done like so - HTTP POST.
- (void)login {
// Login information from UITextFields
id params = #{
#"username": self.usernameField.text,
#"password": self.passwordField.text
};
//Call the AFHTTP subclass client, with post block. postPath = the path of the url, where the parameters should be posted.
[[theAuthAPIClient sharedClient] postPath:#"/login"
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
//handle succesful response from server.
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// handle error - login failed
}
}];
}
You need to pass the parameters in the right format, depending on what format your server expects. This can be done by setting the right encoding in your AFHTTPClient subclass -> ParameterEncoding
Since I came here while searching for a working solution for AFNetworking 2.0, not knowing that AFHTTPClient was removed from the Framework, I will post the new way to establish this connection here:
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://examplewebsite.com"]];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"userName" password:#"password"];

RestKit Login problem

Can anyone give me a hint why I can not login into my service? I dont get an response to my delegate. The service is working. If I call the url in my browser I get a login (Browser receives a cookie) and then I can call request on my service:
Here is my Code:
RKClient *client =[RKClient clientWithBaseURL:#"https://myserverinstance/mobileapp/"];
NSString *loginString = #"SSO.login?application=myAppName&language=en&username=MyUserName&password=MyPassword&permanentLogin=true";
[RKClient setSharedClient:client];
if([[RKClient sharedClient] isNetworkAvailable]){;
NSLog(#"Network is available");
[[RKClient sharedClient] get:loginString delegate:self];
I'm assuming that the typos in your posted code (e.g. if([[RKClient sharedClient] isNetworkAvailable]){;) do not exist in your actual project.
Are your SSL certificates self-signed? If so, you'll need to set the RESTKIT_SSL_VALIDATION preprocessor directive. You'll also need to link against Security.framework.
If your certificates are signed by a common authority, then you should post more information about your problem. Turn RestKit logging on with RKLogConfigureByName("RestKit/Network", RKLogLevelTrace); and see if that provides any hints to where the problem really lies.

Resources