From e53642ab2505d8e980af0d8bb49ccfd165f8a95d Mon Sep 17 00:00:00 2001 From: Gustavo Martin Date: Sun, 13 Jul 2014 09:02:18 +0200 Subject: [PATCH] WindowsPhone WeatherInformation --- .../WeatherInformation/App.xaml.cs | 100 +++++++++++---------- .../WeatherInformation/MainPage.xaml | 10 +-- .../WeatherInformation/MainPage.xaml.cs | 11 ++- .../Model/Services/CustomHTTPClient.cs | 13 ++- .../Resources/AppResources.Designer.cs | 9 ++ .../Resources/AppResources.es.resx | 2 +- .../Resources/AppResources.es.xlf | 23 +++-- .../Resources/AppResources.qps-ploc.xlf | 5 ++ .../WeatherInformation/Resources/AppResources.resx | 4 + .../WeatherInformation/ViewModels/MainViewModel.cs | 13 +-- 10 files changed, 113 insertions(+), 77 deletions(-) diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs index cfdc6bd..9301865 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs @@ -141,58 +141,58 @@ namespace WeatherInformation TimeSinceLastSave = DateTime.Now - dataLastSaveTime; } - // Check to see if data exists in isolated storage and see if the data is fresh. - // This example uses 30 seconds as the valid time window to make it easy to test. - // Real apps will use a larger window. - using(IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) + if (!IsNewLocation) { - if (isoStore.FileExists("JSONDataFile.txt") && TimeSinceLastSave.TotalSeconds < 30) + // Check to see if data exists in isolated storage and see if the data is fresh. + // This example uses 30 seconds as the valid time window to make it easy to test. + // Real apps will use a larger window. + using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { - using (StreamReader sr = new StreamReader(isoStore.OpenFile("JSONDataFile.txt", FileMode.Open))) - { - // This method loads the data from isolated storage, if it is available. - string JSONRemoteForecastWeatherData = sr.ReadLine(); - // string remoteCurrentWeatherData = sr.ReadLine(); - var weatherData = WeatherParser(JSONRemoteForecastWeatherData, null); - weatherData.JSONRemoteForecastWeatherData = JSONRemoteForecastWeatherData; - weatherData.JSONRemoteCurrentWeatherData = null; - weatherData.WasThereRemoteError = false; - ApplicationDataObject = weatherData; - } - } - else - { - // Otherwise, it gets the data from the web. - var task = LoadDataAsync(); - try - { - // TODO: I guess, I may do this because this code is running in a new thread :/ Better alternative just using async? WIP :( - task.Wait(); - } - catch (AggregateException ae) + if (isoStore.FileExists("JSONDataFile.txt") && TimeSinceLastSave.TotalSeconds < 30) { - ae.Handle(e => + using (StreamReader sr = new StreamReader(isoStore.OpenFile("JSONDataFile.txt", FileMode.Open))) { - // If the data request fails, alert the user. - ApplicationDataObject = new WeatherData - { - RemoteForecastWeatherData = null, - RemoteCurrentWeatherData = null, - JSONRemoteForecastWeatherData = null, - JSONRemoteCurrentWeatherData = null, - WasThereRemoteError = true - }; - - return true; - }); + // This method loads the data from isolated storage, if it is available. + string JSONRemoteForecastWeatherData = sr.ReadLine(); + // string remoteCurrentWeatherData = sr.ReadLine(); + var weatherData = WeatherParser(JSONRemoteForecastWeatherData, null); + weatherData.JSONRemoteForecastWeatherData = JSONRemoteForecastWeatherData; + weatherData.JSONRemoteCurrentWeatherData = null; + weatherData.WasThereRemoteError = false; + ApplicationDataObject = weatherData; + } + + // TODO: write more methods or something else to avoid nested returns like this... no time right now... :( + return; } } } + + // Otherwise, it gets the data from the web. + var task = LoadDataAsync(); + try + { + // TODO: I guess, I may do this because this code is running in a new thread :/ Better alternative just using async? WIP :( + // Using Task.WhenAll to avoid deadlock :) + Task.WhenAll(task); + } + catch (Exception ex) + { + // If the data request fails, alert the user. + ApplicationDataObject = new WeatherData + { + RemoteForecastWeatherData = null, + RemoteCurrentWeatherData = null, + JSONRemoteForecastWeatherData = null, + JSONRemoteCurrentWeatherData = null, + WasThereRemoteError = true + }; + } } /// - /// Crear y agregar unos pocos objetos ItemViewModel a la colección Items. + /// Retrieve remote weather data. /// async public Task LoadDataAsync() { @@ -238,8 +238,8 @@ namespace WeatherInformation sw.Write(value.JSONRemoteForecastWeatherData); fileStream.Flush(true); } - - IsolatedStorageSettings.ApplicationSettings["DataLastSaveTime"] = DateTime.Now; + + IsolatedStorageSettings.ApplicationSettings["DataLastSavedTime"] = DateTime.Now; } @@ -274,6 +274,10 @@ namespace WeatherInformation weatherData.WasThereRemoteError = false; ApplicationDataObject = weatherData; } + if (PhoneApplicationService.Current.State.ContainsKey("IsNewLocation")) + { + IsNewLocation = (bool)IsolatedStorageSettings.ApplicationSettings["IsNewLocation"]; + } } // Código para ejecutar cuando la aplicación se desactiva (se envía a segundo plano) @@ -281,14 +285,15 @@ namespace WeatherInformation private void Application_Deactivated(object sender, DeactivatedEventArgs e) { // If there is data in the application member variable... - if (ApplicationDataObject != null) + var weatherData = ApplicationDataObject; + if (weatherData != null) { - var weatherData = ApplicationDataObject; if (!string.IsNullOrEmpty(weatherData.JSONRemoteForecastWeatherData)) { // Store it in the State dictionary. PhoneApplicationService.Current.State["JSONRemoteForecastWeatherData"] = weatherData.JSONRemoteForecastWeatherData; } + PhoneApplicationService.Current.State["IsNewLocation"] = IsNewLocation; // Also store it in isolated storage, in case the application is never reactivated. SaveDataToIsolatedStorage("JSONDataFile.txt", weatherData); @@ -301,9 +306,10 @@ namespace WeatherInformation { // Asegurarse de que el estado de la aplicación requerida persiste aquí. // The application will not be tombstoned, so save only to isolated storage. - if (ApplicationDataObject != null) + var weatherData = ApplicationDataObject; + if (weatherData != null) { - SaveDataToIsolatedStorage("JSONDataFile.txt", ApplicationDataObject); + SaveDataToIsolatedStorage("JSONDataFile.txt", weatherData); } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml index 102ccec..1d66b22 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml +++ b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml @@ -47,7 +47,7 @@ --> - + @@ -81,12 +81,8 @@ - - - - - - + + diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs index 3de7447..2cb803b 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs @@ -1,5 +1,7 @@ using Microsoft.Phone.Controls; using System; +using System.Globalization; +using System.IO.IsolatedStorage; using System.Windows; using System.Windows.Controls; using System.Windows.Navigation; @@ -121,9 +123,16 @@ namespace WeatherInformation MessageBoxButton.OK); return; } + + App.MainViewModel.LoadData(weatherData); (Application.Current as WeatherInformation.App).IsNewLocation = false; - App.MainViewModel.LoadData(weatherData); + + // TODO: Should I try to move this code to MainViewModel. It seems so but how? + 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; } private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e) diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs b/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs index 47bc97c..42ba9a3 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; +using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; @@ -11,9 +12,19 @@ namespace WeatherInformation.Model.Services { async public Task GetWeatherDataAsync(string url) { + using (HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) }) { - return await client.GetStringAsync(url); + // 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? + + // Disable WindowsPhone cache + HttpRequestHeaders headers = client.DefaultRequestHeaders; + headers.IfModifiedSince = DateTime.UtcNow; + + string jsonData = await client.GetStringAsync(url); + + return jsonData; } } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.Designer.cs b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.Designer.cs index 3ba14ae..40ca9f1 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.Designer.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.Designer.cs @@ -151,6 +151,15 @@ namespace WeatherInformation.Resources { } /// + /// Busca una cadena traducida similar a City, country. + /// + public static string MainPageTitle { + get { + return ResourceManager.GetString("MainPageTitle", resourceCulture); + } + } + + /// /// Busca una cadena traducida similar a Location autodetection seems to be disabled in your phone. /// public static string NoticeErrorLocationAutodetection { diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.resx b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.resx index 166965d..761e583 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.resx +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.resx @@ -134,4 +134,4 @@ -MI APLICACIÓNagregarElemento de menúIdiomaText in settings page as headerUnidades de temperaturaText in settings pageinglésSettings page, select English languageespañolSettings page, select Spanish languagecelsiusSettings page, select tempereature units centigradefahrenheitSettings page, select temperature units fahrenheitLocalizaciónAsk for location consent in map windowNo hay localizaciones almacenadas.Main window, notice message, no available locationsDetección automática de la ubicación parece ser desactivado en el teléfonoMap window, notice message, error while location autodetectionPrevision, numero díasText in settings page as headerPrevisión 10 díasSettings page, select forecast day numbersPrevisión 14 díasSettings page, select forecast day numbersPrevisión 5 díasSettings page, select forecast day numbersº FCiudad, paísSubtitle in location pageSelecciona tu localizaciónTitle in location pageprevisiónForecast header in main pageconfiguración deHeader settings in settings pageactualCurrent header in main pageº CEsta aplicación accede a los datos de tu localización. ¿Estás de acuerdo?Ask for location consent in map window \ No newline at end of file +MI APLICACIÓNagregarElemento de menúIdiomaText in settings page as headerUnidades de temperaturaText in settings pageinglésSettings page, select English languageespañolSettings page, select Spanish languagecelsiusSettings page, select tempereature units centigradefahrenheitSettings page, select temperature units fahrenheitLocalizaciónAsk for location consent in map windowNo hay localizaciones almacenadas.Main window, notice message, no available locationsDetección automática de la ubicación parece ser desactivado en el teléfonoMap window, notice message, error while location autodetectionPrevision, numero díasText in settings page as headerPrevisión 10 díasSettings page, select forecast day numbersPrevisión 14 díasSettings page, select forecast day numbersPrevisión 5 díasSettings page, select forecast day numbersº FCiudad, paísSubtitle in location pageSelecciona tu localizaciónTitle in location pageprevisiónForecast header in main pageconfiguración deHeader settings in settings pageactualCurrent header in main pageº CEsta aplicación accede a los datos de tu localización. ¿Estás de acuerdo?Ask for location consent in map windowCiudad, paísTitle in main page \ No newline at end of file diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.xlf b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.xlf index 4d54dee..f9e7910 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.xlf +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.xlf @@ -18,7 +18,7 @@ MY APPLICATION - MI APLICACIÓN + MI APLICACIÓN add @@ -26,21 +26,21 @@ Menu item - Elemento de menú + Elemento de menú Language - Idioma + Idioma Text in settings page as header Temperature units - Unidades de temperatura + Unidades de temperatura Text in settings page english - inglés + inglés Settings page, select English language @@ -95,11 +95,11 @@ ºF - º F + º F City, country - Ciudad, país + Ciudad, país Subtitle in location page @@ -109,7 +109,7 @@ forecast - previsión + previsión Forecast header in main page @@ -117,9 +117,14 @@ configuración de Header settings in settings page + + City, country + Ciudad, país + Title in main page + current - actual + actual Current header in main page diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.xlf b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.xlf index 5b5e6b7..d3e7ea3 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.xlf +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.xlf @@ -102,6 +102,11 @@ settings Header settings in settings page + + City, country + City, country + Title in main page + current current diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.resx b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.resx index 9cd670a..0ab3453 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.resx +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.resx @@ -224,4 +224,8 @@ settings Header settings in settings page + + City, country + Title in main page + \ No newline at end of file diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs index 36a804b..265e2e4 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs @@ -13,7 +13,7 @@ using WeatherInformation.Resources; namespace WeatherInformation.ViewModels { - public class MainViewModel : INotifyPropertyChanged + public class MainViewModel { // The key names of _settings // TODO: reuse settings object instead of using the same code here again... @@ -83,6 +83,7 @@ namespace WeatherInformation.ViewModels string symbol = isFahrenheit ? AppResources.TemperatureUnitsFahrenheitSymbol : AppResources.TemperatureUnitsCentigradeSymbol; var remoteForecastWeatherData = weatherData.RemoteForecastWeatherData; + this.ForecastItems.Clear(); foreach (WeatherInformation.Model.ForecastWeatherParser.List item in remoteForecastWeatherData.list) { DateTime unixTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); @@ -157,15 +158,5 @@ namespace WeatherInformation.ViewModels } return value; } - - public event PropertyChangedEventHandler PropertyChanged; - private void NotifyPropertyChanged(String propertyName) - { - PropertyChangedEventHandler handler = PropertyChanged; - if (null != handler) - { - handler(this, new PropertyChangedEventArgs(propertyName)); - } - } } } \ No newline at end of file -- 2.1.4