Question

I'm working on an iOS application using Xamarin.iOS / MonoTouch and I've run across a bit of a dilemma. We're downloading quite a bit of data with our application by querying JSON-files which are then processed into models that are saved into our local sqlite-database. The problem is that the class I've written is made for specific types, and I want to be able to use the same class for fetching all JSON data into local objects.

Here is my code:

using System;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using System.Collections.Generic;

#pragma warning disable 0414 // Supressing Warning CS0414:

namespace CommonLibrary {
    public class JSONHandler {

        // Debug Constants:
        private static String DEBUG_FILE_TAG = "[JSONHandler] ";

        // Define variables:
        private Uri JSONRequestURL;
        private bool RequestTimedOut;
        private bool RequestSuccessful;
        private string ResponseContent;
        private List<Post> JSONObjects;

        // Define objects:
        private HttpWebRequest JSONWebRequest;
        private HttpWebResponse JSONWebResponse;


        // Constructor:
        public JSONHandler(string requestURL){

            // Set request URL:
            this.JSONRequestURL = new Uri(requestURL);

            // Set default statuses:
            this.RequestTimedOut = false;
            this.RequestSuccessful = false;

        }


        // Create web request:
        private void CreateWebRequest(){
            this.JSONWebRequest = (HttpWebRequest) WebRequest.Create (this.JSONRequestURL);
            this.JSONWebRequest.Method = "GET";
            this.JSONWebRequest.Timeout = 5000;
            this.JSONWebRequest.KeepAlive = false;
            this.JSONWebRequest.AllowAutoRedirect = false;
            this.JSONWebRequest.ContentType = "application/json";
        }


        // Get request response:
        private void GetRequestResponse(){
            try {

                // Catch the response:
                this.JSONWebResponse = (HttpWebResponse) this.JSONWebRequest.GetResponse ();

                // Check the status code:
                if (this.JSONWebResponse.StatusCode == HttpStatusCode.OK){

                    // Get content:
                    StreamReader reader = new StreamReader (this.JSONWebResponse.GetResponseStream ());
                    this.ResponseContent = reader.ReadToEnd();

                    // Close response:
                    this.JSONWebResponse.Close();

                    // Check response length:
                    if (!String.IsNullOrWhiteSpace(this.ResponseContent)){
                        this.JSONObjects = JsonConvert.DeserializeObject<List<Post>>(this.ResponseContent);
                        this.RequestSuccessful = true;
                    } else {
                        this.RequestSuccessful = false;
                    }

                } else {
                    this.RequestSuccessful = false;
                }

            } catch (WebException){
                this.RequestTimedOut = true;
                this.RequestSuccessful = false;
            } catch (TimeoutException){
                this.RequestTimedOut = true;
                this.RequestSuccessful = false;
            }
        }


        // Fetch JSON from server:
        public void FetchJSON(){
            this.CreateWebRequest ();
            this.GetRequestResponse ();
        }


        // Return request status:
        public bool RequestWasSuccessful(){
            return RequestSuccessful;
        }


        // Return timeout status:
        public bool RequestDidTimeOut(){
            return RequestTimedOut;
        }


        // Get object count:
        public int GetJSONCount(){
            return this.JSONObjects.Count;
        }


        // Get list of objects:
        public List<Post> GetJSONObjects (){
            return this.JSONObjects;
        }


    }
}

As you can see, I have to change the type that are stored in the lists from Post to any other object and create a new file, for instance, JSONPost, JSONRunner, JSONLayer etc, and I'd like to handle that with just one class, JSONHandler. Hopefully someone here can help me with this matter. I'm going to have the following classes now:

  • Post
  • Layer
  • RelayTeam
  • RelayRunner
  • RelayRunnerResult
  • MarathonRunner
  • MarathonRunnerResult

And as you all can understand it won't be good having a duplicated file just for all of these.

I'm really thankful for any help I can get!

Best regards, Jonathan

Was it helpful?

Solution

Use Generics - if the type of the JSONObjects collection is the only thing that varies, you can do this

public class JSONHandler<T> {
  ...
  private List<T> JSONObjects;

When you create a new JSONHandler instance, you can specify the type

var handler = new JSONHandler<Post>();
var handler = new JSONHandler<Layer>();
var handler = new JSONHandler<RelayTeam>();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top