allow invalid certificates with AFNetworking - ios

I have been using following code
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
operation.allowsInvalidSSLCertificate=YES;
Now i have changed AFNetworking to latest version that is 2.0. operation.allowsInvalidSSLCertificate is not working anymore with AFHTTPRequestOperation. As per documents i used
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.securityPolicy.allowInvalidCertificates = YES;
and my request code is
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog (#"success: %#", operation.responseString);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error.description);
}
];
[operation start];
[operation waitUntilFinished];
But this is not working for HTTPS which require certificates. What should i do to make this work?

I solved this problem by adding following code before [operation start];
AFSecurityPolicy *sec=[[AFSecurityPolicy alloc] init];
[sec setAllowInvalidCertificates:YES];
operation.securityPolicy=sec;
This happened because AFHTTPRequestOperationManager is not connected to AFHTTPRequestOperation. So setting manager's security certificate can not do magic at requestOperation. So have to initialize and assign one to AFHTTPRequestOperation.
Hope this help somebody :)

As far as I know. It's an iOS 7 issue. Apple does not allow communication with self signed certificate websites. Unless you send the certificate to device and add as a trusted certificate list.
Supporting comment on other question: https://stackoverflow.com/a/20251011/753603
Couldn't find piece of documented text by Apple.

Related

AFNetworking http basic authentication gives error "Your API key was not formatted properly"

Trying to use the postmates api, but running into issues with authorization.
To quote their site:
AUTHENTICATION
The Postmates API requires authentication by HTTP Basic Auth headers.
Your API key should be included as the username. The password should
be left empty.
The actual header that is used will be a base64-encoded string like
this:
Basic Y2YyZjJkNmQtYTMxNC00NGE4LWI2MDAtNTA1M2MwYWYzMTY1Og==
I tried using AFNetworking like so
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"(my postmates key)" password:#"" persistence:NSURLCredentialPersistenceNone];
NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:#"GET" URLString:#"https://api.postmates.com/v1/delivery_zones" parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCredential:credential];
[operation setResponseSerializer:[AFJSONResponseSerializer alloc]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", error);
}];
[manager.operationQueue addOperation:operation];
The error message I'm getting is
Incorrect NSStringEncoding value 0x0000 detected. Assuming NSASCIIStringEncoding. Will stop this compatiblity mapping behavior in the near future.
Success: {
code = "invalid_authorization_header";
kind = error;
message = "Your API key was not formatted properly";
}
Instead of creating a credential, you might want to try:
[request setValue:#"Basic Y2YyZjJkNmQtYTMxNC00NGE4LWI2MDAtNTA1M2MwYWYzMTY1Og==" forHTTPHeaderField:#"Authorization"];

AFNetworking issue with UStream API request for channel's video list

This is probably something simple that I am just overlooking. I am trying to make an AFHTTPRequest from uStream's API using AFNetworking. I should be getting a JSON payload response back that lists all the videos on a uStream Channel. Here is my code:
NSURL *url = [NSURL URLWithString:#"https://api.ustream.tv/channels/12321320/videos.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failed");
}];
[operation start];
Everything works fine when testing in a browser but when trying to use AFNetworking I get a NSURLErrorDomain failure. Anyone have any suggestions?
My code was fine but there was an issue with my iphone simulator. Reset Content and Settings did the trick. Thanks to k6sandeep for the help.

AFNetworking and id reponseObject NOT working and not able to recover the content

After few days of job I am not able to solve this issue, I really need your help because I am completely locked, I start to be crazy!!!!!!. I have a project in Objective c for iOS where I get data from my server to put in my application. I have some trouble to recover and save data from JSON.
I would like to use "id responseObject", and save and use the content in another area in my project. Each time I try to use the following method and use "id responseObject" outside of "setCompletionBlockWithSucess" the "id responseObject" is (null), how can I do ?
NSURL *URL = [NSURL URLWithString:#"…."];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFJSONResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[[NSOperationQueue mainQueue] addOperation:op]
It sounds like you don't quite understand what scope is for variables. This project may be too advanced for you if that's the case. I urge you to read into scope + blocks to get a better understanding of what's going on.
What is happening is the setCompletionBlockWithSuccess is actually a block of code that gets executed if the URL request is a success. This means that responseObject is not immediately executed! It's being passed back some time after and you get access to it within setCompletionBlockWithSuccess. So that's why it's nil outside of the block.
To do what you're wanting is very simple. You need to read responseObject within the setCompletionBlockWithSuccess and set it to another variable that you have access to. Or you can immediately send it to another class to parse/save.
I haven't tested it, but I believe this should work with a simple JSON response. If not, use operation.responseString instead
NSString *jsonResponse;
NSURL *URL = [NSURL URLWithString:#"…."];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFJSONResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
jsonResponse = responseObject;
}
...

AFNetworking 2.0 and authorizing the Imgur API

Imgur's API requires that for simply looking up information about an image you just need to authorize your app with your API keys, no need to log in with an account or anything.
It says:
...all you need to do is send an authorization header with your client_id in your requests
Which apparently looks like:
Authorization: Client-ID YOUR_CLIENT_ID
So I tried doing this using AFHTTPRequestOperationManager, which appears to be the replacement for AFHTTPClient in AFNetworking 2.0 as shown below:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager POST:#"https://api.imgur.com/3/image/1Nf1quS" parameters:#{#"Authorization": #"Client-ID ---"} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];
Basically tried to send a request with authorization information (I removed my ID for this post). It keeps giving "failure" as a response however.
So I tried playing around with the credential property but NSURLCredential seems to be based off a username and password, and I have neither of those as I just need my client ID.
So I tried a completely different way again:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://api.imgur.com/3/image/1Nf1quS"]];
[request addValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"fail");
}];
This time using the authorization things as a value on the request. But this one actually never even logged anything.
I'm quite new to API use, so I'm really confused what I'm doing wrong.
Edit:
Try this code snippet
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager.requestSerializer setValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager GET:#"https://api.imgur.com/3/image/1Nf1quS" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];
I don't know about Imgur API, but for handling header and stuff, if you are just gonna do a few request to the API, you may add the headers just before the request operation. However, if you need to make API calls in more than one place, I think subclassing AFHTTPRequestOperationManager would be a better way to handle this.
For example you can create a subclass named MRTImgurRequestOperationManager:
#interface MRTImgurRequestOperationManager : AFHTTPRequestOperationManager
+ (MRTImgurRequestOperationManager*)sharedManager;
#end
and then in your implementation file:
+ (MRTImgurRequestOperationManager*)sharedManager
{
static MRTImgurRequestOperationManager *_sharedManager;
static dispatch_once_t _dispatchOnceToken;
dispatch_once(&_dispatchOnceToken, ^{
NSURL *baseURL = [NSURL URLWithString:#"API_URL_HERE"];
_sharedManager = [[MRTImgurRequestOperationManager alloc] initWithBaseURL:baseURL];
});
return _sharedManager;
}
- (id)initWithBaseURL:(NSURL*)url
{
self = [super initWithBaseURL:url];
if (self)
{
// Add headers or other options here
// For example
[self.requestSerializer setValue:#"VALUE" forHTTPHeaderField:#"HEADER_NAME"];
}
return self;
}
This way, you can add/remove HTTP headers without ever changing you code in couple of places. This may help with the testing as well.
So to use this, you would:
#import "MRTImgurRequestOperationManager.h"
and then make your Imgur request with the shared manager.
Edit:
You should use GET, not POST, with the API endpoint you are using
[[MRTImgurRequestOperationManager sharedManager] GET:#"path" parameters:params success:success failure:failure]];
In AFNetworking 2.0 you can set header fields. By using method from AFHTTPRequestSerializer
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
Try some thing like this:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager.requestSerializer setValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager POST:#"https://api.imgur.com/3/image/1Nf1quS" parameters:#{#"Authorization": #"Client-ID ---"} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];

IOS Enterprise updates over-the-air

hopefully this is an easy question, tho, I cannot find any specific answers.
we've gone thru all the steps to update our enterprise app OTA. My question is, can I use AFNetworking to make the call? or what is the best way to call the link. (currently afnetworking is giving me errors but it may be something on our side.) I am using afnetworking exclusively, so would rather not change unless I have to.
thanks in advance
itms-services://?action=download-manifest&url=http://ourServer/Setup/manifest.plist
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kiPADSetupLink]];
[request setTimeoutInterval:300];
NSLog(#"begin downloading app update");
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
// handle success
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
// handle error
} ];
[operation start];
No, you need the system to open that URL, you can't access it yourself. Use UIApplication's openURL: method.

Resources