Parsing JSON response from Web service to NSDictionary in iOS – Objective C

Hi,

This post will show how to parse the JSON response received from a web service into an NSDictionary object. For the purpose of this post, I’ll use a sample web service hosted by jsontest.com that returns the MD5 hash of the entered sample text.

The url of the sample web service is http://md5.jsontest.com/?text=AmoghNatu

The output when a request is made to the above URL is as shown below.

{
   "md5": "1e559716c8590f85d81abf7abff073aa",
   "original": "AmoghNatu"
}

In the sample project, I'll display the MD5 text in an alert box.

For parsing the response JSON, we use the NSJSONSerialization class's JSONObjectWithData method. When a request is posted to the web service, the response is initially stored in an NSData object. This NSData object is passed to JSONObjectWithData method as parameter along with json reading options and an error object, in case there is an error while parsing the JSON.

Let's have a look at the code.

- (NSDictionary *)parseJsonResponse:(NSString *)urlString
{
    NSError *error;
    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"GET"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse: nil error:&error];
    if (!data)
    {
        NSLog(@"Download Error: %@", error.localizedDescription);
        UIAlertView *alert =
        [[UIAlertView alloc]initWithTitle:@"Error"
                                  message:[NSString stringWithFormat:@"Error : %@",error.localizedDescription]
                                 delegate:self
                        cancelButtonTitle:@"Ok"
                        otherButtonTitles:nil];
        [alert show];
        return nil;
    }
    
    // Parsing the JSON data received from web service into an NSDictionary object
    NSDictionary *JSON =
    [NSJSONSerialization JSONObjectWithData: data
                                    options: NSJSONReadingMutableContainers
                                      error: &error];
    return JSON;
}

The method parseJsonResponse is a sample method that I have written that makes a request to the web service and gets the response in JSON. This JSON is then parsed into an NSDictionary object.

I have uploaded a sample application. The same can be downloaded here. Check that if required.

Hope this helps!

Posted in iOS, Objective-C | Tagged , , , , , , , , , , , , , , , , , | Leave a comment

Enable scrolling to View to allow multiple elements #iOS

Hi,

In this post, I’ll show how to enable scrolling in a particular view in iOS. That is, say if you have many elements to be added in a view and that won’t fit in one screen of the phone. In that case there will be a need for adding scrolling to the view.

By default, a view will have a fixed height (the height of the screen). But most of the times, there are way too many UI elements like textboxes, labels, etc. that need to be added to the view.

So in order to do that, we need to follow the below 5 steps :

  1. Remove Auto-layout for the view controller of the view that needs to have scrolling
  2. Set the “Size” attribute of the View to “Freeform
  3. Increase the height of the view to required dimensions
  4. Add a scroll view to the view
  5. !important Enable scrolling to scrollview and set the dimensions of it

The above steps are shown below through screen shots:

  1. Remove Auto-layout for the view controller of the view that needs to have scrollingFirst select the View controller by clicking on it in the storyboard, then uncheck the check box on the right.

    Un-Check auto layout

  2. Set the “Size” attribute of the View to “Freeform”In the Attributes inspector, under the Simulated Metrics section, change the value of Size attribute to Freeform

    change size

  3. Increase the height of the view to required dimensionsIt is important to note that BEFORE the size is chanegd to Freeform, the dimensions of the view will be disabled as shown below

    Disabled dimensions

    After the size is changed to “Freeform”, we can see that the dimensions are enabled to change as shown below.

    Enabled Dimensions

    Increase the value of the Height element as required and hit enter. This will make the view to the changed size. A sample is shown below.

    Increased Height

  4. Add a scroll view to the viewFrom the objecct library, drag and drop a scroll view on to the view. By default, it will occupy the entire space of the view. Re size it as required.

    Added ScrollView

  5. Enable scrolling to scrollview and set the dimensions of itThis step is very important and needs to be done in order to enable scrolling for the view. We have to add an outlet for the scroll view and synthesize the same in the implementation. This is to give ourselves a reference to the scrollview for programatically enabling scrolling and setting it’s dimensions. The steps are shown below.

    Add outlet

    Synthesize Property

    Now, enable the scrolling and set the dimensions. Sample code shown below:

    enable scrolling

Now, all the required steps are done. Only thing that needs to be done is add the elements to the screen and run it. For the purpose of this post, I’m randomly dragging some elements on to the view and running the app.

Now, run the app and verify that scrolling has been enabled.

Running app with scrolling
Scrolling working!

I have put the above sample project for download here. You can download the zip file by clicking on File–>Download. Please let me know if there are any changes or improvements that can be done here.

Hope this helps!

Posted in General, iOS, Mobile Application Development | Tagged , , , , , , , , , , | 4 Comments

Consuming SOAP web services from iOS (Objective-C)

Hi,

In this post, I’ll show you how to consume a SOAP web service (asmx web service) from iOS. It’s pretty easy to start off with.

There are many links that talk about the use of many frameworks like ASIHttp framework, JSON Framework, wsdl2objc tool, etc. But for the purpose of this post, I would like to keep it simple (KISS! ;-)) Those frameworks are basically used for consuming web service methods that are more complex and those that return JSON response or things like that.

More on those later. For now, let’s concentrate on consuming a very basic ASMX web service hosted by w3schools.org, Temperature conversion web service.

As you can see, this web service exposes two methods: Convert a given temperature from Celsius to Fahrenheit and vice versa. In this post, let’s consume the first one (Celsius to Fahrenheit method).

The steps to follow for consuming the service from XCODE are given below:

  1. Create the request SOAP Envelope message as string
  2. Create a request to the URL
  3. Add required request header elements
  4. Initiate the request
  5. Implement connection delegate methods
  6. Parse the response.

For creating the soap request envelope message, open the method definition in the browser and copy-paste the request string as shown in the page. A sample is shown below:

soap Message

Note the format specifier in the middle of the soap message. That is to take the value entered by the user from the text field.

Celsius

Next step is to create a request to the URL of the web service. Sample code is shown below:

Request

Next, add the required header elements to the request object. You can find out what header elements are required in the message by looking at the sample request objects shown in the webpage of the service’s method. Sample code shown below:

Headers

Finally, set the body of the request by converting the soapMessage to bytes (shown in the last step above).

Next step is to implement the NSURLConnection delegate methods in the application. These methods are used to implement functionality at different stages of the request. A sample of the methods is shown below:

Connection Methods

The code of the connection methods is given below:

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [self.webResponseData  setLength:0];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.webResponseData  appendData:data];
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"Some error in your Connection. Please try again.");
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"Received %d Bytes", [webResponseData length]);
    NSString *theXML = [[NSString alloc] initWithBytes:
                        [webResponseData mutableBytes] length:[webResponseData length] encoding:NSUTF8StringEncoding];
    
    NSLog(@"%@",theXML);
    
    //now parsing the xml
    
    NSData *myData = [theXML dataUsingEncoding:NSUTF8StringEncoding];
    
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:myData];
    
    //setting delegate of XML parser to self
    xmlParser.delegate = self;
    
    // Run the parser
    @try{
        BOOL parsingResult = [xmlParser parse];
        NSLog(@"parsing result = %hhd",parsingResult);
    }
    @catch (NSException* exception)
    {
        UIAlertView* alert = [[UIAlertView alloc]initWithTitle:@"Server Error" message:[exception reason] delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert show];
        return;
    }
}

In the last method, you can see that we have written some code to parse the response received from the web service.
Now, to enable our application to parse the response XML, we need to indicate that our app implements the NSXmlParserDelegate interface.

For this purpose, specify the same in the interface file as shown below:

interface

Now, the next step is to implement the NSXmlParserDelegate methods. It has 3 methods:

  1. didStartElement
  2. foundCharacters
  3. didEndElement

The code of the above methods is given below:


//Implement the NSXmlParserDelegate methods
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:
(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    currentElement = elementName;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if ([currentElement isEqualToString:@"CelsiusToFahrenheitResult"]) {
        self.resultLabel.text = string;
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    NSLog(@"Parsed Element : %@", currentElement);
}


The foundCharacters method is called when an XML tag is encountered that has some characters between the start and end tag. In our case, the response is wrapped between the CelsiusToFahrenheitResult tag. The characters that are found between the start and end tag are stored in the NSString variable string. Hence the code. The result string found is assigned to the result label on the screen.

When you put all the required pieces of the code together and run the app, you get this result.

result

When the user enters the celsius value in the text box and presses the button, the web service is called and the resultant xml response is parsed and the resulting value is displayed on to the screen.

I have attached the complete sample application source code here. Do have a look. And please do let me know if you have any questions or any problems downloading the source code.

Hope this helps!

Posted in .NET, iOS | Tagged , , , , , , , , , , , | Leave a comment

Invoke a POST method with XML Request message in C#

Hi,

To invoke a POST method located at a particular URL with an XML request message, we need to follow the below steps:

  1. Create a request to the url
  2. Put required request headers
  3. Convert the request XML message to a stream (or bytes)
  4. Write the stream of bytes (our request xml) to the request stream
  5. Get the response and read the response as a string

This looks much easier when seen in code. :-) Keep reading…..

So, the code for the above steps looks something like this:

namespace HttpPostRequestDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string xmlMessage = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" +
            "construct your xml request message as required by that method along with parameters";
            string url = "http://XXXX.YYYY/ZZZZ/ABCD.aspx";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);


            byte[] requestInFormOfBytes = System.Text.Encoding.ASCII.GetBytes(xmlMessage);
            request.Method = "POST";
            request.ContentType = "text/xml;charset=utf-8";
            request.ContentLength = requestInFormOfBytes.Length;
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(requestBytes, 0, requestInFormOfBytes.Length);
            requestStream.Close();


            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader respStream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);
            string receivedResponse = respStream.ReadToEnd();

            Console.WriteLine(receivedResponse);
            respStream.Close();
            response.Close();
        }
    }
}

If the xmlMessage is formed correctly, then you should be getting the expected response from the web method located at the URL.

Hope this helps!

Posted in .NET, ASP.NET, C# | Tagged , , , , , , , | Leave a comment

QR code for my blog

Hi there!

Check out the new QR code for my blog!

qr code
Posted in General | Leave a comment

Selecting all unique rows from duplicate rows in table in SQL Server

Hi,

This post will show how you can write a select query to select only unique rows from a table that has many duplicate rows. In other words, this post will show the query to select distinct rows from a table that has duplicate rows.

Let’s say we have a table duplicated_table that has the following rows.

Initial Table
ID Name Email Age
1 Amogh amogh@example.com 24
1 Amogh amogh@example.com 24
2 Uday uday@example.com 23
2 Uday uday@example.com 23
3 Pati pati@example.com 24
3 Pati pati@example.com 24
3 Pati pati@example.com 24
and so on

Now, we can see that all the rows are repeated at least once and we need the output as shown below:

Expected Output
ID Name Email Age
1 Amogh amogh@example.com 24
2 Uday uday@example.com 23
3 Pati pati@example.com 24
and so on — Only unique rows will appear here — no duplicates

First thing to observe here is that there is no unique column in the table. So we need something to uniquely identify the column in the duplicated table. For this, we can use the ROW_NUMBER() function of SQL server. ROW_NUMBER() returns a unique row number for the current row.

So now, the logic that we can use for our purpose is:

  1. Create a data source that will select all the required data that is grouped together by a column, along with a row number to each row
  2. From this dynamically created data source, select those columns that are required but with a row number of “1″

It is important to understand point number 2 above. The output of point number 1 will be as shown below:

Table with Row Numbers
Row Number ID Name Email Age
1 1 Amogh amogh@example.com 24
2 1 Amogh amogh@example.com 24
1 2 Uday uday@example.com 23
2 2 Uday uday@example.com 23
1 3 Pati pati@example.com 24
2 3 Pati pati@example.com 24
3 3 Pati pati@example.com 24
and so on

The above table will be the output of the first point mentioned above. That is, create a data source that selects all the data along with the row number. Observe the “Row Number” column in the above table. Though the table has duplicate rows, each duplicate row has a unique row number.

Now, the only thing left to do is to select those rows from the above table that have row number = 1. And you will end up with the desired output.

Now let’s see the queries for both the steps.

For step – 1: Create a data source that selects all the data along with row number.

;with dataSrc as 
( 
     select ROW_NUMBER() over(partition by Name order by Name) as RowNum,
     ID, Name, email, age from duplicated_table 
)

For step - 2: Selecting those rows with row number = 1;

select Id, Name, email, age from dataSrc where RowNum = 1;

Final Complete Query :

;with dataSrc as 
( 
    select ROW_NUMBER() over(partition by Name order by Name) as RowNum,
    ID, Name, email, age from duplicated_table 
) 
select Id, Name, email, age from dataSrc where RowNum = 1;

Hope this helps!

Posted in SQL Server | Tagged , , , , , , , , , , , , | Leave a comment

Restricting to only one running instance of an application in C#

Hi,

We all must have observed some time or the other that when you try to open an application that is already running, you get a pop up that says, “Another instance of the same application is already running” or something like that.

This post will show how you can implement that in your windows application using C#.

The main class used here is the Process class that is a part of System.Diagnostics namespace. Process class provides access to some local and also remote processes and can be used to start/stop these processes. Some static methods provided by Process class are GetCurrentProcess() and GetProcessesByName(string process_name).

These methods pretty much do exactly what they are named.

  • GetCurrentProcess() basically gets a Process component and links it to the current running process from which this method was called. That means that if we call this method from our app (which is what we’ll do shortly), the method returns a Process component that is linked to our app’s process.
  • GetProcessesByName(string process_name) returns an array of Process components that are currently running in the local system with the specified process name, process_name. So for example, if you have chrome browser running with multiple tabs open, then you can see in Task Manager that there are as many number of “Chrome.exe” processes running as there are tabs in your browser. Now if you call this method for “Chrome.exe”, you will get an array of Process components each having all the details of one chrome.exe process each.

NOTE : It is very important to note here that these methods simply GET the already existing and running instances of the processes. They DO NOT create new instances of Process class. Note the words “gets/returns” in the above bullet points.

So to implement this functionality, all you need to do is before you create a new instance of your application, get all the running processes and check the names of those processes with the currently running process. If you find such a process, it means that there is an instance already running and you should not create another instance for the same application. If not, just create a new instance for the application.

Check the below code. I have created a Windows Forms application with a very basic form with a label. In the Program.cs file, I have created a static method that performs the above mentioned check and returns either true or false based on whether it finds a process with the same name or not.

[STAThread]
 static void Main()
 {
     if (AnotherInstanceExists())
     {
           MessageBox.Show("You cannot run more than one instance of this application.", "Only one instance allowed to run", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
           
           return;
     }

     Form1 objMyForm = new Form1();
     objMyForm.ShowDialog();
 }
public static bool AnotherInstanceExists()
{
    Process currentRunningProcess = Process.GetCurrentProcess();
    Process[] listOfProcs = Process.GetProcessesByName(currentRunningProcess.ProcessName);
 
    foreach (Process proc in listOfProcs)
    {
       if ((proc.MainModule.FileName == currentRunningProcess.MainModule.FileName) && (proc.Id != currentRunningProcess.Id))
               return true;
    }
    return false;
 }

The method AnotherInstanceExists() initially makes a call to GetCurrentProcess() to get a Process component associated with the currently running process. Then it makes a call to GetProcessesByName() and passes the currently running process's name as parameter. With the array of Process components that are returned from this method, it checks whether the current process ID and process module's filename are the same. Basically it checks whether both these processes are same or not.

If the method returns true, the user is shown an error message that only one instance can be running for this application.

That's all there is to do.

Hope this helps!

Posted in .NET, C#, General | Tagged , , , , , , , , , , , , , , , , , | Leave a comment