From 6ad9c344133bb93156642c6ef9b4b0f6defe0d5c Mon Sep 17 00:00:00 2001 From: Gustavo Martin Date: Sat, 5 Jul 2014 12:14:38 +0200 Subject: [PATCH] WindowsPhone WeatherInformation Retrieving remote JSON data --- .../WeatherInformation/MapPage.xaml.cs | 41 ++++-- .../Model/JsonDataParser/JsonParser.cs | 2 +- .../Model/Services/CustomHTTPClient.cs | 20 +++ .../Resources/AppResources.Designer.cs | 108 +++++++++++++++ .../Resources/AppResources.es.resx | 2 +- .../Resources/AppResources.es.xlf | 60 +++++++- .../Resources/AppResources.qps-ploc.resx | 2 +- .../Resources/AppResources.qps-ploc.xlf | 60 +++++++- .../WeatherInformation/Resources/AppResources.resx | 48 ++++++- .../WeatherInformation/SettingsPage.xaml | 9 ++ .../WeatherInformation/SettingsPage.xaml.cs | 10 ++ .../WeatherInformation/ViewModels/MainViewModel.cs | 154 +++++++++++++++++---- .../ViewModels/SettingsViewModel.cs | 52 +++++-- .../WeatherInformation/WeatherInformation.csproj | 15 ++ .../WeatherInformation/packages.config | 3 + 15 files changed, 522 insertions(+), 64 deletions(-) create mode 100644 WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs index 3d37029..56622c3 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs @@ -13,38 +13,45 @@ using System.Device.Location; using System.Windows.Shapes; using System.Windows.Media; using Microsoft.Phone.Maps.Controls; +using WeatherInformation.Resources; namespace WeatherInformation { public partial class MapPage : PhoneApplicationPage { + // Settings + private readonly IsolatedStorageSettings _settings; + public MapPage() { InitializeComponent(); + + // Get the _settings for this application. + _settings = IsolatedStorageSettings.ApplicationSettings; } protected override void OnNavigatedTo(NavigationEventArgs e) { - if (!IsolatedStorageSettings.ApplicationSettings.Contains("LocationConsent")) + if (!_settings.Contains("LocationConsent")) { - MessageBoxResult result = - MessageBox.Show("This app accesses your phone's location. Is that ok?", - "Location", + MessageBoxResult result = MessageBox.Show( + AppResources.AskForLocationConsentMessageBox, + AppResources.AskForLocationConsentMessageBoxCaption, MessageBoxButton.OKCancel); if (result == MessageBoxResult.OK) { - IsolatedStorageSettings.ApplicationSettings["LocationConsent"] = true; + _settings["LocationConsent"] = true; } else { - IsolatedStorageSettings.ApplicationSettings["LocationConsent"] = false; + _settings["LocationConsent"] = false; } - IsolatedStorageSettings.ApplicationSettings.Save(); + _settings.Save(); } - if ((bool)IsolatedStorageSettings.ApplicationSettings["LocationConsent"] != true) + if ((bool)_settings["LocationConsent"] != true) { // The user has opted out of Location. return; @@ -89,21 +96,27 @@ namespace WeatherInformation // Add the MapLayer to the Map. this.mapWeatherInformation.Layers.Add(myLocationLayer); - - - //LatitudeTextBlock.Text = geoposition.Coordinate.Latitude.ToString("0.00"); - //LongitudeTextBlock.Text = geoposition.Coordinate.Longitude.ToString("0.00"); + _settings["CurrentLatitude"] = myGeoCoordinate.Latitude; + _settings["CurrentLongitude"] = myGeoCoordinate.Longitude; } catch (Exception ex) { if ((uint)ex.HResult == 0x80004004) { + // the application does not have the right capability or the location master switch is off - //StatusTextBlock.Text = "location is disabled in phone settings."; + MessageBox.Show( + AppResources.NoticeErrorLocationAutodetection, + AppResources.AskForLocationConsentMessageBoxCaption, + MessageBoxButton.OK); } - //else + else { // something else happened acquring the location + MessageBox.Show( + AppResources.NoticeErrorLocationAutodetection, + AppResources.AskForLocationConsentMessageBoxCaption, + MessageBoxButton.OK); } } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Model/JsonDataParser/JsonParser.cs b/WindowsPhone/WeatherInformation/WeatherInformation/Model/JsonDataParser/JsonParser.cs index 3f077cb..326cf0e 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Model/JsonDataParser/JsonParser.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Model/JsonDataParser/JsonParser.cs @@ -8,7 +8,7 @@ namespace WeatherInformation.Model.JsonDataParser class JsonParser { /// - /// The _json settings. + /// The _json _settings. /// private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs b/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs new file mode 100644 index 0000000..083959f --- /dev/null +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Model/Services/CustomHTTPClient.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace WeatherInformation.Model.Services +{ + class CustomHTTPClient + { + async public Task getWeatherData(string url) + { + using (HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) }) + { + return await client.GetStringAsync(url); + } + } + } +} diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.Designer.cs b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.Designer.cs index 68019f7..3b12d42 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.Designer.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.Designer.cs @@ -61,6 +61,15 @@ namespace WeatherInformation.Resources { } /// + /// Busca una cadena traducida similar a 2.5. + /// + public static string APIVersionOpenWeatherMap { + get { + return ResourceManager.GetString("APIVersionOpenWeatherMap", resourceCulture); + } + } + + /// /// Busca una cadena traducida similar a add. /// public static string AppBarButtonText { @@ -88,6 +97,42 @@ namespace WeatherInformation.Resources { } /// + /// Busca una cadena traducida similar a This app accesses your phone's location. Is that ok?. + /// + public static string AskForLocationConsentMessageBox { + get { + return ResourceManager.GetString("AskForLocationConsentMessageBox", resourceCulture); + } + } + + /// + /// Busca una cadena traducida similar a Location. + /// + public static string AskForLocationConsentMessageBoxCaption { + get { + return ResourceManager.GetString("AskForLocationConsentMessageBoxCaption", resourceCulture); + } + } + + /// + /// Busca una cadena traducida similar a Location autodetection seems to be disabled in your phone. + /// + public static string NoticeErrorLocationAutodetection { + get { + return ResourceManager.GetString("NoticeErrorLocationAutodetection", resourceCulture); + } + } + + /// + /// Busca una cadena traducida similar a There is not stored locations.. + /// + public static string NoticeThereIsNotCurrentLocation { + get { + return ResourceManager.GetString("NoticeThereIsNotCurrentLocation", resourceCulture); + } + } + + /// /// Busca una cadena traducida similar a LeftToRight. /// public static string ResourceFlowDirection { @@ -106,6 +151,42 @@ namespace WeatherInformation.Resources { } /// + /// Busca una cadena traducida similar a Forecast day numbers. + /// + public static string SettingsForecastDayNumbersHeader { + get { + return ResourceManager.GetString("SettingsForecastDayNumbersHeader", resourceCulture); + } + } + + /// + /// Busca una cadena traducida similar a 5-Day Forecast. + /// + public static string SettingsForecastDayNumbersSelectionFive { + get { + return ResourceManager.GetString("SettingsForecastDayNumbersSelectionFive", resourceCulture); + } + } + + /// + /// Busca una cadena traducida similar a 14-Day Forecast. + /// + public static string SettingsForecastDayNumbersSelectionFourteen { + get { + return ResourceManager.GetString("SettingsForecastDayNumbersSelectionFourteen", resourceCulture); + } + } + + /// + /// Busca una cadena traducida similar a 10-Day Forecast. + /// + public static string SettingsForecastDayNumbersSelectionTen { + get { + return ResourceManager.GetString("SettingsForecastDayNumbersSelectionTen", resourceCulture); + } + } + + /// /// Busca una cadena traducida similar a Language. /// public static string SettingsLanguageHeader { @@ -158,5 +239,32 @@ namespace WeatherInformation.Resources { return ResourceManager.GetString("SettingsTemperatureUnitsSelectionFahrenheit", resourceCulture); } } + + /// + /// Busca una cadena traducida similar a ºC. + /// + public static string TemperatureUnitsCentigradeSymbol { + get { + return ResourceManager.GetString("TemperatureUnitsCentigradeSymbol", resourceCulture); + } + } + + /// + /// Busca una cadena traducida similar a ºF. + /// + public static string TemperatureUnitsFahrenheitSymbol { + get { + return ResourceManager.GetString("TemperatureUnitsFahrenheitSymbol", resourceCulture); + } + } + + /// + /// Busca una cadena traducida similar a http://api.openweathermap.org/data/{0}/forecast/daily?lat={1}&lon={2}&cnt={3}&mode=json. + /// + public static string URIAPIOpenWeatherMapForecast { + get { + return ResourceManager.GetString("URIAPIOpenWeatherMapForecast", resourceCulture); + } + } } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.resx b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.resx index 621209a..65748f3 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 pageUnidades de temperaturaText in settings pageinglésSettings page, select English languageespañolSettings page, select Spanish languagecelsiusSettings page, select tempereature units centigradefahrenheitSettings page, select temperature units fahrenheit \ 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 fahrenheit \ 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 6f829c2..f413a74 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.xlf +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.es.xlf @@ -31,7 +31,7 @@ Language Idioma - Text in settings page + Text in settings page as header Temperature units @@ -58,6 +58,64 @@ fahrenheit Settings page, select temperature units fahrenheit + + Location + Location + Ask for location consent in map window + + + There is not stored locations. + There is not stored locations. + Main window, notice message, no available locations + + + Location autodetection seems to be disabled in your phone + Location autodetection seems to be disabled in your phone + Map window, notice message, error while location autodetection + + + Forecast day numbers + Forecast day numbers + Text in settings page as header + + + 10-Day Forecast + 10-Day Forecast + Settings page, select forecast day numbers + + + 14-Day Forecast + 14-Day Forecast + Settings page, select forecast day numbers + + + 5-Day Forecast + 5-Day Forecast + Settings page, select forecast day numbers + + + ºF + ºF + + + ºC + ºC + + + This app accesses your phone's location. Is that ok? + This app accesses your phone's location. Is that ok? + Ask for location consent in map window + + + 2.5 + 2.5 + Not to be translated. + + + http://api.openweathermap.org/data/{0}/forecast/daily?lat={1}%%amp;lon={2}%%amp;cnt={3}%%amp;mode=json + http://api.openweathermap.org/data/{0}/forecast/daily?lat={1}%%amp;lon={2}%%amp;cnt={3}%%amp;mode=json + Not to be translated. + diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.resx b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.resx index a363470..be39ccb 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.resx +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.resx @@ -136,7 +136,7 @@ [D9E46][!!_Ļàйģûáğè_!!] - Text in settings page + Text in settings page as header [27946][!!_Ţêmþêŗáτúřê ûиìтş_!!] diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.xlf b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.xlf index 807e3b2..d4361fe 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.xlf +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.qps-ploc.xlf @@ -43,6 +43,64 @@ [9AF14][!!_ƒáĥřêηĥęîţ_!!] Settings page, select temperature units fahrenheit + + Location + Location + Ask for location consent in map window + + + There is not stored locations. + There is not stored locations. + Main window, notice message, no available locations + + + Location autodetection seems to be disabled in your phone + Location autodetection seems to be disabled in your phone + Map window, notice message, error while location autodetection + + + Forecast day numbers + Forecast day numbers + Text in settings page as header + + + 10-Day Forecast + 10-Day Forecast + Settings page, select forecast day numbers + + + 14-Day Forecast + 14-Day Forecast + Settings page, select forecast day numbers + + + 5-Day Forecast + 5-Day Forecast + Settings page, select forecast day numbers + + + ºF + ºF + + + ºC + ºC + + + This app accesses your phone's location. Is that ok? + This app accesses your phone's location. Is that ok? + Ask for location consent in map window + + + 2.5 + 2.5 + Not to be translated. + + + http://api.openweathermap.org/data/{0}/forecast/daily?lat={1}%%amp;lon={2}%%amp;cnt={3}%%amp;mode=json + http://api.openweathermap.org/data/{0}/forecast/daily?lat={1}%%amp;lon={2}%%amp;cnt={3}%%amp;mode=json + Not to be translated. + celsius [EFA86][!!_ćęηťíğŕãďõ_!!] @@ -56,7 +114,7 @@ Language [D9E46][!!_Ļàйģûáğè_!!] - Text in settings page + Text in settings page as header diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.resx b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.resx index 8adccab..39ab410 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.resx +++ b/WindowsPhone/WeatherInformation/WeatherInformation/Resources/AppResources.resx @@ -136,7 +136,7 @@ Language - Text in settings page + Text in settings page as header Temperature units @@ -158,4 +158,50 @@ fahrenheit Settings page, select temperature units fahrenheit + + http://api.openweathermap.org/data/{0}/forecast/daily?lat={1}&lon={2}&cnt={3}&mode=json + Not to be translated. + + + 2.5 + Not to be translated. + + + This app accesses your phone's location. Is that ok? + Ask for location consent in map window + + + Location + Ask for location consent in map window + + + There is not stored locations. + Main window, notice message, no available locations + + + Location autodetection seems to be disabled in your phone + Map window, notice message, error while location autodetection + + + Forecast day numbers + Text in settings page as header + + + 5-Day Forecast + Settings page, select forecast day numbers + + + 14-Day Forecast + Settings page, select forecast day numbers + + + 10-Day Forecast + Settings page, select forecast day numbers + + + ºC + + + ºF + \ No newline at end of file diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/SettingsPage.xaml b/WindowsPhone/WeatherInformation/WeatherInformation/SettingsPage.xaml index ea65478..5de48e9 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/SettingsPage.xaml +++ b/WindowsPhone/WeatherInformation/WeatherInformation/SettingsPage.xaml @@ -34,6 +34,7 @@ + @@ -52,6 +53,14 @@ + + + + + + + + diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/SettingsPage.xaml.cs b/WindowsPhone/WeatherInformation/WeatherInformation/SettingsPage.xaml.cs index bd08d8a..ce2756a 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/SettingsPage.xaml.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/SettingsPage.xaml.cs @@ -51,5 +51,15 @@ namespace WeatherInformation var item = listPicker.Items[index]; listPicker.SelectedItem = item; } + + private void ForecastDayNumbersSelection_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + ListPicker listPicker = sender as ListPicker; + + // TODO: with LINQ :( + int index = listPicker.SelectedIndex; + var item = listPicker.Items[index]; + listPicker.SelectedItem = item; + } } } \ No newline at end of file diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs index 4bf9dee..da91928 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/MainViewModel.cs @@ -2,6 +2,9 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Globalization; +using System.IO.IsolatedStorage; +using System.Threading.Tasks; +using System.Windows; using WeatherInformation.Model.ForecastWeatherParser; using WeatherInformation.Model.JsonDataParser; using WeatherInformation.Model.Services; @@ -11,11 +14,28 @@ namespace WeatherInformation.ViewModels { public class MainViewModel : INotifyPropertyChanged { + // The key names of _settings + // TODO: reuse settings object instead of using the same code here again... + private const string _temperatureUnitsSelectionSettingKeyName = "TemperatureUnitsSelection"; + private const string _forecastDayNumbersSelectionSelectionSettingKeyName = "ForecastDayNumbersSelection"; + + // The default value of _settings + // TODO: reuse settings object instead of using the same code here again... + private const int _temperatureUnitsSelectionSettingDefault = 0; + private const int _forecastDayNumbersSelectionSettingDefault = 0; + + // Settings + private readonly IsolatedStorageSettings _settings; + private readonly ServiceParser _serviceParser; + public MainViewModel() { this.ForecastItems = new ObservableCollection(); this.CurrentItems = new ObservableCollection(); this._serviceParser = new ServiceParser(new JsonParser()); + + // Get the _settings for this application. + _settings = IsolatedStorageSettings.ApplicationSettings; } /// @@ -24,31 +44,7 @@ namespace WeatherInformation.ViewModels public ObservableCollection ForecastItems { get; private set; } public ObservableCollection CurrentItems { get; private set; } - private readonly ServiceParser _serviceParser; - - string _jsonForeCastWeatherData = - "{" - + "\"cod\":\"200\"," - + "\"message\":0.0048," - + "\"city\":{\"id\":2641549,\"name\":\"Newtonhill\",\"coord\":{\"lon\":-2.15,\"lat\":57.033329},\"country\":\"GB\",\"population\":0}," - + "\"cnt\":15," - + "\"list\":[" - + "{\"dt\":1397304000,\"temp\":{\"day\":286.15,\"min\":284.62,\"max\":286.15,\"night\":284.62,\"eve\":285.7,\"morn\":286.15},\"pressure\":1016.67,\"humidity\":84,\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"speed\":7.68,\"deg\":252,\"clouds\":0,\"rain\":0.25}," - + "{\"dt\":1397390400,\"temp\":{\"day\":284.92,\"min\":282.3,\"max\":284.92,\"night\":282.3,\"eve\":283.79,\"morn\":284.24},\"pressure\":1021.62,\"humidity\":84,\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],\"speed\":7.91,\"deg\":259,\"clouds\":92}," - + "{\"dt\":1397476800,\"temp\":{\"day\":282.1,\"min\":280.32,\"max\":282.1,\"night\":280.32,\"eve\":281.51,\"morn\":281.65},\"pressure\":1033.84,\"humidity\":92,\"weather\":[{\"id\":801,\"main\":\"Clouds\",\"description\":\"few clouds\",\"icon\":\"02d\"}],\"speed\":8.37,\"deg\":324,\"clouds\":20}," - + "{\"dt\":1397563200,\"temp\":{\"day\":280.73,\"min\":280.11,\"max\":281.4,\"night\":281.4,\"eve\":280.75,\"morn\":280.11},\"pressure\":1039.27,\"humidity\":97,\"weather\":[{\"id\":801,\"main\":\"Clouds\",\"description\":\"few clouds\",\"icon\":\"02d\"}],\"speed\":7.31,\"deg\":184,\"clouds\":12}," - + "{\"dt\":1397649600,\"temp\":{\"day\":281.73,\"min\":281.03,\"max\":282.22,\"night\":281.69,\"eve\":282.22,\"morn\":281.03},\"pressure\":1036.05,\"humidity\":90,\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04d\"}],\"speed\":7.61,\"deg\":205,\"clouds\":68}," - + "{\"dt\":1397736000,\"temp\":{\"day\":282.9,\"min\":281.45,\"max\":283.21,\"night\":282.71,\"eve\":283.06,\"morn\":281.49},\"pressure\":1029.39,\"humidity\":83,\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04d\"}],\"speed\":6.17,\"deg\":268,\"clouds\":56}," - + "{\"dt\":1397822400,\"temp\":{\"day\":285.26,\"min\":281.55,\"max\":285.26,\"night\":282.48,\"eve\":285.09,\"morn\":281.55},\"pressure\":1025.83,\"humidity\":0,\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"sky is clear\",\"icon\":\"01d\"}],\"speed\":5.31,\"deg\":221,\"clouds\":10}," - + "{\"dt\":1397908800,\"temp\":{\"day\":284.29,\"min\":281.5,\"max\":284.29,\"night\":282.53,\"eve\":283.58,\"morn\":281.5},\"pressure\":1024.55,\"humidity\":0,\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"speed\":5.51,\"deg\":192,\"clouds\":6}," - + "{\"dt\":1397995200,\"temp\":{\"day\":283.36,\"min\":281.62,\"max\":284.34,\"night\":284.04,\"eve\":284.34,\"morn\":281.62},\"pressure\":1019.58,\"humidity\":0,\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"speed\":7.66,\"deg\":149,\"clouds\":0,\"rain\":0.48}," - + "{\"dt\":1398081600,\"temp\":{\"day\":282.24,\"min\":280.51,\"max\":282.41,\"night\":280.51,\"eve\":282.41,\"morn\":280.9},\"pressure\":1027.35,\"humidity\":0,\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"speed\":8.17,\"deg\":221,\"clouds\":10,\"rain\":0.94}," - + "{\"dt\":1398168000,\"temp\":{\"day\":282.28,\"min\":279.76,\"max\":282.28,\"night\":280.69,\"eve\":281.13,\"morn\":279.76},\"pressure\":1038.31,\"humidity\":0,\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"sky is clear\",\"icon\":\"01d\"}],\"speed\":6.33,\"deg\":172,\"clouds\":1}," - + "{\"dt\":1398254400,\"temp\":{\"day\":281.54,\"min\":280.52,\"max\":281.54,\"night\":281.44,\"eve\":281.23,\"morn\":280.52},\"pressure\":1022.4,\"humidity\":0,\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"speed\":7.84,\"deg\":140,\"clouds\":91,\"rain\":1.24}," - + "{\"dt\":1398340800,\"temp\":{\"day\":282.1,\"min\":280.66,\"max\":282.78,\"night\":280.97,\"eve\":282.78,\"morn\":280.66},\"pressure\":1013.39,\"humidity\":0,\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"speed\":9.43,\"deg\":164,\"clouds\":98,\"rain\":1.03}," - + "{\"dt\":1398427200,\"temp\":{\"day\":282.11,\"min\":280.72,\"max\":282.32,\"night\":282.32,\"eve\":280.99,\"morn\":280.72},\"pressure\":1018.65,\"humidity\":0,\"weather\":[{\"id\":502,\"main\":\"Rain\",\"description\":\"heavy intensity rain\",\"icon\":\"10d\"}],\"speed\":5.26,\"deg\":158,\"clouds\":83,\"rain\":14.4}," - + "{\"dt\":1398513600,\"temp\":{\"day\":282.75,\"min\":280.61,\"max\":282.75,\"night\":280.61,\"eve\":281.75,\"morn\":281.96},\"pressure\":1007.4,\"humidity\":0,\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"speed\":9.18,\"deg\":198,\"clouds\":35,\"rain\":0.55}" - + "]}"; + public bool IsDataLoaded { @@ -59,27 +55,127 @@ namespace WeatherInformation.ViewModels /// /// Crear y agregar unos pocos objetos ItemViewModel a la colección Items. /// - public void LoadData() + async public Task LoadData() { - ForecastWeather weather = this._serviceParser.GetForecastWeather(this._jsonForeCastWeatherData); + 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); + int count; + switch(forecastDayNumbers) + { + case(0): + count = 5; + break; + case(1): + count = 10; + break; + case(2): + count = 14; + break; + default: + count = 14; + 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) + { + isFahrenheit = false; + } + double tempUnits = isFahrenheit ? 0 : 273.15; + string symbol = isFahrenheit ? AppResources.TemperatureUnitsFahrenheitSymbol : AppResources.TemperatureUnitsCentigradeSymbol; + DateTime unixTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime date = unixTime.AddSeconds(item.dt).ToLocalTime(); + + // TODO: if I do not receive max temp or min temp... Am I going to receive item.temp.max=0 or item.temp.min=0 (I guess because + // double has no null value) + // I need something that is not 0 value in order to find out if OpenWeatherMap sent me values or not :/ + // I guess; I am going to need nullable but I will have to modify my Json Parser :( + double maxTemp = item.temp.max; + maxTemp = maxTemp - tempUnits; + + double minTemp = item.temp.min; + minTemp = minTemp - tempUnits; + this.ForecastItems.Add(new ItemViewModel() { LineOne = date.ToString("ddd", CultureInfo.InvariantCulture), LineTwo = date.ToString("dd", CultureInfo.InvariantCulture), - LineThree = String.Format("{0:0.##}", item.temp.max), - LineFour = String.Format("{0:0.##}", item.temp.min), + LineThree = String.Format(CultureInfo.InvariantCulture, "{0:0.##}", maxTemp) + symbol, + LineFour = String.Format(CultureInfo.InvariantCulture, "{0:0.##}", minTemp) + symbol, LineFive = "/Assets/Tiles/IconicTileMediumLarge.png" }); + + count--; + if (count == 0) + { + break; + } } this.IsDataLoaded = true; } + /// + /// Get the current value of the setting, or if it is not found, set the + /// setting to the default value. + /// + /// + /// + /// + /// + private T GetValueOrDefault(string Key, T defaultValue) + { + T value; + + // You need to add a check to DesignerProperties.IsInDesignTool to that code since accessing + // IsolatedStorageSettings in Visual Studio or Expression Blend is invalid. + // see: http://stackoverflow.com/questions/7294461/unable-to-determine-application-identity-of-the-caller + if (System.ComponentModel.DesignerProperties.IsInDesignTool) + { + return defaultValue; + } + + // If the key exists, retrieve the value. + if (_settings.Contains(Key)) + { + value = (T)_settings[Key]; + } + // Otherwise, use the default value. + else + { + value = defaultValue; + } + return value; + } + public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/SettingsViewModel.cs b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/SettingsViewModel.cs index ef6d94c..ce56db2 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/SettingsViewModel.cs +++ b/WindowsPhone/WeatherInformation/WeatherInformation/ViewModels/SettingsViewModel.cs @@ -12,18 +12,22 @@ using WeatherInformation.Resources; namespace WeatherInformation.ViewModels { + // TODO: to use this class or something like that in every place of this application where the settings must be retrieved!!! + // (do not copy-paste code!!!) public class SettingsViewModel { // Settings - private IsolatedStorageSettings settings; + private readonly IsolatedStorageSettings _settings; - // The key names of settings + // The key names of _settings private const string _languageSelectionSettingKeyName = "LanguageSelection"; private const string _temperatureUnitsSelectionSettingKeyName = "TemperatureUnitsSelection"; + private const string _forecastDayNumbersSelectionSelectionSettingKeyName = "ForecastDayNumbersSelection"; - // The default value of ListPicker settings + // The default value of ListPicker _settings private const int _languageSelectionSettingDefault = 0; - private const int _temperatureUnitsSelectionSettinDefault = 0; + private const int _temperatureUnitsSelectionSettingDefault = 0; + private const int _forecastDayNumbersSelectionSettingDefault = 0; public SettingsViewModel() @@ -33,8 +37,8 @@ namespace WeatherInformation.ViewModels // see: http://stackoverflow.com/questions/7294461/unable-to-determine-application-identity-of-the-caller if (!System.ComponentModel.DesignerProperties.IsInDesignTool) { - // Get the settings for this application. - settings = IsolatedStorageSettings.ApplicationSettings; + // Get the _settings for this application. + _settings = IsolatedStorageSettings.ApplicationSettings; } } @@ -63,7 +67,7 @@ namespace WeatherInformation.ViewModels { get { - return GetValueOrDefault(_temperatureUnitsSelectionSettingKeyName, _temperatureUnitsSelectionSettinDefault); + return GetValueOrDefault(_temperatureUnitsSelectionSettingKeyName, _temperatureUnitsSelectionSettingDefault); } set { @@ -75,6 +79,24 @@ namespace WeatherInformation.ViewModels } /// + /// Property to get and set forecast day numbers selection Setting Key. + /// + public int ForecastDayNumbersSelectionSetting + { + get + { + return GetValueOrDefault(_forecastDayNumbersSelectionSelectionSettingKeyName, _forecastDayNumbersSelectionSettingDefault); + } + set + { + if (AddOrUpdateValue(_forecastDayNumbersSelectionSelectionSettingKeyName, value)) + { + Save(); + } + } + } + + /// /// Get the current value of the setting, or if it is not found, set the /// setting to the default value. /// @@ -95,9 +117,9 @@ namespace WeatherInformation.ViewModels } // If the key exists, retrieve the value. - if (settings.Contains(Key)) + if (_settings.Contains(Key)) { - value = (T)settings[Key]; + value = (T)_settings[Key]; } // Otherwise, use the default value. else @@ -127,27 +149,27 @@ namespace WeatherInformation.ViewModels } // If the key exists - if (settings.Contains(Key)) + if (_settings.Contains(Key)) { // If the value has changed - if (settings[Key] != value) + if (_settings[Key] != value) { // Store the new value - settings[Key] = value; + _settings[Key] = value; valueChanged = true; } } // Otherwise create the key. else { - settings.Add(Key, value); + _settings.Add(Key, value); valueChanged = true; } return valueChanged; } /// - /// Save the settings. + /// Save the _settings. /// private void Save() { @@ -159,7 +181,7 @@ namespace WeatherInformation.ViewModels return; } - settings.Save(); + _settings.Save(); } } } diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj b/WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj index 4d7bef3..a4bbe40 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj +++ b/WindowsPhone/WeatherInformation/WeatherInformation/WeatherInformation.csproj @@ -118,6 +118,7 @@ + @@ -216,6 +217,15 @@ ..\packages\Newtonsoft.Json.6.0.3\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll + + ..\packages\Microsoft.Net.Http.2.2.22\lib\sl4-windowsphone71\System.Net.Http.dll + + + ..\packages\Microsoft.Net.Http.2.2.22\lib\sl4-windowsphone71\System.Net.Http.Extensions.dll + + + ..\packages\Microsoft.Net.Http.2.2.22\lib\sl4-windowsphone71\System.Net.Http.Primitives.dll + @@ -238,4 +248,9 @@ --> + + + + + \ No newline at end of file diff --git a/WindowsPhone/WeatherInformation/WeatherInformation/packages.config b/WindowsPhone/WeatherInformation/WeatherInformation/packages.config index 226e900..deb89d6 100644 --- a/WindowsPhone/WeatherInformation/WeatherInformation/packages.config +++ b/WindowsPhone/WeatherInformation/WeatherInformation/packages.config @@ -1,5 +1,8 @@  + + + \ No newline at end of file -- 2.1.4