WeatherInformation: save App status
authorGustavo Martin <gu.martinm@gmail.com>
Sat, 12 Jul 2014 10:06:16 +0000 (12:06 +0200)
committerGustavo Martin <gu.martinm@gmail.com>
Sat, 12 Jul 2014 10:06:16 +0000 (12:06 +0200)
WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs
WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml
WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs
WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs
WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs
WindowsPhone/WeatherInformation/WeatherInformation/Model/WeatherData.cs [new file with mode: 0644]
WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs
WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj

index e6e1356..cfdc6bd 100644 (file)
@@ -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; }
-
         /// <summary>
         /// MainViewModel estático que usan las vistas con el que se van a enlazar.
         /// </summary>
@@ -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)
+        /// <summary>
+        /// Crear y agregar unos pocos objetos ItemViewModel a la colección Items.
+        /// </summary>
+        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)
index 69742f9..102ccec 100644 (file)
@@ -50,7 +50,7 @@
         <phone:Pivot Title="City, country">
             <!--Elemento Pivot uno-->
             <phone:PivotItem Header="{Binding LocalizedResources.MainPageForecastHeader, Mode=OneWay, Source={StaticResource LocalizedStrings}}">
-                <phone:LongListSelector Margin="0,0,-12,0" ItemsSource="{Binding ForecastItems}" SelectionChanged="LongListSelector_SelectionChanged">
+                <phone:LongListSelector x:Name="ForecastItems" Margin="0,0,-12,0" ItemsSource="{Binding ForecastItems}" SelectionChanged="LongListSelector_SelectionChanged">
                     <phone:LongListSelector.ItemTemplate>
                         <DataTemplate>
                             <Grid>
index 4f9bcf2..3de7447 100644 (file)
@@ -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)
index e6e012e..6e1ae1a 100644 (file)
@@ -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);  
                 }
             }
         }
index 083959f..47bc97c 100644 (file)
@@ -9,7 +9,7 @@ namespace WeatherInformation.Model.Services
 {
     class CustomHTTPClient
     {
-        async public Task<string> getWeatherData(string url)
+        async public Task<string> 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 (file)
index 0000000..649f212
--- /dev/null
@@ -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;
+        }
+    }
+}
index da91928..36a804b 100644 (file)
@@ -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
         /// <summary>
         /// Colección para objetos ItemViewModel.
         /// </summary>
-        public ObservableCollection<ItemViewModel> ForecastItems { get; private set; }
+        public ObservableCollection<ItemViewModel> ForecastItems{ get; private set; }
         public ObservableCollection<ItemViewModel> CurrentItems { get; private set; }
 
-        
-
-        public bool IsDataLoaded
-        {
-            get;
-            private set;
-        }
 
         /// <summary>
         /// Crear y agregar unos pocos objetos ItemViewModel a la colección Items.
         /// </summary>
-        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<int>(_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<int>(_temperatureUnitsSelectionSettingKeyName, _temperatureUnitsSelectionSettingDefault);
+            if (temperatureUnitsSelection != 0)
             {
-                // TODO: there must be a better way than using the index value :(
-                bool isFahrenheit = true;
-                int temperatureUnitsSelection =
-                    GetValueOrDefault<int>(_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;
         }
 
         /// <summary>
index a4bbe40..e0795ba 100644 (file)
     <Compile Include="Model\ForecastWeatherParser\Temp.cs" />
     <Compile Include="Model\ForecastWeatherParser\Weather.cs" />
     <Compile Include="Model\JsonDataParser\JsonParser.cs" />
+    <Compile Include="Model\WeatherData.cs" />
     <Compile Include="Model\Services\CustomHTTPClient.cs" />
     <Compile Include="Model\Services\ServiceParser.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />