Access SQL database from an iPhone app Via RESTful WCF service - ios

I have created a small project that can read and insert data from iPhone to sql server via RESTful WCF service.
I have read the data successfully with the following approach:
1- I have created a wcf web service that read data from Sql serverwith table Employees(firstname,lastname,salary):
"41.142.251.142/JsonWcfService/GetEmployees.svc/json/employees"
2- I have created a new project in xcode 5.0.2, and I added a textfield (viewData.text) to display data retrieved by the web service.
3- I added the following instruction in my viewController.m :
"#define WcfSeviceURL [NSURL URLWithString: #"41.142.251.142/JsonWcfService/GetEmployees.svc/json/employees"]"
3- In (void)viewDidLoad method, I implemented the below code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:WcfSeviceURL options:NSDataReadingUncached error:&error];
if(!error)
{
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
NSMutableArray *array= [json objectForKey:#"GetAllEmployeesMethodResult"];
for(int i=0; i< array.count; i++)
{
NSDictionary *empInfo= [array objectAtIndex:i];
NSString *first = [empInfo objectForKey:#"firstname"];
NSString *last = [empInfo objectForKey:#"lastname"];
NSString *salary = [empInfo objectForKey:#"salary"];
//Take out whitespaces from String
NSString *firstname = [first
stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *lastname = [last
stringByReplacingOccurrencesOfString:#" " withString:#""];
viewData.text= [viewData.text stringByAppendingString:[NSString stringWithFormat:#"%# %# makes $%#.00 per year.\n",firstname,lastname,salary]];
}
}
}
Check the following link : http://www.codeproject.com/Articles/405189/How-to-access-SQL-database-from-an-iPhone-app-Via.
As I mentioned, I can read the data from my iPhone without any problem.
So the second step is how to write and insert data from the iPhone to sql server.
for this, I created first the method that insert data in my webservice:
In WCF interface:
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "json/InsertEmployee/{id1}/{id2}/{id3}")]
bool InsertEmployeeMethod(string id1,string id2, string id3);
In Implementation:
public bool InsertEmployeeMethod(string id1,string id2, string id3)
{
int success = 0;
using (SqlConnection conn = new SqlConnection("server=(local);database=EmpDB;Integrated Security=SSPI;"))
{
conn.Open();
decimal value= Decimal.Parse(id3);
string cmdStr = string.Format("INSERT INTO EmpInfo VALUES('{0}','{1}',{2})",id1,id2,value);
SqlCommand cmd = new SqlCommand(cmdStr, conn);
success = cmd.ExecuteNonQuery();
conn.Close();
}
return (success != 0 ? true : false);
}
So to test this web servcie method use:
"41.142.251.142/JsonWcfService/GetEmployees.svc/json/InsertEmployee/myName/MylastName/6565"
Then to consume this method from iPhone I used the following approach:
I decalared the Define Instruction:
"#define BaseWcfUrl [NSURL URLWithString:
#"41.142.251.142/JsonWcfService/GetEmployees.svc/json/InsertEmployee/{id1}/{id2}/{id3}"]"
Then I implemented the Insert Employee Method related to click button.
-(void) insertEmployeeMethod
{
if(firstname.text.length && lastname.text.length && salary.text.length)
{
NSString *str = [BaseWcfUrl stringByAppendingFormat:#"InsertEmployee/%#/%#/%#",firstname.text,lastname.text,salary.text];
NSURL *WcfServiceURL = [NSURL URLWithString:str];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:WcfServiceURL];
[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];
}
}
But the issue here, is in the following instruction:
NSString *str = [BaseWcfUrl stringByAppendingFormat:#"InsertEmployee/%#/%#/%#",firstname.text,lastname.text,salary.text];
Always the system returns a message 'Data parameter nil' with this line, knowing that the firstname.text, and lastname.text, salary are all filled and I can see their values with NSLog(#"First Name :%#",firstname.text)...
Can you please help on this?
Thanks in advance.

I don't think NSURLs stringByAppendingFormat will do what you want.
Try something like this:
#define kBase_URL #"41.142.251.142/JsonWcfService/GetEmployees.svc/json/%#"
#define kAuthAPI_InsertEmployee_URL [NSString stringWithFormat:kBase_URL, #"InsertEmployee/%#/%#/%#"]
//Setup session
NSError *error;
NSURL *requestURL = [NSURL URLWithString:[NSString stringWithFormat:kAuthAPI_InsertEmployee_URL,firstname.text,lastname.text,salary.text]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
NSData *postData = [NSJSONSerialization dataWithJSONObject:profileData options:0 error:&error];
[request setHTTPBody:postData];
etc. etc.

Related

Load data from MySQL in iOS app

Good morning,
How can I load a MySQL query result into a UILabel in my iOS app? I need to display the name of the user, the followers and also the profile image. How can I do that?
I have created the storyboard with the UILabels and the UIImageView but now I need to load the data from my MySQL database and I'm a little bit lost.
Thanks in advance.
You can get data with JSON.
NSMutableURLRequest * requestTransfer;
NSString *strUrl = #"www.yoursite.com/Mobile/GetUser";
requestTransfer = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:strUrl]
cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
[requestTransfer setValue:#"gzip" forHTTPHeaderField:#"Accept-Encoding"];
[requestTransfer setHTTPMethod:#"POST"];
NSHTTPURLResponse * response;
NSError* error = nil;
response = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:requestTransfer returningResponse:&response error:&error];
NSDictionary *dicUsers = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
You can use dictionary like that.
NSString* strID = [dictionary objectForKey:#"UserID"];
NSString* strName = [dictionary objectForKey:#"UserName"];
NSString* strLink = [dictionary objectForKey:#"ImageLink"];
yourlabel.text = strName;

How to get cookie from a url in iOS?

I have an application where I have to create session using a URL and need to get cookie from that URL and pass the cookie to webview so that it won't ask for any username and password.
For that I am using this code:
- (void)getcookie {
NSURL* aUrl =
[NSURL URLWithString:#"https://www.sessioncheck.com/session/create"];
NSMutableURLRequest* request =
[NSMutableURLRequest requestWithURL:aUrl
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30.0];
NSString* email = #"tina#gmail.com";
NSString* password = #"abcde#123";
NSString* combinedString =
[NSString stringWithFormat:#"%#:%#", email, password];
NSString* base64encodedstring =
[NSString stringWithBase64EncodedString:combinedString];
NSData* base64data = [NSData dataWithBase64EncodedString:combinedString];
[request addValue:[NSString stringWithFormat:#"Basic %#", base64encodedstring]
forHTTPHeaderField:#"Authorization"];
[request setHTTPMethod:#"GET"];
NSError* error = nil;
NSData* returnData = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil
error:&error];
if (returnData != nil) {
NSDictionary* JSONDictionary =
[NSJSONSerialization JSONObjectWithData:returnData
options:kNilOptions
error:&error];
}
}
This is my Android code. I am able to get cookie in Android:
HttpGet get;
try {
get = new HttpGet(
new URI("https://www.sessioncheck.com/session/create"));
byte[] encodedBytes = Base64.encodeBase64((email+":"+password).getBytes());
//System.out.println("encodedBytes " + new String(encodedBytes));
get.setHeader("Authorization", "Basic " + new String(encodedBytes));
http.execute(get);
List<Cookie> cookies = ((DefaultHttpClient)http).getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
cookie = cookies.get(i);
}
String cookieString = cookie.getName() + "=" + cookie.getValue();
signedin.storeCookie("cookie", cookieString);
}
I am trying to get the base64encoded string from my combinedString(username:password) but the problem is my base64encodedstring is returning nil.
Did you use this code: https://github.com/nicklockwood/Base64 ?
If you did then you should use - (NSString *)base64EncodedString; instead.
So your code should look like this:
NSString* base64encodedstring = [combinedString base64EncodedString];
NSData* base64data = [base64encodedstring dataUsingEncoding:NSUTF8StringEncoding];
About cookies, you can get them from "returningResponse" outgoing parameter of -[NSURLConnection sendSynchronousRequest:returningResponse:error:].
You should pass an address of a NSHTTPURLResponse pointer into it.
So your code should be like this:
NSHTTPURLResponse *res = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&res
error:&error];
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[res allHeaderFields]
forURL:aUrl];
EDIT : As you requested, to set cookies into a NSMutableURLRequest, you have to use the NSArray *cookies from above. Here is the code:
// Use the cookies from the code above
NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:newURL];
[req setAllHTTPHeaderFields:headers];
// Do your other setups here...

getting error when calling objectFromJSONString using JSONKit

I use the following code to create a dictionary based on a JSON string received from the server. (I have downloaded JSONKit and embedded it into the project). The code below returns a legal JSON string from the server (parsed well on Android) but crashes when I try to convert it to a dictionary.
- (IBAction)submit
{
bool useSSL = true;
char *c_url="http://(rest of URL)";
NSString* url = [NSString stringWithFormat:#"%s" , c_url];
url = [NSString stringWithFormat:#"%#%#%s", url, self.label.text, "/keys"];
NSString * response = [self getDataFrom:url];
NSDictionary *dict = [response objectFromJSONString]; //generates SIGABRT!!
NSLog(#"%#",dict);
NSString *success = [dict valueForKey:#"success"];
}
- (NSString *) getDataFrom:(NSString *)url{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"GET"];
[request setURL:[NSURL URLWithString:url]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *responseCode = nil;
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
if([responseCode statusCode] != 200){
NSLog(#"Error getting %#, HTTP status code %i", url, [responseCode statusCode]);
return nil;
}
return [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
}
THANKS,
Simon
Found an answer here.
Answer says: "Figured it out... I had JSONKIt.h included in the project but for some weird reason, JSONKit.m was not included in the 'Compile Sources' under 'Build Phases' - once I added it manually it started working fine."

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.

ios parsing json result after http request

am starting to build login form reading from external server via http request i need to parse json result to get user name
- (IBAction)getlogin:(UIButton *)sender {
NSString *rawStrusername = [NSString stringWithFormat:#"username=%#",_username.text];
NSString *rawStrpassword = [NSString stringWithFormat:#"password=%#",_password.text];
NSString *post = [NSString stringWithFormat:#"%#&%#", rawStrusername, rawStrpassword];
// NSString *post = #"rawStrusername&rawStrpassword";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
/* NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]]; */
NSURL *url = [NSURL URLWithString:#"http://www.othaimmarkets.com/my_services_path/user/login.json"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
/* [request setValue:postLength forHTTPHeaderField:#"Content-Length"]; */
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSLog(#"responseData: %#", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
//NSLog(#"responseData: %#", responseData);
}
I get this result:
{"sessid":"g2ev7til6d750ducrkege0cbj2","session_name":"SESS02795057fe9e6b2fc0777bf4057b248f","user":{"uid":"617","name":"mohammed.abdelrasoul#gmail.com","mail":"mohammed.abdelrasoul#gmail.com","mode":"0","sort":"0","threshold":"0","theme":"","signature":"","signature_format":"0","created":"1316602317","access":"1352643854","login":"1352666338","status":"1","timezone":"10800","language":"ar","picture":"","init":"mohammed.abdelrasoul#gmail.com","data":"a:5:{s:18:\"country_iso_code_2\";s:2:\"SA\";s:13:\"timezone_name\";s:11:\"Asia/Riyadh\";s:5:\"block\";a:1:{s:7:\"webform\";a:1:{s:15:\"client-block-88\";i:1;}}s:13:\"form_build_id\";s:37:\"form-3ae73833f08accc7abe5517347ea87eb\";s:7:\"contact\";i:0;}","country_iso_code_2":"SA","timezone_name":"Asia/Riyadh","block":{"webform":{"client-block-88":1}},"form_build_id":"form-3ae73833f08accc7abe5517347ea87eb","contact":0,"roles":{"2":"authenticated user"}}}
Or, formatted for the sake of legibility:
{
"sessid":"g2ev7til6d750ducrkege0cbj2",
"session_name":"SESS02795057fe9e6b2fc0777bf4057b248f",
"user":{
"uid":"617",
"name":"mohammed.abdelrasoul#gmail.com",
"mail":"mohammed.abdelrasoul#gmail.com",
"mode":"0",
"sort":"0",
"threshold":"0",
"theme":"",
"signature":"",
"signature_format":"0",
"created":"1316602317",
"access":"1352643854",
"login":"1352666338",
"status":"1",
"timezone":"10800",
"language":"ar",
"picture":"",
"init":"mohammed.abdelrasoul#gmail.com",
"data":"a:5:{s:18:\"country_iso_code_2\";s:2:\"SA\";s:13:\"timezone_name\";s:11:\"Asia/Riyadh\";s:5:\"block\";a:1:{s:7:\"webform\";a:1:{s:15:\"client-block-88\";i:1;}}s:13:\"form_build_id\";s:37:\"form-3ae73833f08accc7abe5517347ea87eb\";s:7:\"contact\";i:0;}",
"country_iso_code_2":"SA",
"timezone_name":"Asia/Riyadh",
"block":{
"webform":{
"client-block-88":1
}
},
"form_build_id":"form-3ae73833f08accc7abe5517347ea87eb",
"contact":0,
"roles":{
"2":"authenticated user"
}
}
}
how i can get the objects data or parse the result to get user name
any help or examples will be appreciated
You need to use the NSJSONSerialization class method, JSONObjectWithData:options:error: to create an NSDictionary:
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
if (! error) {
NSLog(#"%#",jsonDict);
}else{
NSLog(#"%#",error.localizedDescription);
}
This will get you to the point where you can look at the dictionary, which will be easier to read. It looks like you need to use objectForKey:#"sessid" to get you to user, then objectForKey#"user", then objectForKey:#"name" to get you to the name.
Check out this framework for parsing json. https://github.com/stig/json-framework/
Also check out this answer iPhone/iOS JSON parsing tutorial. You'll find a link to a tutorial you can do to get acquainted with json parsing in ios.
See this answer and some code :
NSMutableData *data; // Contains data received from the URL connection declares in header
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)dataIn
{
// Do it this way because connection doesn't guarantee all the data is in
POLLog(#" Tide View connection");
[data appendData:dataIn];
}
- (void) connectionDidFinishLoading:(NSURLConnection *) conn
{
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *results = [jsonString JSONValue]; // This is a new category added to the NSString by SBJSON
//100 parameters
for (int n=0;n<=100;n++)
{
// Get all the returned results
params[n] = [[results objectForKey:[NSString stringWithFormat:#"param%d",n]] floatValue];
}
To expand upon rdelmar's answer (which I think you should accept), you can use NSJSONSerialization and then navigate the NSDictionary results to extract the userName:
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData
options:0
error:&error];
if (error == nil) {
NSDictionary *userDictionary = [jsonDict objectForKey:#"user"];
NSString *userName = [userDictionary objectForKey:#"name"];
// do what you need with the userName
} else {
NSLog(#"%#",error.localizedDescription);
}
Or if using the latest version of Xcode, you can replace those objectForKey references with the even more concise Modern Objective-C syntax:
NSDictionary *userDictionary = jsonDict[#"user"];
NSString *userName = userDictionary[#"name"];

Resources