When the app starts - how is the default timezone set? (Nativescript) - nativescript

When the app starts - how is the default JVM timezone set?
I assume it get's the device's timezone (where ever they might be) -
and that's what's returned by TimeZone.getDefault()
I'm not getting that behavior on Android simulator - I went into
phone Settings for Date/time and explicitly set it to mine local.
It's off by 1 hr - almost as it doesn't know about daylight savings.

I'm using the next function which allows me to get the device timezone.
import { isIOS } from '#nativescript/core';
export function getTimeZone(): string {
if (isIOS) {
return NSTimeZone.localTimeZone.name;
} else {
return java.util.TimeZone.getDefault().getID();
}
}

Related

Appcelerator iOS 12 Location

Are there new code changes to be made for iOS 12 when it comes to location services, as opposed to iOS 11?
I have the following code that works perfectly in iOS 11, but in iOS 12, even though it asks for the prompts as far as always/when in use, and I see the GPS icon, I get undefined on my e.coords.
var hasLocationPermission = Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS);
if (hasLocationPermission) {
//this just calls the function, but it the e.coords comes back as undefined in iOS 12, fine in iOS 11
getLocation();
}
function getLocation() {
Ti.Geolocation.addEventListener('location', function (e) {
try {
longitude = e.coords.longitude;
latitude = e.coords.latitude;
} catch (err) {
console.log('err', err)
}
});
}
Make sure to include the iOS 11+ NSLocationAlwaysAndWhenInUseUsageDescription key in your plist, which became more important in iOS 12, because the prompt will suggest to use the less critical "when in use" permission if you do not include the above key. In addition, make sure to always first ask for the "when in use" permission and then upgrade to "always" later.
See the Ti.Geolocation docs for details.

How to ignore system messages on application level? (WM_SettingChange / WM_WinIniChange)

We have an application that misbehaves when the user changes the date format in his Windows region settings. (Yes, the solution would be to fix the misbehaviour--- not the point here.)
Changing the settings braodcasts a WM_SETTINGCHANGE message to all applications. We're trying to avoid our problem by ignoring this message and keep the date format as it was (for now, as a hotfix).
Whatever I do, the TMonthCalendar component still changes its format, as well as TDateTimePicker which uses TMonthCalendar as its popup.
I tried (all with the same result):
Overriding TForm::WndProc()
void __fastcall TfrmMainWindow::WndProc( TMessage & msg )
{
if( msg.Msg == WM_SETTINGCHANGE ) return; // ignore
TForm::WndProc( msg );
}
Setting a hook with Application->HookMainWindow( hookWindowsMessage );
Setting TApplication.UpdateFormatSettings = false;
Setting Application->OnEvent = onApplicationEvent; to catch all events... but unfortunately this specific case falls under the "OnMessage only receives messages that are posted to the message queue, not those sent directly with the Windows API SendMessage function." rule.
It would seem that overriding WndProc() is almost a good idea, only that it only affects that one window, not the application as a whole. I thought that's what Application->HookMainWindow() was for, but apparently not.
Anyone any idea how to solve or circumvent this problem?
As Cody Gray states in the comment above, the problem is not the message handling but the TMonthCalendar component which uses the Win32 API calendar and thus works outside the application context.
However, for all other components (ie. TDateTimePicker's line edit) and internal global variables (like ShortDateFormat etc.) it is possible to ignore the format change as follows:
class TfrmMainWindow : public TForm
{
public:
__fastcall TfrmMainWindow( TComponent * Owner )
: TForm( Owner )
{
Application->HookMainWindow( hookWindowsMessage );
}
__fastcall ~TfrmMainWindow()
{
Application->UnhookMainWindow( hookWindowsMessage );
}
private:
bool __fastcall hookWindowsMessage( TMessage & msg )
{
if( msg.Msg == WM_SETTINGCHANGE )
{
String sLParam( (char *)msg.LParam );
// Check for Region Settings change (not Desktop background etc.)
if( sLParam.LowerCase() == "intl" )
{
return true; // ignore message
}
}
return false; // handle message as usual
}
};
Sources:
"Trapping Messages Sent to an Application"
"TMonthCalendar displays dates according to the system locale (ignoring the BiDiMode setting)."
"The Win32 API provides a control used to select dates on a colorful calendar. The dates used and the way they display are based on the Regional Settings of the Control Panel."

ViewModels and IsolatedStorageSettings

Im working on a MVVM Windows phone app that displays weather info.
When the app loads up it opens MainPage.xaml. It makes a call the the service to get weather info and binds that data to the UI. Both Fahrenheit and Celcius info are returned but only one is displayed.
On the setting page, the user can select to view the temp in either Fahrenheit or Celcius.
The user can change this setting at any time and its stored in IsolatedStorageSettings.
The issue Im having is this:
when the user navigates to the Settings page and changes their preference for either Fahrenheit or Celcius, this change is not reflected on the main page.
This issue started me thinking about this in a broader context. I can see this being an issue in ANY MVVM app where the display depends on some setting in IsolatedStorage. Any time any setting in the IsoStore is updated, how does the ViewModels know this? When I navigate back in the NavigationStack from the settings page back to MainPage how can I force a rebind of the page?
The data in my model hasnt changed, only the data that I want to display has changed.
Am I missing something simple here?
Thanks in advance.
Alex
Probably you have code like this:
public double DisplayTemperature
{
get { return (IsCelsium) ? Celsium : Fahrenheit; }
}
And IsCelsium is:
public double IsCelsium
{
get { return (bool)settings["IsCelsium"]; }
set { settings["IsCelsium"] = value; }
}
So you need to add NotifyPropertyChanged event to notify UI to get new values from DisplayTemperature property:
public double IsCelsium
{
get { return (bool)settings["IsCelsium"]; }
set
{
settings["IsCelsium"] = value;
NotifyPropertyChanged("DisplayTemperature");
}
}
Take a look at Caliburn Micro. You could implement something similar or use CM itself. When using CM I don't even think about this stuff, CM makes it so simple.
When your ViewModel inherits from Screen there are life-cycle events that fire that you can override. For example, OnInitialize fires the very first time the ViewModel is Activated and OnActivate fires every time the VM is activated. There's also OnViewAttached and OnViewLoaded.
These methods are the perfect place to put logic to populate or re-populate data.
CM also has some special built in features for allowing one to easily tombstone a single property or an entire object graph into Iso or phone state.
ok, so Ive come up with a solution. Before I get to it, let me provide some background. The app that Im working on uses both MVVM Light and WP7Contrib. That being the case, I am using Funq for DI and the MVVMLight Toolkit. After I posted my initial question, I gave the question a bit more thought. I remembered a video that I watched a while back from MIX2011 called Deep Dive MVVM with Laurent Bugnion
http://channel9.msdn.com/Events/MIX/MIX11/OPN03
In it, he talks about just this problem (view models not living at the same time) on Windows Phone. The part in question starts around the 19 minute mark.
Anyway, after I remembered that and realized that the ViewModel locator is exposed in App.xaml, this became a trivial problem to solve. When the user changes the Fahrenheit/Celcius option on the setting page, I simply get a reference to the MainViewModel via the ViewModelLocator and reset the collection that is bound to the UI thus causing the bindings to update.
public bool AddOrUpdateValue(string Key, Object value)
{
bool valueChanged = false;
// If the key exists
if (settings.Contains(Key))
{
// If the value has changed
if (settings[Key] != value)
{
// Store the new value
settings[Key] = value;
valueChanged = true;
}
}
// Otherwise create the key.
else
{
settings.Add(Key, value);
valueChanged = true;
}
return valueChanged;
}
public bool ImperialSetting
{
get
{
return GetValueOrDefault<bool>(ImperialSettingKeyName, ImperialSettingDefault);
}
set
{
if (AddOrUpdateValue(ImperialSettingKeyName, value))
{
Save();
RaisePropertyChanged("ImperialSettingText");
var vml = new ViewModelLocator();
vml.MainViewModel.Cities = (App.Current as App).Cities;
}
}
}
It was a mistake on my part not to realize that I could get access to the viewModel via the ViewModelLocator. Hopefully this post saves someone else the time I burned on this issue.

Cache Shows Old Values on IIS7, not Debug Server

I have a pretty standard MVC3 application. I'm trying to store some data that's application-wide (not user wide) in a the cache (in this case, a Theme object/name). When debugging (on the development server that integrates with Visual Studio), if I call SwitchTheme, I see the new theme right away. On IIS7, whatever theme was cached, stays cached; it doesn't update to the new theme.
Edit: Some code:
public static Theme CurrentTheme { get {
Theme currentTheme = HttpContext.Current.Cache[CURRENT_THEME] as Theme;
if (currentTheme == null)
{
string themeName = DEFAULT_THEME;
try
{
WebsiteSetting ws = WebsiteSetting.First(w => w.Key == WebsiteSetting.CURRENT_THEME);
if (ws != null && !string.IsNullOrEmpty(ws.Value))
{
themeName = ws.Value;
}
}
catch (Exception e)
{
// DB not inited, or we're installing, or something broke.
// Don't panic, just use the default.
}
// Sets HttpContext.Current.Cache[CURRENT_THEME] = new themeName)
Theme.SwitchTo(themeName);
currentTheme = HttpContext.Current.Cache[CURRENT_THEME] as Theme;
}
return currentTheme;
} }
public static void SwitchTo(string name)
{
HttpContext.Current.Cache.Insert(CURRENT_THEME, new Theme(name), null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));
// Persist change to the DB.
// But don't do this if we didn't install the application yet.
try
{
WebsiteSetting themeSetting = WebsiteSetting.First(w => w.Key == WebsiteSetting.CURRENT_THEME);
if (themeSetting != null)
{
themeSetting.Value = name;
themeSetting.Save();
}
// No "else"; if it's not there, we're installing, or Health Check will take care of it.
}
catch (Exception e)
{
// DB not inited or install not complete. No worries, mate.
}
}
I'm not sure where the problem is. I am calling the same method and updating the cache; but IIS7 just shows me the old version.
I can disable output caching in IIS, but that's not what I want to do. That seems like a hacky work-around at best.
Without a code sample it's difficult to know what your problem is. In an attempt to provide some assistance, here is how I frequently set the cache in my applications:
public static void SetCache(string key, object value) {
if (value != null) {
HttpRuntime.Cache.Insert(key, value, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));
}
}
The HTTP cache is reset only if you do so manually or the app domain (or app pool) resets for whatever reason. Are you sure that's not happening in this case? And generally speaking, any global static variables would also be maintained in memory under the same circumstances.
There are many reasons why an app pool might be reset at any given point, such as a change to a web.config file, etc. I suggest checking that's not happening in your case.
By the way, output caching is a different thing, although it is maintained in memory largely the same way.
Given that this only happens on IIS7 when Output Caching is not disabled, this seems very likely to be an IIS7 bug. Seriously.
Whether it is or not, is irrelevant to the solution. What you need to do is find some manual process of invalidating the cache, such as touching the web.config file.
But beware: doing this will wipe out the cache (as you expect), but also all static variables (as a side-effect). Whether this is another bug or not, I don't know; but in my case, this was sufficient to solve the problem.

In Outlook 2007 using VSTO 3.0, how to detect if the default store has changed since Outlook was started?

I'm doing something similar to this, but wondering if there is an event somewhere that I'm missing
Store DefaultStore
{
get
{
var defaultStore = mOutlookApp_Model.Session.DefaultStore;
if ( defaultStore.StoreID == mDefaultStore.StoreID )
{
// the default store we set at startup is the same as the default store now, so all good
return mDefaultStore;
}
else
{
// the user changed the default store, so restart the addin_app
DefaultStoreChangedRestartAddIn.Fire();
return null;
}
}
}
readonly Store mDefaultStore;
Nope there isn't anything like this in the API, so hand crafting something is the only way.

Resources