I just want to hit URL :
http://kiascenehai.pk/rest_api/todayEvents/api-key/Of7NU7Jimh665D5G5VwO2eKO69sWv9lf/format/json
and parameter is city_id.i.e: /city_id/1 but; compiler creates Error
Domain=NSURLErrorDomain Code=-1002
"unsupported URL"
or
error 300;
so what shall be best way to pass arguments in a method in objective c???it also causes Error Domain=kCFErrorDomainCFNetwork Code=303 "The operation couldn’t be completed.
(kCFErrorDomainCFNetwork error 303
It will be pleasure for me if any one can reply me fast as possible.
Unable to reproduce issue you have mentioned, Probably the issue 'll be not because of the URL or parameters you used.
This is one of the best way to handle GET web service call and parsing data from the response, here i implemented the web call with your URL and params,
// Server data fetch
- (void)getDataForCityId:(NSInteger)cityId
{
NSMutableString *urlString = [#"http://kiascenehai.pk/rest_api/todayEvents/api-key/Of7NU7Jimh665D5G5VwO2eKO69sWv9lf/format/json/city_id/" mutableCopy];
[urlString appendFormat:#"%d", cityId];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
[request setHTTPMethod:#"GET"];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (data)
{
id jsonObj = [self parseJSON:data];
}
}];
}
// Method parses the JSON Data Received
- (id)parseJSON:(NSData *)data
{
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
return jsonData;
}
The jsonObj parsed form the response is as
Related
//Below is the code i have used to perform simple httpPOST. But app hangs on App launch on splash screen and crashes . i am doing an API Call on applaunch in Appdelegate
- (NSDictionary *)postUserRegWithUrl:(NSString *)urlString andParams:(NSString *)paramString{
NSString * encodedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)paramString,
NULL,
(CFStringRef)#"+",
kCFStringEncodingUTF8 ));
NSDictionary *responseDictionary;
NSError *err;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#%#",kBaseProdURL,urlString]]];
NSData *data = [encodedString dataUsingEncoding:NSUTF8StringEncoding];
[request setTimeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:data];
NSLog(#"the data Details is =%#", request);
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
NSLog(#"got response==%#", resSrt);
if(resSrt.length)
{
responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&err];
NSLog(#"Response dictionary formed is =%#", responseDictionary);
} else {
NSLog(#"failed to connect");
[self showAlertViewTitle:#"Please try later" withMessage:#"Something went wrong"];
}
return responseDictionary;
}
You shouldn't execute your network calls synchronously, especially on main thread. Either use sendAsynchronousRequest or just use any good networking library, like AFNetworking, which do this out of the box.
First set the timeoutInterval for your request. if your request takes more time then you have to stop the api call and inform the user with proper error message.
For example:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:1200.0];
Don't use Synchronised Request. It will block your main thread.
If your network is slow or server is not responding then your app will take more time to load. Which is not good for the user experience.
Remember, your app’s load time is your first chance to impress your users.
Use Asynchronised Request of the NSURLConnection. Handle the response in the api completion block.
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSString *resSrt = [[NSString alloc]initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"got response==%#", resSrt);
if(resSrt.length)
{
responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&err];
NSLog(#"Response dictionary formed is =%#", responseDictionary);
} else {
NSLog(#"failed to connect");
}
}];
Change queue:[NSOperationQueue mainQueue] parameter based on your need.
queue -> An NSOperationQueue upon which the handler block will
be dispatched.
I am trying to construct a POST request with certain parameters in the body of the message but am struggling with handling / seeing the response.
This is the request I am trying to recreate in Obj C:
I am somewhat familiar with the code to create this request but am struggling with parsing the response into meaningful data. This is what my method currently looks like for this (it appears to be Successful):
NSLog(#"WEB SERVICE CALLED!");
NSURL *aUrl = [NSURL URLWithString:#"xxx"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
NSString *postString = #"grant_type=password&username=xxx&password=xxx";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection= [[NSURLConnection alloc] initWithRequest:request
delegate:self];
if(connection) {
NSLog(#"Connection Successful");
} else {
NSLog(#"Connection could not be made");
}
}
How can I see what my response is? Thanks in advance for any help!
UPDATE
I added this bit and can see that my response gives me a code 200 (success) but the data object looks like it needs to be serialized as it looks like a hex string. This is what I am doing to handle the response / data / error:
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// your data or an error will be ready here
NSLog(#"RESPONSE: %#",response);
NSLog(#"DATA: %#",data);
NSLog(#"ERROR: %#",error);
}];
This is what the log for the data object looks like:
NSError *error;
id obj= [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (!obj) {
NSLog(#"JSON parse error: %#", error);
} else {
NSLog(#"obj= %#", obj);
}
I am getting the following error when running my code from the xcode.
Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x17166b740
{NSErrorFailingURLStringKey=https://..../move/resource/v1/user/me/activity/summary?start_date=2015-01-21&end_date=2015-01-14&detail=true,
NSUnderlyingError=0x17405b630 "The operation couldn’t be completed.
(kCFErrorDomainCFNetwork error -1012.)",
NSErrorFailingURLKey=https://..../move/resource/v1/user/me/activity/summary?start_date=2015-01-21&end_date=2015-01-14&detail=true}
Here is my Code
NSString *urlSummaryString = [[NSString stringWithFormat: #"%#summary?start_date=%#&end_date=%#&detail=true", kMisfitCloudEndpoint, strStartDate,strEndDate] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
__block NSMutableDictionary *responseDict = [NSMutableDictionary dictionary];
__block NSError *error = nil;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlSummaryString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
[request setValue:#"access_token" forHTTPHeaderField:self.misfitAccessToken];
[request setHTTPMethod:#"GET"];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if(connectionError){
// Handle the connection error
return ;
}}];
Can any one help me what is wrong here. Is it something related to SSL Certificate on the server and is related to the security. When I use CocoaRestClient to make my request it works perfectly.
Can some body explain me in detail what cause this problem or if any body can have the solution for this. I have to use [NSURLConnection sendAsynchronousRequest] method. I am using Xcode 6.1 and ios 8.1.2
In my case i am making a very silly mistake.
[request setValue:self.misfitAccessToken forHTTPHeaderField:#"access_token" ];
This solved my problem
This is kCFURLErrorUserCancelledAuthentication error,
-10xx errors are of the CFNetworkErrors enum.
Name of this constant is pretty selfexplanatory. Server cancelled authentication for some reason
When I query the google datastore (after authenticating from iOS) - the response from my NSURLConnection is 'Not Found'. I am expecting to see something like 'missing parameters from post', or like on this site, where it says '503 service unavailable' or something like that.
https://developers.google.com/apis-explorer/#s/datastore/v1beta2/datastore.datasets.runQuery
The code is
NSString *url = #"https://www.googleapis.com/datastore/v1beta2/datasets/MYDATASETID/runQuery?key=MY_API_KEY";
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
NSString *stringData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"response is %#", stringData);
}];
Where MYDATASETID is my actual project name. And I am getting these instructions for this url from the site:
https://developers.google.com/datastore/docs/apis/v1beta2/datasets/runQuery
thanks
The answer for me to get a response was to set 'POST' as the HTTP Method, for example:
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:fullUrl]];
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[someData dataUsingEncoding:NSUTF8StringEncoding]];
Note though that this does not fully solve my challenge because although I get a response, the response from my variable stringData is
Login Required
And the error in NSError *connectionError is
Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x8e20690 {NSErrorFailingURLKey=https://www.googleapis.com/datastore/v1beta2/datasets/MY_APP_ID/runQuery?key=MY_APPS_API_KEY, NSErrorFailingURLStringKey=https://www.googleapis.com/datastore/v1beta2/datasets/MY_APP_ID/runQuery?key=MY_APPS_API_KEY, NSUnderlyingError=0x8d6f120 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)"}
I'm writing an iPad app that needs to communicate with a backend server. The first order of business in using this backend is to login, and for this the server has a URL that we can POST to, which I do like this:
// Create the request.
NSString* loginURL = #"http://foo.local/signature/service/auth/rest/firewall/login";
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:loginURL]];
NSString* credentials = #"{\"userName\":\"foo2#foolinator.com\", \"password\":\"password\"}";
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[credentials dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES]];
// Logging in...
NSError* error = nil;
NSURLResponse* response;
NSData* result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
NSString* responseString = [NSHTTPURLResponse localizedStringForStatusCode:[httpResponse statusCode]];
NSLog(#"Response String is: %#\n", responseString);
NSLog(#"Header fields are: %#\n", [httpResponse allHeaderFields]);
What's odd is that the response I'm getting is Error 405: Method Not Allowed. I would've expected this if I was doing a GET, but I'm doing a POST.
I installed WireShark to examine the HTTP requests and it seems that there's actually two being made. The first one, is a POST call, and the server returns some cookie information as a response, and then a second GET call, which is what the code above gets back.
Why does this happen? Is it something to do with the response from the server the first time?
While you research your web service's login API, a couple of unrelated observations:
You should be sending this asynchronously if doing this from the main queue. Never issue synchronous network requests from the main queue. If you do this synchronously on the main queue (a) you risk having the iOS watch-dog process kill your app, which happens if the main queue becomes unresponsive while some synchronous network request is being processed; and (b) it's a bad UX to simply freeze an app during a network request ... if you need, disable the UI and show an indeterminate progress indicator (a UIActivityIndicatorView) while the network request is in progress.
You should probably be setting a value forHTTPHeaderField for Content-Length. It's probably not required, but it's good practice.
You probably should not be using a string with the JSON with the userid and password, but rather you should probably build this from a NSDictionary using something like NSJSONSerialization. As it is, if your password, for example, had any characters that needed to be escaped (e.g. a quotation mark), the existing code might not work. Using NSJSONSerialization is an easy way to ensure that your JSON is properly formatted.
You probably should not be sending a password in plaintext in your JSON request. At the very least, I hope your server employs HTTPS.
Anyway, with these observations, assuming your server really is expecting a JSON request, I might suggest something like:
// hopefully your production server is employing HTTPS
NSString *loginURL = #"https://foo.local/signature/service/auth/rest/firewall/login";
// use NSJSONSerialization to create JSON rather than building it in a NSString
NSDictionary *postDictionary = #{#"userName": userName, #"password": password}; // assuming you have NSString variables, `userName` and `password`
NSError *error = nil;
NSData *postData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:&error];
NSAssert(postData, #"dataWithJSONObject failed: %#", error);
// when creating request, also set Content-Length
NSURL *url = [NSURL URLWithString:loginURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
[request setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
// issue request asynchronously
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
NSLog(#"sendAsynchronousRequest error: %#", connectionError);
return;
}
// process the server response here
}];
You might still want to use a NSURLConnectionDataDelegate/NSURLConnectionDelegate based request (you can identify redirects, challenges, cancel it if you need, etc.), but the above might be a good start at an asynchronous JSON-based request.