calling method webService (WCF) from iOS objective C) - ios

I want calling method webService by parameter Json from IOS, but I received an error.
Code Server Side (WCF):
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/test/{input}")]
int test(string input);
I want get input (parameter method and url) = typeof (Json)
Code Client Side (iOS-objective C) :
NSString *json = [self convertToJson:myObject];
NSString *urlComplete = [NSString stringWithFormat:#"%#%#",#"http://test.com/Service.svc/test/",json];
urlComplete = [urlComplete stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:urlComplete]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:
^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (data.length > 0 && connectionError == nil) {
NSString *string = [[NSString alloc]initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"Data Recived:\n %#",string);
}
else{
NSLog(#"Error %#",[connectionError description]);
}
}];
The webService is being tested by windowsPhone and returns OK but doesn't work with iOS.
Please help me!
thanks:)

Error description "HTTP Error 400. The request URL is invalid." clears that url you are passing is incorrect. Please cross check with windows team if they are appending the JSON to the get URL.
Generally, if you want to post data you can set the requestdata which is JSON and go for either a PUT or POST request instead of GET request.

Related

How to test if Json response includes error or proper json

Explanation: Throughout app, we use a web request method located in AppDelegate.m to fetch data from server. I use a token in all these requests. Sometimes the response from server is the json : {error = "token_not_provided"} or {error = "token_expired"}. I need a way to test if the json includes these errors or the proper json data. If the data sent back is either of these errors, we need to go back to login screen to get a new token upon login. Right now, I have no way to detect these errors in the request method so if they occur, the app will forever crash because there is no way to take you back to login. Here is the request method in App Delegate:
-(void)makeRequest:(NSString*)urlString method:(NSString*)method params:(NSMutableDictionary*)params onComplete:(RequestBlock)callback {
// create the url
NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/%#", BASE_URL, urlString]];
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url];
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:#"YourAppLogin" accessGroup:nil];
NSString *token = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
if(!token){
token = #"NO_TOKEN";
}
// set the method (GET/POST/PUT/UPDATE/DELETE)
[request setHTTPMethod:method];
[request addValue:[#"Bearer " stringByAppendingString:token] forHTTPHeaderField:#"Authorization"];
// if we have params pull out the key/value and add to header
if(params != nil) {
NSMutableString * body = [[NSMutableString alloc] init];
for (NSString * key in params.allKeys) {
NSString * value = [params objectForKey:key];
[body appendFormat:#"%#=%#&", key, value];
}
[request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
}
// submit the request
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError) {
// do we have data?
if(data && data.length > 0) {
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
// if we have a block lets pass it
if(callback) {
callback(json);
}
HERE IS WHERE I WANT TO TEST IF WE HAVE ERROR JSON or PROPER JSON
}
}];
}
If you can modify the interface on your server you could send a bool to identify if the request was successful. Something like "success" = 1 or 0.
To check on the error-message is dangerous, if the message changes your app will crash. If you want to do it anyway you need to check if the key "error" exists and then what it contains.
// Check if key is available.
if ([json.keys containsObject:#"error"]) {
if ([json[#"error"] isEqualToString:#"token_not_privided"] || [json[#"error"] isEqualToString:#"token_expired"]) {
// Token is invalid
} else {
// Something different went wrong.
}
}
// Nothing is wrong, lets inform the caller.
else {
if (callback) {
callback(json);
}
}
You should check on the json and not on the data.

SOAP services iOS

I wanted to call SOAP services, saw many document's over link.
I used one of those like the BestSoaptool from github https://github.com/yillars/BestSoapToolwithafnet, but I am still lacking some where and not able to get the response.
I am using the link as -- "https://aaa.com/Customers.svc?singleWsdl" and then the method name "xxx" but I don't get a response.
If not this can any one give me some better idea as to how should I implement this?
Thanks.
I've added sample SOAP implementation in iOS in my wordpress blog. Hope this will help you https://wordpress.com/post/bharathreddys.wordpress.com/6
Lets assume the following .wsdl url is the source URL.
http://www.webservicex.net/geoipservice.asmx?WSDL
Create a SOAP Envelop and SOAP Header.
NSMutableString * soapHeader = #"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\""
" xmlns:hom=\"http://www.webservicex.net/">"
"<soapenv:Header/>";
Be remember that "xmlns:hom", text next to ":" is the word which will be used as the targetnamespace reference for the service call which will be added in SOAP body.
SOAP body will be as follows :
[soapHeader appendString:#"<soapenv:Body>"];
[soapHeader appendString:#"<hom:GetGeoIP>"]; // add the body parameters
[soapHeader appendString:#"<hom:IPAddress>0.0.0.1</hom:IPAddress>"];
[soapHeader appendString:#"</hom:GetGeoIP>"];
[soapHeader appendString:#"</soapenv:Body>"];
[soapHeader appendString:#"</soapenv:envelope>"];
Now the web service is as follows:
NSMutableString * requestStr = [NSMutableStringstring];
[requestStr appendString:soapHeader];
NSString * urlStr = #"http://www.webservicex.net/geoipservice.asmx?WSDL";
NSURL * url = [NSURL URLWithString:urlStr];
NSMutableURLRequest * request = [[NSMutableURLRequestalloc] initWithURL:url];
[request setValue:#"http://www.webservicex.net/GetGeoIP" forHTTPHeaderField:#"SOAPAction"];
[request setValue:#"http://www.webservicex.net/" forHTTPHeaderField:#"targetNamespace"];
[request setValue:#"text/xml;charset=UTF-8"forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:requestBody];
[request setHTTPMethod:#"POST"];
[request setValue:[NSStringstringWithFormat:#"%d",[requestBody length]] forHTTPHeaderField:#"Content-Length"];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
BOOL isSuccess = YES;
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(#"received data---%#",response);
if(connectionError != nil) {
isSuccess = NO;
NSLog(#"connection error with code %d",connectionError.code);
}
NSDictionary * responseDictionary = [NSDictionary dictionary];
if([httpResponse statusCode] == 200) {
isSuccess = YES;
//Do something with the received dictionary.
}];
This is the basic platform how we can make a simple SOAP based web service calls in iOS.
Happy coding !!!!

Uploading image as base 64 string webservice response getting as html tags in iOS

I am uploading image along with user id to my server. So, i converted image into base 64 string. After conversion, i am sending to server along with user id. I have checked many forums for my isssue, but hopefully not helped me. I am using below code to sending server
In didFinishPickingMediaWithInfo delegate method
NSData *webData = UIImageJPEGRepresentation(chosenImage,90);
NSLog(#"webData -->%#",webData);
NSString *strEncoded = [Base64 encode:webData];
NSLog(#"strEncoded -->%#",strEncoded);
NSURL *url2 = [NSURL URLWithString:#"http://"]; //url
// NSString *base64ImageString = [imageData base64EncodedStringWithOptions:kNilOptions]; // iOS 7+
NSDictionary *jsonDictionary = #{#"user_id" : userIdString,
#"Image" : strEncoded,
};
NSError *error;
NSData *httpBody = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:&error];
NSAssert(httpBody, #"dataWithJSONObject error: %#", error);
NSMutableURLRequest *request2 = [NSMutableURLRequest requestWithURL:url2];
[request2 setHTTPMethod:#"POST"];
[request2 setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request2 setHTTPBody:httpBody];
NSLog(#"request2 -->%#",request2);
[NSURLConnection sendAsynchronousRequest:request2 queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!data) {
NSLog(#"sendAsynchronousRequest error: %#", connectionError);
return;
}
// use the `data` result here, e.g.
NSString *responseString2 = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"responseString2 = %#", responseString2);
}];
my request is successfully going to server, but i am getting response as below (html tags which is not correct response)
<!DOCTYPE html PUBLIC
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
etc some html tags, but i need to get server response as json data, server side everything is fine. they are telling my side problem in code.
I have tried many ways, but nothing useful to me. Please anyonce can give your valuable suggestions to me. Thanks in Advanced!

Find out character encoding of file without ending

The url below downloads a file without an extention including busstations and times. The data is fetched in an iPhone-app that displays bustimes called mobitime. The problem is that I can't find out what encoding the data is. Is there any way to find out?
Thanks!
http://d2.mobitime.se/cgi/mtc/sad?uuid=01b07052fa390ceb845405e3d0547f7e&r=4&id=191430&no=721&to=Odensbacken%20via%20Ekeby-Almby&lang=sv
There are two techniques that I know of:
You can look at the HTTP headers and see if it reports anything useful:
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (id)response;
NSLog(#"httpResponse.allHeaderFields = %#", httpResponse.allHeaderFields);
}
}];
Those headers report "Content-Type" = "text/plain"; which obviously is not the case.
Sometimes you can also use the usedEncoding option of one of the initWithContentsOfURL method:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSStringEncoding encoding;
NSError *error;
NSString *string = [[NSString alloc] initWithContentsOfURL:url usedEncoding:&encoding error:&error];
if (error)
NSLog(#"%s: initWithContentsOfURL error: %#", __FUNCTION__, error);
if (string)
NSLog(#"encoding = %d", encoding);
});
But that reports an error (suggesting, again, that this might not be a string encoding at all).
In short, I'd suggest you contact the provider of that web service, and ask them regarding the format. But looking at the hex dump, I don't recognize the format. With a passing glance at it, it looks like binary data, not any string encoding.

Web service method not hit when called via Objective C

My App_Code/IGetEmployees.vb file
<ServiceContract()> _
Public Interface IGetEmployees
<OperationContract()> _
<WebInvoke(Method:="POST", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.Wrapped, UriTemplate:="json/contactoptions")> _
Function GetAllContactsMethod(strCustomerID As String) As List(Of NContactNames)
End Interface
My App_Code/GetEmployees.vb file
<WebMethod()> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
Public Function GetAllContactsMethod(strCustomerID As String) As List(Of NContactNames) Implements IGetEmployees.GetAllContactsMethod
Utilities.log("Hit get all contacts at 56")
Dim intCustomerID As Integer = Convert.ToInt32(strCustomerID)
Dim lstContactNames As New List(Of NContactNames)
'I add some contacts to the list.
Utilities.log("returning the lst count of " & lstContactNames.Count)
Return lstContactNames
End Function
NContactNames is a class with 3 properties.
So i am using ASP.NET web services to retrieve information from SQL server and pass it to my iPad in JSON format. I have a problem with parameter passing. So like you see i have 2 files IGetEmployees.vb and GetEmployees.vb. I am implementing the method GetAllContactsMethod. What's happening is the two lines in GetEmployees.vb file (Utilities.log), they never get logged. The function is not getting called at all.
My objective c code to call this function
NSString *param = [NSString stringWithFormat:#"strCustomerID=%#",strCustomerID];
jUrlString = [NSString stringWithFormat:#"%#",#"http://xyz-dev.com/GetEmployees.svc/json/contactoptions"];
jurl = [NSURL URLWithString:jUrlString];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:jurl];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[param dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(#" request string is %#",[[request URL] absoluteString]);
NSLog(#"Done");
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if(theConnection)
{
jData = [NSMutableData data];
NSError *jError;
NSMutableDictionary *json =[NSJSONSerialization JSONObjectWithData:jData options:kNilOptions error:&jError];
NSLog(#"%#",json); //Gets Here and prints (null)
NSLog(#"Done"); //prints this as well.
}
else
{
NSLog(#"No");
}
At the time of posting this code the "if" statement is true and (null) is printed followed by "Done"
The output of my absolute request is:
request string is http://xyz-dev.com/GetEmployees.svc/json/contactoptions
This is the first time i am writing json to accept parameters. So i might be missing something.What is it?Why is the function not getting called at all on the Visual Studio side. If you need more info please ask.Thanks...
this is the moethod in Objetive-C, for that.
-(void) insertEmployeeMethod
{
if(firstname.text.length && lastname.text.length && salary.text.length)
{
NSString *str = [BaseWcfUrl stringByAppendingFormat:#"InsertEmployee/%#/%#/%#",firstname.text,lastname.text,salary.text];
NSURL *WcfSeviceURL = [NSURL URLWithString:str];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:WcfSeviceURL];
[request setHTTPMethod:#"POST"];
// connect to the web
NSData *respData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// NSString *respStr = [[NSString alloc] initWithData:respData encoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:respData
options:NSJSONReadingMutableContainers
error:&error];
NSNumber *isSuccessNumber = (NSNumber*)[json objectForKey:#"InsertEmployeeMethodResult"];
//create some label field to display status
status.text = (isSuccessNumber && [isSuccessNumber boolValue] == YES) ? [NSString stringWithFormat:#"Inserted %#, %#",firstname.text,lastname.text]:[NSString stringWithFormat:#"Failed to insert %#, %#",firstname.text,lastname.text];
}
}
Before to run the code, test your URL with POSTMAN, is an app from Google Chrome.
regards.

Resources