From b1f16b108fab0e2f7ab1b893d4c7f8c9d5985f23 Mon Sep 17 00:00:00 2001 From: Gustavo Martin Date: Sat, 12 Jul 2014 12:06:16 +0200 Subject: [PATCH] WeatherInformation: save App status --- .../WeatherInformation/App.xaml.cs | 185 +++++++++++++-------- .../WeatherInformation/MainPage.xaml | 2 +- .../WeatherInformation/MainPage.xaml.cs | 88 +++++++--- .../WeatherInformation/MapPage.xaml.cs | 79 +++++---- .../Model/Services/CustomHTTPClient.cs | 2 +- .../WeatherInformation/Model/WeatherData.cs | 42 +++++ .../WeatherInformation/ViewModels/MainViewModel.cs | 66 +++----- .../WeatherInformation/WeatherInformation.csproj | 1 + 8 files changed, 294 insertions(+), 171 deletions(-) create mode 100644 WindowsPhone/WeatherInformation/WeatherInformation/Model/WeatherData.cs diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs index e6e1356..cfdc6bd 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs @@ -1,6 +1,5 @@ using System; using System.Diagnostics; -using System.Resources; using System.Windows; using System.Windows.Markup; using System.Windows.Navigation; @@ -12,6 +11,11 @@ using WeatherInformation.Resources; using WeatherInformation.ViewModels; using System.IO.IsolatedStorage; using System.IO; +using WeatherInformation.Model; +using WeatherInformation.Model.Services; +using System.Threading.Tasks; +using WeatherInformation.Model.ForecastWeatherParser; +using WeatherInformation.Model.JsonDataParser; namespace WeatherInformation { @@ -25,15 +29,11 @@ namespace WeatherInformation private static MainViewModel viewModel = null; // Declare a private variable to store application state. - private string _applicationDataObject; + private WeatherData _remoteWeatherData; // Declare an event for when the application data changes. public event EventHandler ApplicationDataObjectChanged; - // Declare a public property to store the status of the application data. - // Pages should register this event (if they want to receive - public string ApplicationDataStatus { get; set; } - /// /// MainViewModel estático que usan las vistas con el que se van a enlazar. /// @@ -51,19 +51,25 @@ namespace WeatherInformation } // Declare a public property to access the application data variable. - public string ApplicationDataObject + public WeatherData ApplicationDataObject { - get { return _applicationDataObject; } + get { return _remoteWeatherData; } set { - if (value != _applicationDataObject) + if (value != _remoteWeatherData) { - _applicationDataObject = value; + _remoteWeatherData = value; OnApplicationDataObjectChanged(EventArgs.Empty); } } } + public bool IsNewLocation + { + get; + set; + } + // Create a method to raise the ApplicationDataObjectChanged event. protected void OnApplicationDataObjectChanged(EventArgs e) { @@ -138,67 +144,106 @@ namespace WeatherInformation // 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. - IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication(); - if (isoStore.FileExists("myDataFile.txt") && TimeSinceLastSave.TotalSeconds < 30) + using(IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { - // This method loads the data from isolated storage, if it is available. - StreamReader sr = new StreamReader(isoStore.OpenFile("myDataFile.txt", FileMode.Open)); - string data = sr.ReadToEnd(); - sr.Close(); - - ApplicationDataStatus = "data from isolated storage"; - ApplicationDataObject = data; - } - else - { - // SHOULD I CHECK HERE IF THERE ARE COORDINATES AND IN THAT CASE CALL OPENWEATHERMAP? :/ I THINK SO!!! - // MOVE THE MainViewModel.LoadData METHOD TO THIS PLACE!!!! - - // Otherwise, it gets the data from the web. - //HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("http://windowsteamblog.com/windows_phone/b/windowsphone/rss.aspx")); - //request.BeginGetResponse(HandleWebResponse, request); + if (isoStore.FileExists("JSONDataFile.txt") && TimeSinceLastSave.TotalSeconds < 30) + { + 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) + { + ae.Handle(e => + { + // If the data request fails, alert the user. + ApplicationDataObject = new WeatherData + { + RemoteForecastWeatherData = null, + RemoteCurrentWeatherData = null, + JSONRemoteForecastWeatherData = null, + JSONRemoteCurrentWeatherData = null, + WasThereRemoteError = true + }; + + return true; + }); + } + } } + } - private void HandleWebResponse(IAsyncResult result) + /// + /// Crear y agregar unos pocos objetos ItemViewModel a la colección Items. + /// + async public Task LoadDataAsync() { - // Put this in a try block in case the web request was unsuccessful. - try - { - // Get the request from the IAsyncResult. - // HttpWebRequest request = (HttpWebRequest)(result.AsyncState); + CustomHTTPClient httpClient = new CustomHTTPClient(); + + int resultsNumber = 14; + string formattedForecastURL = String.Format( + CultureInfo.InvariantCulture, AppResources.URIAPIOpenWeatherMapForecast, + AppResources.APIVersionOpenWeatherMap, (double)IsolatedStorageSettings.ApplicationSettings["CurrentLatitude"], + (double)IsolatedStorageSettings.ApplicationSettings["CurrentLongitude"], resultsNumber); + string JSONRemoteForecastWeatherData = await httpClient.GetWeatherDataAsync(formattedForecastURL); + + var weatherData = WeatherParser(JSONRemoteForecastWeatherData, null); + weatherData.WasThereRemoteError = false; + weatherData.JSONRemoteForecastWeatherData = JSONRemoteForecastWeatherData; + weatherData.JSONRemoteCurrentWeatherData = null; + ApplicationDataObject = weatherData; + } - // Read the response stream from the response. - //StreamReader sr = new StreamReader(request.EndGetResponse(result).GetResponseStream()); - //string data = sr.ReadToEnd(); - // Use the Dispatcher to call SetData on the UI thread, passing the retrieved data. - //Dispatcher.BeginInvoke(() => { SetData(data, "web"); }); - ApplicationDataStatus = "data from web."; - //ApplicationDataObject = data; - } - catch + private WeatherData WeatherParser(string remoteForecastWeatherData, string remoteCurrentWeatherData) + { + ForecastWeather weather = new ServiceParser(new JsonParser()).GetForecastWeather(remoteForecastWeatherData); + return new WeatherData { - // If the data request fails, alert the user. - ApplicationDataStatus = "Unable to get data from Web."; - ApplicationDataObject = ""; - } + RemoteForecastWeatherData = weather, + RemoteCurrentWeatherData = null + }; } // TODO: temporary file :/ - private void SaveDataToIsolatedStorage(string isoFileName, string value) + private void SaveDataToIsolatedStorage(string isoFileName, WeatherData value) { + if (string.IsNullOrEmpty(value.JSONRemoteForecastWeatherData)) + { + return; + } + using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) using (IsolatedStorageFileStream fileStream = isoStore.OpenFile(isoFileName, FileMode.OpenOrCreate)) - using (StreamWriter sw = new StreamWriter(isoStore.OpenFile(isoFileName, FileMode.OpenOrCreate))) + using (StreamWriter sw = new StreamWriter(fileStream)) { + sw.Write(value.JSONRemoteForecastWeatherData); fileStream.Flush(true); - sw.Write(value); } IsolatedStorageSettings.ApplicationSettings["DataLastSaveTime"] = DateTime.Now; } + + // Código para ejecutar cuando la aplicación se inicia (p.ej. a partir de Inicio) // Este código no se ejecutará cuando la aplicación se reactive private void Application_Launching(object sender, LaunchingEventArgs e) @@ -210,26 +255,24 @@ namespace WeatherInformation // Coming from TOMBSTONED or DORMANT private void Application_Activated(object sender, ActivatedEventArgs e) { - // Asegurarse de que el estado de la aplicación se restaura adecuadamente - // It seems as if here I should store global data to the whole application because this event - // is just called here (never from classes implementing PhoneApplicationPage) - //if (!App.MainViewModel.IsDataLoaded) - //{ - // App.MainViewModel.LoadData(); - //} - if (e.IsApplicationInstancePreserved) { - ApplicationDataStatus = "application instance preserved."; + // Coming from DORMANT return; } + // Coming from TOMBSTONED // Check to see if the key for the application state data is in the State dictionary. - if (PhoneApplicationService.Current.State.ContainsKey("ApplicationDataObject")) + if (PhoneApplicationService.Current.State.ContainsKey("JSONRemoteForecastWeatherData")) { // If it exists, assign the data to the application member variable. - ApplicationDataStatus = "data from preserved state."; - ApplicationDataObject = PhoneApplicationService.Current.State["ApplicationDataObject"] as string; + string JSONRemoteForecastWeatherData = PhoneApplicationService.Current.State["JSONRemoteForecastWeatherData"] as string; + // string remoteCurrentWeatherData = sr.ReadLine(); + var weatherData = WeatherParser(JSONRemoteForecastWeatherData, null); + weatherData.JSONRemoteForecastWeatherData = JSONRemoteForecastWeatherData; + weatherData.JSONRemoteCurrentWeatherData = null; + weatherData.WasThereRemoteError = false; + ApplicationDataObject = weatherData; } } @@ -238,13 +281,17 @@ namespace WeatherInformation private void Application_Deactivated(object sender, DeactivatedEventArgs e) { // If there is data in the application member variable... - if (!string.IsNullOrEmpty(ApplicationDataObject)) + if (ApplicationDataObject != null) { - // Store it in the State dictionary. - PhoneApplicationService.Current.State["ApplicationDataObject"] = ApplicationDataObject; + var weatherData = ApplicationDataObject; + if (!string.IsNullOrEmpty(weatherData.JSONRemoteForecastWeatherData)) + { + // Store it in the State dictionary. + PhoneApplicationService.Current.State["JSONRemoteForecastWeatherData"] = weatherData.JSONRemoteForecastWeatherData; + } // Also store it in isolated storage, in case the application is never reactivated. - SaveDataToIsolatedStorage("myDataFile.txt", ApplicationDataObject); + SaveDataToIsolatedStorage("JSONDataFile.txt", weatherData); } } @@ -254,11 +301,11 @@ 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 (!string.IsNullOrEmpty(ApplicationDataObject)) + if (ApplicationDataObject != null) { - SaveDataToIsolatedStorage("myDataFile.txt", ApplicationDataObject); + SaveDataToIsolatedStorage("JSONDataFile.txt", ApplicationDataObject); } - } + } // Código para ejecutar si hay un error de navegación private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml index 69742f9..102ccec 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml +++ b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml @@ -50,7 +50,7 @@ - + diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs index 4f9bcf2..3de7447 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs @@ -1,23 +1,15 @@ using Microsoft.Phone.Controls; using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.IO.IsolatedStorage; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Navigation; +using WeatherInformation.Model; using WeatherInformation.Resources; -using WeatherInformation.ViewModels; namespace WeatherInformation { public partial class MainPage : PhoneApplicationPage { - private MainViewModel _mainViewModel; private bool _isNewPageInstance = false; // Constructor @@ -33,6 +25,10 @@ namespace WeatherInformation _isNewPageInstance = true; // Set the event handler for when the application data object changes. + // TODO: doing this, when is the GC going to release this object? I do not think it is going to be able... This is weird... + // Shouldn't I release this even handler when the MainPage is not used anymore. In my case is not a big problem because + // the MainPage should be always active (it is the "mainpage") but if this was not the mainpage... Would the GC be able + // to release this object when the page is not active... I DO NOT THINK SO... (Application.Current as WeatherInformation.App).ApplicationDataObjectChanged += new EventHandler(MainPage_ApplicationDataObjectChanged); @@ -45,27 +41,58 @@ namespace WeatherInformation // Cargar datos para los elementos MainViewModel protected override void OnNavigatedTo(NavigationEventArgs e) { - if (!App.MainViewModel.IsDataLoaded) - { - App.MainViewModel.LoadData(); - } - - // If _isNewPageInstance is true, the page constructor has been called, so // state may need to be restored. if (_isNewPageInstance) { - // If the application member variable is not empty, - // set the page's data object from the application member variable. - if ((Application.Current as WeatherInformation.App).ApplicationDataObject != null) + if (!App.MainViewModel.IsThereCurrentLocation()) + { + MessageBox.Show( + AppResources.NoticeThereIsNotCurrentLocation, + AppResources.AskForLocationConsentMessageBoxCaption, + MessageBoxButton.OK); + } + else + { + // If the application member variable is not empty, + // set the page's data object from the application member variable. + // TODO: I am setting and getting ApplicationDataObject from different threads!!!! What if I do not see its last value? Do I need synchronization? :/ + WeatherData weatherData = (Application.Current as WeatherInformation.App).ApplicationDataObject; + if (weatherData != null && !(Application.Current as WeatherInformation.App).IsNewLocation) + { + UpdateApplicationDataUI(); + } + else + { + // Otherwise, call the method that loads data. + (Application.Current as WeatherInformation.App).GetDataAsync(); + } + } + } + else + { + if (!App.MainViewModel.IsThereCurrentLocation()) { - UpdateApplicationDataUI(); + MessageBox.Show( + AppResources.NoticeThereIsNotCurrentLocation, + AppResources.AskForLocationConsentMessageBoxCaption, + MessageBoxButton.OK); } else { - // Otherwise, call the method that loads data. - //statusTextBlock.Text = "getting data..."; - (Application.Current as WeatherInformation.App).GetDataAsync(); + // If the application member variable is not empty, + // set the page's data object from the application member variable. + // TODO: I am setting and getting ApplicationDataObject from different threads!!!! What if I do not see the its last state? Do I need synchronization? :/ + WeatherData weatherData = (Application.Current as WeatherInformation.App).ApplicationDataObject; + if (weatherData != null && !(Application.Current as WeatherInformation.App).IsNewLocation) + { + UpdateApplicationDataUI(); + } + else + { + // Otherwise, call the method that loads data. + (Application.Current as WeatherInformation.App).GetDataAsync(); + } } } @@ -80,12 +107,23 @@ namespace WeatherInformation // Call UpdateApplicationData on the UI thread. Dispatcher.BeginInvoke(() => UpdateApplicationDataUI()); } + void UpdateApplicationDataUI() { // Set the ApplicationData and ApplicationDataStatus members of the ViewModel - // class to update the UI. - // dataTextBlock.Text = (Application.Current as ExecutionModelApplication.App).ApplicationDataObject; - // statusTextBlock.Text = (Application.Current as ExecutionModelApplication.App).ApplicationDataStatus; + WeatherData weatherData = (Application.Current as WeatherInformation.App).ApplicationDataObject; + + if (weatherData.WasThereRemoteError) + { + MessageBox.Show( + AppResources.NoticeThereIsNotCurrentLocation, + AppResources.AskForLocationConsentMessageBoxCaption, + MessageBoxButton.OK); + return; + } + + (Application.Current as WeatherInformation.App).IsNewLocation = false; + App.MainViewModel.LoadData(weatherData); } private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e) diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs index e6e012e..6e1ae1a 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs @@ -73,38 +73,12 @@ namespace WeatherInformation maximumAge: TimeSpan.FromMinutes(5), timeout: TimeSpan.FromSeconds(10) ); - GeoCoordinate myGeoCoordinate = CoordinateConverter.ConvertGeocoordinate(geoposition.Coordinate); - - ReverseGeocodeQuery myReverseGeocodeQuery = new ReverseGeocodeQuery(); - myReverseGeocodeQuery.GeoCoordinate = myGeoCoordinate; - myReverseGeocodeQuery.QueryCompleted += QueryCompletedCallback; - myReverseGeocodeQuery.QueryAsync(); - - // Create a small circle to mark the current location. - Ellipse myCircle = new Ellipse(); - myCircle.Fill = new SolidColorBrush(Colors.Blue); - myCircle.Height = 20; - myCircle.Width = 20; - myCircle.Opacity = 50; - - // Create a MapOverlay to contain the circle. - MapOverlay myLocationOverlay = new MapOverlay(); - myLocationOverlay.Content = myCircle; - myLocationOverlay.PositionOrigin = new Point(0.5, 0.5); - myLocationOverlay.GeoCoordinate = myGeoCoordinate; - - // Create a MapLayer to contain the MapOverlay. - MapLayer myLocationLayer = new MapLayer(); - myLocationLayer.Add(myLocationOverlay); - - this.mapWeatherInformation.Center = myGeoCoordinate; - this.mapWeatherInformation.ZoomLevel = 13; - - // Add the MapLayer to the Map. - this.mapWeatherInformation.Layers.Add(myLocationLayer); - - _settings["CurrentLatitude"] = myGeoCoordinate.Latitude; - _settings["CurrentLongitude"] = myGeoCoordinate.Longitude; + GeoCoordinate currentGeoCoordinate = CoordinateConverter.ConvertGeocoordinate(geoposition.Coordinate); + + ReverseGeocodeQuery currentReverseGeocodeQuery = new ReverseGeocodeQuery(); + currentReverseGeocodeQuery.GeoCoordinate = currentGeoCoordinate; + currentReverseGeocodeQuery.QueryCompleted += QueryCompletedCallback; + currentReverseGeocodeQuery.QueryAsync(); } catch (Exception ex) { @@ -138,13 +112,52 @@ namespace WeatherInformation } Exception errorException = eventData.Error; - if (errorException == null) + if (errorException != null) + { + // TODO: Show some log. I need to use remote logging :( + return; + } + else { if (eventData.Result.Count > 0) { MapAddress address = eventData.Result[0].Information.Address; + GeoCoordinate currentGeoCoordinate = eventData.Result[0].GeoCoordinate; + string cityCountry = String.Format(CultureInfo.InvariantCulture, "{0}, {1}", address.City, address.Country); this.LocationTextCityCountry.Text = cityCountry; + + // TODO: If I want to store more than one place I should use a database :( + _settings["CurrentLatitude"] = currentGeoCoordinate.Latitude; + _settings["CurrentLongitude"] = currentGeoCoordinate.Longitude; + // TODO: If I want to store more thant one place I should use a database :( + _settings["City"] = address.City; + _settings["Country"] = address.Country; + + (Application.Current as WeatherInformation.App).IsNewLocation = true; + + // Create a small circle to mark the current location. + Ellipse myCircle = new Ellipse(); + myCircle.Fill = new SolidColorBrush(Colors.Blue); + myCircle.Height = 20; + myCircle.Width = 20; + myCircle.Opacity = 50; + + // Create a MapOverlay to contain the circle. + MapOverlay myLocationOverlay = new MapOverlay(); + myLocationOverlay.Content = myCircle; + myLocationOverlay.PositionOrigin = new Point(0.5, 0.5); + myLocationOverlay.GeoCoordinate = currentGeoCoordinate; + + // Create a MapLayer to contain the MapOverlay. + MapLayer myLocationLayer = new MapLayer(); + myLocationLayer.Add(myLocationOverlay); + + this.mapWeatherInformation.Center = currentGeoCoordinate; + this.mapWeatherInformation.ZoomLevel = 13; + + // Add the MapLayer to the Map. + this.mapWeatherInformation.Layers.Add(myLocationLayer); } } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs b/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs index 083959f..47bc97c 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs @@ -9,7 +9,7 @@ namespace WeatherInformation.Model.Services { class CustomHTTPClient { - async public Task getWeatherData(string url) + async public Task GetWeatherDataAsync(string url) { using (HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) }) { diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Model/WeatherData.cs b/WindowsPhone/WeatherInformation/WeatherInformation/Model/WeatherData.cs new file mode 100644 index 0000000..649f212 --- /dev/null +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Model/WeatherData.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WeatherInformation.Model.CurrentWeatherParser; +using WeatherInformation.Model.ForecastWeatherParser; + +namespace WeatherInformation.Model +{ + public class WeatherData + { + public ForecastWeather RemoteForecastWeatherData + { + get; + set; + } + public string JSONRemoteForecastWeatherData + { + get; + set; + } + + + public CurrentWeather RemoteCurrentWeatherData + { + get; + set; + } + public string JSONRemoteCurrentWeatherData + { + get; + set; + } + + public bool WasThereRemoteError + { + get; + set; + } + } +} diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs index da91928..36a804b 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.IO.IsolatedStorage; using System.Threading.Tasks; using System.Windows; +using WeatherInformation.Model; using WeatherInformation.Model.ForecastWeatherParser; using WeatherInformation.Model.JsonDataParser; using WeatherInformation.Model.Services; @@ -41,43 +42,15 @@ namespace WeatherInformation.ViewModels /// /// Colección para objetos ItemViewModel. /// - public ObservableCollection ForecastItems { get; private set; } + public ObservableCollection ForecastItems{ get; private set; } public ObservableCollection CurrentItems { get; private set; } - - - public bool IsDataLoaded - { - get; - private set; - } /// /// Crear y agregar unos pocos objetos ItemViewModel a la colección Items. /// - async public Task LoadData() + public void LoadData(WeatherData weatherData) { - if (!_settings.Contains("CurrentLatitude") || !_settings.Contains("CurrentLongitude")) - { - MessageBox.Show( - AppResources.NoticeThereIsNotCurrentLocation, - AppResources.AskForLocationConsentMessageBoxCaption, - MessageBoxButton.OK); - return; - } - - CustomHTTPClient httpClient = new CustomHTTPClient(); - - int resultsNumber = 14; - string formattedForecastURL = String.Format( - CultureInfo.InvariantCulture, AppResources.URIAPIOpenWeatherMapForecast, - AppResources.APIVersionOpenWeatherMap, (double)_settings["CurrentLatitude"], - (double)_settings["CurrentLongitude"], resultsNumber); - string jsonData = await httpClient.getWeatherData(formattedForecastURL); - - ForecastWeather weather = this._serviceParser.GetForecastWeather(jsonData); - - // TODO: there must be a better way than using the index value :( int forecastDayNumbers = GetValueOrDefault(_forecastDayNumbersSelectionSelectionSettingKeyName, _forecastDayNumbersSelectionSettingDefault); @@ -98,19 +71,20 @@ namespace WeatherInformation.ViewModels break; } - foreach (WeatherInformation.Model.ForecastWeatherParser.List item in weather.list) + // TODO: there must be a better way than using the index value :( + bool isFahrenheit = true; + int temperatureUnitsSelection = + GetValueOrDefault(_temperatureUnitsSelectionSettingKeyName, _temperatureUnitsSelectionSettingDefault); + if (temperatureUnitsSelection != 0) { - // TODO: there must be a better way than using the index value :( - bool isFahrenheit = true; - int temperatureUnitsSelection = - GetValueOrDefault(_temperatureUnitsSelectionSettingKeyName, _temperatureUnitsSelectionSettingDefault); - if (temperatureUnitsSelection != 0) - { - isFahrenheit = false; - } - double tempUnits = isFahrenheit ? 0 : 273.15; - string symbol = isFahrenheit ? AppResources.TemperatureUnitsFahrenheitSymbol : AppResources.TemperatureUnitsCentigradeSymbol; + isFahrenheit = false; + } + double tempUnits = isFahrenheit ? 0 : 273.15; + string symbol = isFahrenheit ? AppResources.TemperatureUnitsFahrenheitSymbol : AppResources.TemperatureUnitsCentigradeSymbol; + var remoteForecastWeatherData = weatherData.RemoteForecastWeatherData; + foreach (WeatherInformation.Model.ForecastWeatherParser.List item in remoteForecastWeatherData.list) + { DateTime unixTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime date = unixTime.AddSeconds(item.dt).ToLocalTime(); @@ -139,8 +113,16 @@ namespace WeatherInformation.ViewModels break; } } + } + + public bool IsThereCurrentLocation() + { + if (_settings.Contains("CurrentLatitude") && _settings.Contains("CurrentLongitude")) + { + return true; + } - this.IsDataLoaded = true; + return false; } /// diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj b/WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj index a4bbe40..e0795ba 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj +++ b/WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj @@ -118,6 +118,7 @@ + -- 2.1.4