So I need to make an app that can access several APIs that all return the same info about the current time, but they all have different naming conventions. From what I’ve gathered on the internet, the only way to get the info from the JSON strings they return is to make a class with the same names as the fields in that JSON string, which seems extremely inefficient and I think I probably missed the better way to do this. In an ideal scenario I would just go through a list of websites I have saved up, sending requests for each of them if the previous one didn’t work, but as it stands, I have to make a separate class for every one of them. Is there some better way I couldn’t find?
There are methods for incrementally parsing JSON.
In general I highly suggest staying away from Unity’s JSON “tiny lite” package. It’s really not very capable at all and will silently fail on very common data structures, such as Dictionaries and Hashes and ALL properties.
Instead grab Newtonsoft JSON .NET off the asset store for free, or else install it from the Unity Package Manager (Window → Package Manager).
Also, always be sure to leverage sites like:
So you retrieving the current time from multiple websites, can you list a couple? They will each have their own element naming which you will need to account for. One site might be down, but not 3. So code for 3.
http://worldtimeapi.org/api/ip
https://timeapi.io/api/Time/current/ip
These are the two I’m using right now.
That’s exactly why I’m using several of them, I just felt like creating several unique classes just to parse json strings seemed kind of ineficcient. I thought maybe there could be an option of assigning different named fields from different jsons to the same variable, or something like that. Is this just the standard way JSON parsing is done?
Keep in mind that the the time you’ve posted this thread, you would have the 3 classes completed! Also, you don’t need an entire class, just the specific element name, and go directly for that. The first uses “datetime” (or your preference), the second link gives me an error but I suspect you were just using shorthand for IP address in the URL. Can you share your code you are using for parsing the JSON? This example doesn’t use separate classes C# JSON - working with JSON data in C# but instead uses GetProperty for example.
Honestly, the code for parsing it might not be as important as the code I ended up with for using that data. I’m sorry that you’ll have to look at this, but I’m kind of stuck on how I could handle this.
public async void VerifyCurrentInfo()
{
var httpClient = new WebClient(new JsonSerializationOption());
var resultTimeApiByIP = await httpClient.Get<TimeAPI>(_timeApiByIP);
DateTime time = DateTime.Now;
string timezone = TimeZoneInfo.Local.ToString();
if (resultTimeApiByIP != default)
{
time = DateTime.Parse(resultTimeApiByIP.dateTime);
timezone = resultTimeApiByIP.timeZone;
}
else
{
var resultWorldApiByIP = await httpClient.Get<WorldTimeAPI>(_worldApiByIP);
if (resultWorldApiByIP != default)
{
time = DateTime.Parse(resultWorldApiByIP.datetime);
timezone = resultWorldApiByIP.timezone;
}
else
{
var resultTimeApiByCoordinate = await httpClient.Get<TimeAPI>(_timeApiByCoordinate);
if (resultTimeApiByCoordinate != default)
{
time = DateTime.Parse(resultTimeApiByCoordinate.dateTime);
timezone = resultTimeApiByCoordinate.timeZone;
}
}
}
_timeSO.SetValues(time.Hour, time.Minute, time.Second, time.Millisecond, timezone);
I have three types of requests from two sites with different naming conventions. I have to assign an individual class to every url I have. I don’t have any ideas on how I could generalize this process and turn this ugly mess into something presentable. Make all of the classes that are used for JSON parcing into interfaces with the same variables that return the values from the fields they have?
No you don’t need separate classes. Look how the example I provided doesn’t use a class to parse the JSON, just a named identifier to the specific JSON element you are looking for. All you need are the three separate JSON element identifiers for each URL. That last code you provided doesn’t parse JSON.
Yeah, the parsing is done in the Get() function. My point in sending this code was that wouldn’t I have to make separate if statements for each url even if I only access those specific fields I need? For example, I make a request for the first site, get an unparsed string with a JSON thing, that stores the time in a field called “datetime”, for example. But if the request returns an error, I have to make the next one to a different site, that stores the time in a field called “DateTime”, or something like that, so I somehow have to account for that and I can’t seem to figure out how to generalize it all.
You only have 3, there is no need generalize it. You’ll never have more than 3 if it’s just part of retry logic. Just associate the tag you mentioned with each URL. Get it working first, perhaps with a switch statement instead of if/else. Then if you find you need many more later, generalize it then.