From: gu.martinm@gmail.com Date: Sun, 3 Aug 2014 22:25:09 +0000 (+0200) Subject: WeatherInformation: WP8 X-Git-Url: https://git.gumartinm.name/?a=commitdiff_plain;h=15745c0374bcc7e97d1f0c6852bc8f5f3b2dee51;p=CSharpForFun%2F.git WeatherInformation: WP8 HTTP client improvements Many others (no time...) --- diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs index 31d00b4..338023f 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs @@ -298,6 +298,9 @@ namespace WeatherInformation // Código para ejecutar cuando la aplicación se desactiva (se envía a segundo plano) // Este código no se ejecutará cuando la aplicación se cierre + // TODO: no siempre pasa por aqui cuando se lanza una nueva ventana de la misma aplicación. + // Y POR ESO HAY PROBLEMAS CON GetDataAsync PORQUE ESTO NO TIENE NADA DE NADA Y DEVUELVE NULL + // Y SIEMPRE HACE UNA PETICIÓN AL SERVIDOR :( private void Application_Deactivated(object sender, DeactivatedEventArgs e) { // If there is data in the application member variable... diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml index 084a4fd..f15066d 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml +++ b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml @@ -105,10 +105,10 @@ - + - + @@ -149,7 +149,7 @@ - + diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs b/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs index c9c2bef..aa98917 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs @@ -1,6 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; +using System.IO; +using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; @@ -10,23 +10,73 @@ namespace WeatherInformation.Model.Services { class CustomHTTPClient { - async public Task GetWeatherDataAsync(string url) + async public Task GetWeatherDataAsync(string uri) { - - using (HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) }) + if (string.IsNullOrEmpty(uri)) { - // TODO: I wish my string to be converted to UTF-8. WTH is doing HttpClient? Dunno :( - // How do I control the encoding used by HttpClient? + throw new ArgumentException("Missing argument", "uri"); + } - // Disable WindowsPhone cache + // TODO: it would be nice to use the same HttpClient for the the 2 requests instead of creating + // a new one for each connection. :( Not easy with using statement and async :( + using(HttpClientHandler handler = new HttpClientHandler + { + // TODO: check if this really works when receiving compressed data. + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate + }) + using (HttpClient client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) }) + { HttpRequestHeaders headers = client.DefaultRequestHeaders; - headers.IfModifiedSince = DateTime.UtcNow; - // TODO: THIS IS FUCKED UP. IT IS WORKING RANDOMLY... THE MOST OF THE TIMES IT STOPS HERE FOREVER... - string jsonData = await client.GetStringAsync(url); + headers.UserAgent.Clear(); + headers.UserAgent.Add(new ProductInfoHeaderValue(new ProductHeaderValue("WeatherInformation", "WP8"))); + + headers.AcceptCharset.Clear(); + headers.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8")); + + headers.Accept.Clear(); + headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - return jsonData; + headers.AcceptEncoding.Clear(); + headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); + headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); + + // Bypassing Windows cache + DateTime currentDate = DateTime.UtcNow; + string uriWindowsCacheSucks = String.Concat(uri, currentDate); + + // TODO: HttpCompletionOption, without it, by default, I am buffering the received data. + // in this case it is not a problem but when receiving loads of bytes I do not + // think it is a great idea to buffer all of them... :( + using (HttpResponseMessage response = await client.GetAsync(uriWindowsCacheSucks)) + { + response.EnsureSuccessStatusCode(); + + using (HttpContent contentRESULT = response.Content) + { + return await this.ReadResponseAsync(contentRESULT); + } + } + } + } + + async private Task ReadResponseAsync(HttpContent content) + { + Encoding encoding; + if (content.Headers != null && content.Headers.ContentType != null && content.Headers.ContentType.CharSet != null) + { + encoding = Encoding.GetEncoding(content.Headers.ContentType.CharSet); + } + else + { + encoding = Encoding.UTF8; + } + + using (Stream stream = await content.ReadAsStreamAsync()) + using (StreamReader streamReader = new StreamReader(stream, encoding)) + { + return await streamReader.ReadToEndAsync(); } - } + } } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/SampleData/SelectedDateViewModelSampleData.xaml b/WindowsPhone/WeatherInformation/WeatherInformation/SampleData/SelectedDateViewModelSampleData.xaml index 30098de..bbc7f3e 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/SampleData/SelectedDateViewModelSampleData.xaml +++ b/WindowsPhone/WeatherInformation/WeatherInformation/SampleData/SelectedDateViewModelSampleData.xaml @@ -1,5 +1,6 @@  - + diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/SelectedDatePage.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/SelectedDatePage.xaml.cs index 8fd70ae..fc2cfca 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/SelectedDatePage.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/SelectedDatePage.xaml.cs @@ -62,13 +62,6 @@ namespace WeatherInformation } _selectedDateViewModel.LoadData(weatherData); - - // TODO: Should I try to move this code to MainViewModel. It seems so but how? - // TODO: What if the address is not available? I should show something like "Address not found" by default... - string country = (string)IsolatedStorageSettings.ApplicationSettings["Country"]; - string city = (string)IsolatedStorageSettings.ApplicationSettings["City"]; - string cityCountry = String.Format(CultureInfo.InvariantCulture, "{0}, {1}", city, country); - this.TitleTextCityCountry.Title = cityCountry; } } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs index 470d397..6393509 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs @@ -111,14 +111,6 @@ namespace WeatherInformation.ViewModels } double tempUnits = isFahrenheit ? 0 : 273.15; string symbol = isFahrenheit ? AppResources.TemperatureUnitsFahrenheitSymbol : AppResources.TemperatureUnitsCentigradeSymbol; - - - // TODO: What if address is not available? I should show something like "Address not found" by default... - string country = (string)IsolatedStorageSettings.ApplicationSettings["Country"]; - string city = (string)IsolatedStorageSettings.ApplicationSettings["City"]; - string cityCountry = String.Format(CultureInfo.InvariantCulture, "{0}, {1}", city, country); - this.TitleTextCityCountry = cityCountry; - DateTime unixTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var remoteForecastWeatherData = weatherData.RemoteForecast; @@ -293,6 +285,13 @@ namespace WeatherInformation.ViewModels this.CurrentSunSet = sunSetTime.ToString("MM/dd/yy H:mm:ss", CultureInfo.InvariantCulture); NotifyPropertyChanged("CurrentSunSet"); NotifyPropertyChanged("CurrentSunSetText"); + + // TODO: What if address is not available? I should show something like "Address not found" by default... + string country = StoredLocation.Country; + string city = StoredLocation.City; + string cityCountry = String.Format(CultureInfo.InvariantCulture, "{0}, {1}", city, country); + this.TitleTextCityCountry = cityCountry; + NotifyPropertyChanged("TitleTextCityCountry"); } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/SelectedDateViewModel.cs b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/SelectedDateViewModel.cs index 1fa3430..93a4bc9 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/SelectedDateViewModel.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/SelectedDateViewModel.cs @@ -7,6 +7,7 @@ using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using WeatherInformation.Model; +using WeatherInformation.Model.Services; using WeatherInformation.Resources; namespace WeatherInformation.ViewModels @@ -17,6 +18,8 @@ namespace WeatherInformation.ViewModels [DataMember] public Int32 SelectedDateIndex { get; set; } + public String TitleTextCityCountry { get; private set; } + public String SelectedDate { get; private set; } public String SelectedDateMaxTemp { get; private set; } public String SelectedDateMaxTempUnits { get; private set; } @@ -202,6 +205,13 @@ namespace WeatherInformation.ViewModels NotifyPropertyChanged("SelectedDateNightTemp"); this.SelectedDateNightTempUnits = selectedDateTempUnits; NotifyPropertyChanged("SelectedDateNightTempUnits"); + + // TODO: What if address is not available? I should show something like "Address not found" by default... + string country = StoredLocation.Country; + string city = StoredLocation.City; + string cityCountry = String.Format(CultureInfo.InvariantCulture, "{0}, {1}", city, country); + this.TitleTextCityCountry = cityCountry; + NotifyPropertyChanged("TitleTextCityCountry"); } public event PropertyChangedEventHandler PropertyChanged;