How to get data from non-http url on iOS - ios

I'm developing an app that gets RSS feeds from a website and the url has following form:
feed://feeds.<a_site_name>.org/...
As it isn't a http protocol so when I use NSURLConnection and NSUrlRequest to get data, it always returns nil data.
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:feedURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
NSOperationQueue *aqueue = [[[NSOperationQueue alloc] init] autorelease];
[NSURLConnection sendAsynchronousRequest:request queue:aqueue completionHandler:^(NSURLResponse *response, NSData *resultJsonData, NSError *error)
{
}];
I have used ASIHttpRequest third party library to get, it works but I don't want to use third party library here.
Can I use any given framework on iOS or any simple code to get?

A feed:// URL is really just an HTTP or HTTPS URL, but intended to be read by an app that knows how to handle RSS feeds. The way you solve this is to change the URL scheme to http (or https, if possible). For example:
NSURLComponents *components = [NSURLComponents componentsWithURL:feedURL
resolvingAgainstBaseURL:YES];
components.scheme = #"https";
feedURL = [components URL];
Then try that URL, and if it fails, change the scheme to http and try again.

Related

Invalid signed-request: Missing required parameter

I got the following response while getting my Photo from Instagram. Please help any help would be appreciated.
{
code = 403;
"error_message" = "Invalid signed-request: Missing required parameter 'sig'";
"error_type" = OAuthForbiddenException;
}
Here is my code
NSURL *url = [NSURL URLWithString:#"https://api.instagram.com/v1/tags/nofilter/media/recent?access_token=...........aef2"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error){
}
else {
NSString * a = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSDictionary *tokenData = [jResponse objectWithString:a];
NSLog(#"%#",tokenData);
}
}];
Looks like you have enabled Enforce Signed Requests, so it requires you to have sig parameter which is signature for API request, described here: https://www.instagram.com/developer/secure-api-requests/
Either generate the signature or disable Enforce Signed Requests
Looks like you are making API call from an app (client side), so it is not recommended to make signed request, since u have to save the client_secret in the app code. It is recommended to do this on the server to be secure. So just disable the Enforce Signed Requests for you app and make API call as is.
A continution for #krisrak answer.
To disable Enforce Signed Requests.
Goto https://www.instagram.com/developer/clients/manage/
Select your Client required. Go to Security.Uncheck the Enforce signed requests
And save the updated changes.

iOS Trying to call web service and I'm getting a NSURLErrorDomain error

I'm trying to connect to a web service that if I hit it through Safari I get back some json, but when I hit it through code I get a NSURLErrorDomain error with the following description.
"The certificate for this server is invalid. You might be connecting to a server that is pretending to be "url" which could..."
Here is the code:
NSURL *url = [NSURL URLWithString:#"webservice_url"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"GET"];
NSError *error = nil;
NSHTTPURLResponse *responseCode = nil;
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
Can anyone explain how to get around this? Also, it is a https web service.
The website doesn't have a HTTPS certificate. Try looking into this:
https://stackoverflow.com/a/15011030/4716039
In your code, the URLWithString value needs to be an actual URL. It is the same thing as going to Safari and typing in "webservice_url" as the entire URL instead of giving it the entire address. Instead you'll want to do something like the following:
NSURL *url = [NSURL URLWithString:#"https://www.urlgoeshere.com/getJSON"];
You can use like this -
NSURL *baseURL = [NSURL URLWithString:#"http://example.com/v1/"];
[NSURL URLWithString:#"foo" relativeToURL:baseURL];
// http://example.com/v1/foo

AFNetworking - add "image\jpeg" content type to AFImageResponseSerializer

I'm trying to load a picture from Facebook's source (a picture I've uploaded through my app and saved it's source).
I'm using AFNetworking to handle all my networking needs but when i'm trying to load a picture from:
http://fbcdn-sphotos-e-a.akamaihd.net/hphotos-ak-xfa1/v/t1.0-9/s720x720/10314676_10152739718934904_452946709678730535_n.jpg?oh=7e73d62e46c33e541e559e07e12bf275&oe=54B7E8CB&gda=1421866048_e364ab835ea15826e7ff28c8382ac085
(which opens in the browser, or in a regular http get request i'm setting in a http generator) but from the AFNetworking it always get a bad request (403) error..
I think that because the response from the server will be image\jpeg and i've ready that by default it doesn't work with AFNetworking..
How can i add it to the serialzer? or should i just write a new http request ?
imageView.imageResponseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"image/jpeg", #"image/jpg"];
I've ended up using:
-(void) loadPictureFromUrl:(NSString*)urlString {
NSURL* url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
[_httpRequestDelegate httpResponseReceived:nil responsedData:[[UIImage alloc] initWithData:data]];
else
[_httpRequestDelegate httpRequestReturnedError:nil withError:error];
}];
}
instead of fighting with AfNetworking - which is usually awesome but has an issue with what i'm trying to do

Prevent initWithContentsOfURL: from using cache

I'm using this line to get the contents of a URL:
NSString *result=[[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:URL]
encoding:NSUTF8StringEncoding
error:nil];
The problem is when there's a bad connection, it loads the contents from cache. Is there a way to avoid this behaviour? For example, clearing the cache or something.
First, it's not recommended to use initWithContentsOfURL:encoding:error to load data from a network resource.
Second, if you want to control caching behavior, you should be using an NSURLRequest. NSURLRequest allows you to customize the caching behavior of the request by setting the cachePolicy of the request. In your case, you want to use NSURLRequestReloadIgnoringLocalCacheData. An example of doing this synchronously using NSURLConnection would be:
NSString *result = nil;
NSData *data = nil;
NSURLResponse *response = nil;
NSURLError *error = nil;
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20L];
data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (response != nil && [data length] > 0){
result = [NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
Note that this is a very naive implementation that does not check the HTTP status code returned, the mime-type of the response, or perform any error handling. It is also not a recommended practice to load network resources synchronously or to do so from the main thread. A better implementation would use sendAsynchronousRequest:completion: or NSURLSession.
However, it does demonstrate at a high level what you would need to do to answer your question: The NSURLRequest specifies that this request should never use the local cache, and the returned data is used to create an instance of NSString.
Simple cache-buster dummy parameter with random value added to URL should work.
And as #Josh-Caswell said, use NSURLRequest. Although in case of proxy servers, just using NSURLRequest may not help and you will still need cache-buster.

ios sendAsynchronousRequest redirect basic auth

Is it possible to use the sendAsynchronousRequest of NSURLConnection knowing the requested url will have a redirect and all request must also use basic auth?
I am getting the following error: Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)
I did write some code using the NSURLConnectionDelegate and modified the redirect request to add the basic auth in the header and that worked.
So I'm guessing it has something to do with the authentication not being set on the second request. The same with the Delegate, If I didn't set the basic auth on the redirect request things were failing with a HTTP 401 unauthorized
It is possible I believe as I am doing it currently, here's my code, the trick is to set the header for "Authorization" with "Basic base64encodedmethod(username:password)"
//SETUP URL
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://YOURURLHERE"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:90.0];
//Get the username & password - then encode the values with Base64 (i googled for a library)
NSString *userAndPassword = [NSString stringWithFormat:#"%#:%#",userName,password];
NSString *encodedString = [userAndPassword base64EncodedString];
//Set the Authorization header which will now let your service calls pass basic authentication
[request addValue:[NSString stringWithFormat:#"Basic %#",encodedString] forHTTPHeaderField:#"Authorization"];
//Setup a queue and call the async request - remember to do items in your block on the
//main thread if it's for things like showing/hiding items as other threads will not run that code when you're expecting it
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
//your code block here
}];
I believe that answers your question, now I just need to find out how to delete that authentication so I can log the user out as I'm building this for a secure legal site. Any help there would be appreciated

Resources