Windows Store App: Change language programmatically - localization

I have a Windows Store App where the user should be able to change its language.
One Screen 1 he selects his language. Then the app switches to screen 2 in the correct language.
My problem is, that screen 2 doesn't get initiated with the correct language. If I switch back to screen 1 and change to a different language, screen 2 has the language selected before.
My localization is located in Resources.resw files.
Here is the code I use:
private void ChangeLanguage(SupportedLanguage language)
{
CultureInfo cultureInfo = CultureInfoForSupportedLanguage(language);
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = cultureInfo.Name;
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
ResourceContext.GetForCurrentView().Reset();
Frame rootFrame = Window.Current.Content as Frame;
rootFrame.Language = cultureInfo.Name;
}

I had the same problem with Windows Store Apps.
I fixed this with a little workaround:
switched - like you - with
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = language;
But I also deleted the Navigation Cache
var Frame = Window.Current.Content as Frame;
Frame.CacheSize = 0;
Frame.Navigate(typeof(Screen1));
Frame.CacheSize = *your Cachesize*;
Frame.Navigate(typeof(Screen2));
Frame.GoBack();
It worked in my case, hope something similar is going to help you

Related

How to enable annotation in PDFJS viewer

I am using PDFJS and the viewer. I do however have the problem that annotation are not shown correctly like the are in the pdfs demo viewer https://mozilla.github.io/pdf.js/web/viewer.html.
Annotation correctly displayed in pdfs demo viewer:
Here is now it is displayed in my app using Chrome:
Here is how it is displayed I Safari using my app:
This is now I initialise the pdfs viewer:
function initPdfjs() {
// Enable hyperlinks within PDF files.
pdfLinkService = new (pdfjsViewer as any).PDFLinkService({
eventBus,
});
// Enable find controller.
pdfFindController = new (pdfjsViewer as any).PDFFindController({
eventBus,
linkService: pdfLinkService,
});
const container = document.getElementById('viewerContainer');
if (container) {
// Initialize PDFViewer
pdfViewer = new (pdfjsViewer as any).PDFViewer({
eventBus,
container,
removePageBorders: true,
linkService: pdfLinkService,
findController: pdfFindController,
});
// pdfViewer.textLayerMode = Utils.enableTextSelection() ? TextLayerMode.ENABLE : TextLayerMode.DISABLE;
pdfViewer.textLayerMode = TextLayerMode.ENABLE_ENHANCE;
// See https://github.com/mozilla/pdf.js/issues/11245
if (Utils.isIos()) {
pdfViewer.maxCanvasPixels = 4000 * 4000;
}
pdfLinkService.setViewer(pdfViewer);
return;
} else {
console.error(`getElementById('viewerContainer') failed`);
}
}
What do I need to do in order to get the annotations to display correctly in my app?
I got it working. I don't know if it is the right way, but I post it in case somebody can use it.
First I setup webpack to copy the content from ./node_modules/pdfjs-dist/web/images to my dist folder so the images got included. That solved all the display errors except {{date}}, {{time}}.
new CopyPlugin({
patterns: [
{ from: './node_modules/pdfjs-dist/web/images', to: '' },
{ from: './l10n', to: 'l10n' },
],
}),
To solve the {{date}}, {{time}} problem I set up a localisation service. I did that by copying the file ng2-pdfjs-viewer-master/pdfjs/web/locale/en-US/viewer.properties to ./l10n/local.properties in my project. Then it is copied to the dist folder by above webpack plugin. I then setup the l10n service in my pdfjs by adding this code:
// initialize localization service, so time stamp in embedded comments are shown correctly
l10n = new (pdfjsViewer as any).GenericL10n('en-US');
const dir = await l10n.getDirection();
document.getElementsByTagName('html')[0].dir = dir;
and added l10n to PDFViewer initialisation:
// Initialize PDFViewer
pdfViewer = new (pdfjsViewer as any).PDFViewer({
eventBus,
container,
removePageBorders: true,
linkService: pdfLinkService,
findController: pdfFindController,
l10n,
});
And now annotations is shown correctly:
What I find a bit weird is the date format. I used en-US as locale, so I would expect it to be mm/dd/yyyy (American way), but it is dd/mm/yyyy (like a dane would prefer it). I have tried to fool around with the date settings on my Mac and language settings in Chrome, but it doesn't look like it has any effect, so I don't know what to do if an American customer complains.

How to show a webview (with all interaction) in secondary display, like apple Tv

I have a viewcontroller which has a webview attached to it. I wan't to mirror it to external screen connected to ipad. I am able to create new window and show images and all, but here i want the exact mirroring of UIWebview (all taps, links, textfield input in web page, video) on secondary display.
func initiateTheExternalDisplay() {
guard UIScreen.screens.count > 1 else {
return
}
let externalScreen = UIScreen.screens[1]
let externalWindow = UIWindow(frame: externalScreen.bounds)
self.externalSecondaryWindow = externalWindow
let roortVc = ExternalPresentationViewController() // this contains view to be shown
self.externalPresentationViewController = rootVc
externalWindow.rootViewController = rootVc
externalWindow.screen = externalScreen
externalWindow.isHidden = false
externalWindow.makeKeyAndVisible()
}
This is how i am instantiating the secondary display and is working fine. Suppose same class is showing the webview, can anyone suggest what info should i pass from here (or alternate way) to achieve mirroring.
I couldn't find any way to do so, so I used a work around. I taking screenshots of the web view controller and updating the secondary view at around 20fps, so it lags a bit but at least able to see the same interaction in almost rela time.

Arabic characters (effective power bug) crash my swift iOS app. how do I properly sanitize inputs to avoid this and related problems?

the text that caused the crash is the following:
the error occurred at the following line:
let size = CGSize(width: 250, height: DBL_MAX)
let font = UIFont.systemFontOfSize(16.0)
let attributes = [
NSFontAttributeName:font ,
NSParagraphStyleAttributeName: paraStyle
]
var rect = text.boundingRectWithSize(size, options:.UsesLineFragmentOrigin, attributes: attributes, context: nil)
where text variable contains the inputted string
parastyle is declared as follows:
let paraStyle = NSMutableParagraphStyle()
paraStyle.lineBreakMode = NSLineBreakMode.ByWordWrapping
My initial idea is that the system font can't handle these characters and I need to do an NSCharacterSet, but I'm not sure how to either just ban characters that'll crash my app or make it so i can handle this input (ideal). I don't want to ban emojis/emoticons either.
Thanks!
Not an answer but some information and that possibly provids a way code way to avoid it.
Updated to information from The Register:
The problem isn’t with the Arabic characters themselves, but in how the unicode representing them is processed by CoreText, which is a library of software routines to help apps display text on screens.
The bug causes CoreText to access memory that is invalid, which forces the operating system to kill off the currently running program: which could be your text message app, your terminal, or in the case of the notification screen, a core part of the OS.
From Reddit but this may not be completely correct:
It only works when the message has to be abbreviated with ‘…’. This is usually on the lock screen and main menu of Messages.app.
The words effective and power can be anything as long as they’re on two different lines, which forces the Arabic text farther down the message where some of the letters will be replaced with ‘…’
The crash happens when the first dot replaces part of one of the Arabic characters (they require more than one byte to store) Normally there are safety checks to make sure half characters aren’t stored, but this replacement bypasses those checks for whatever reason.
My solution is the next category:
static NSString *const CRASH_STRING = #"\u0963h \u0963 \u0963";
#implementation NSString (CONEffectivePower)
- (BOOL)isDangerousStringForCurrentOS
{
if (IS_IOS_7_OR_LESS || IS_IOS_8_4_OR_HIGHER) {
return NO;
}
return [self containsEffectivePowerText];
}
- (BOOL)containsEffectivePowerText
{
return [self containsString:CRASH_STRING];
}
#end
Filter all characters to have same directionality. Unfortunately, I'm only aware of such API in Java.
Don't even try. This is a bug in the operating system that will be fixed. It's not your problem. If you try to fix it, you are just wasting your time. And you are very likely to introduce bugs - when you say you "sanitise" input that means you cannot handle some perfectly fine input.
The company I work at develops a multiplatform group video chat.
In Crashlytics report we started noticing that some users are "effectively" trolling iOS users using this famous unicode sequence.
We can't just sit and wait for Apple to fix this bug.
So, I've worked on this problem, this is the shortest crashing sequence I got:
// unichar representation
unichar crashChars[8] = {1585, 1611, 32, 2403, 32, 2403, 32, 2403};
// string representation
NSString *crashString = #"\u0631\u064b \u0963 \u0963 \u0963"
So, I decided to filter out all text messages that contains two U+0963 'ॣ' symbols with one symbol between them (hope you are able to decipher this phrase)
My code from NSString+Extensions category.
static const unichar kDangerousSymbol = 2403;
- (BOOL)isDangerousUnicode {
NSUInteger distance = 0;
NSUInteger charactersFound = 0;
for (NSUInteger i = 0; i < self.length; i++) {
unichar character = [self characterAtIndex:i];
if (charactersFound) {
distance++;
}
if (distance > 2) {
charactersFound = 0;
}
if (kDangerousSymbol == character) {
charactersFound++;
}
if (charactersFound > 1 && distance > 0) {
return YES;
}
}
return NO;
}
Lousy Specta test:
SpecBegin(NSStringExtensions)
describe(#"NSString+Extensions", ^{
//....
it(#"should detect dangerous Unicode sequences", ^{
expect([#"\u0963 \u0963" isDangerousUnicode]).to.beTruthy();
expect([#"\u0631\u064b \u0963 \u0963 \u0963" isDangerousUnicode]).to.beTruthy();
expect([#"\u0631\u064b \u0963 \u0963 \u0963" isDangerousUnicode]).to.beFalsy();
});
//....
});
SpecEnd
I'm not sure if it's OK to "discriminate" messages with too many "devanagari vowel sign vocalic ll".
I'm open to corrections, suggestions, criticism :).
I would love to see a better solution to this problem.

SKmaps failed to perform multi level search

I want to make a multi level offline search in my app.
I followed the directions at official Skobbler page and only difference is that l did not download map of France, but map of Wyoming instead.
Offline package code for it is USWY if I am right.
-(void)prepareForSearch{
[SKSearchService sharedInstance].searchServiceDelegate = self;
[SKSearchService sharedInstance].searchResultsNumber = 500;
_listLevel = SKCountryList;
_searchSettings = [SKMultiStepSearchSettings multiStepSearchSettings];
_searchSettings.listLevel = _listLevel;
_searchSettings.offlinePackageCode = #"USWY";
_searchSettings.parentIndex=-1;
}
- (IBAction)searchAction:(UIButton *)sender {
_searchSettings.searchTerm = [NSString stringWithFormat:#"%#",_searchBar.text];
[[SKSearchService sharedInstance]startMultiStepSearchWithSettings:_searchSettings];
}
-(void)searchService:(SKSearchService *)searchService didRetrieveMultiStepSearchResults:(NSArray *)searchResults
{
if ([searchResults count] !=0 && _listLevel<SKInvalidListLevel){
if (_listLevel == SKCountryList) {
_listLevel = SKCityList;
}
else{
_listLevel++;
}
SKSearchResult *searchResult = searchResults[0];
SKMultiStepSearchSettings* multiStepSearchObject = [SKMultiStepSearchSettings multiStepSearchSettings];
multiStepSearchObject.listLevel = _listLevel++;
multiStepSearchObject.offlinePackageCode = _searchSettings.offlinePackageCode;
multiStepSearchObject.searchTerm = _searchBar.text;
multiStepSearchObject.parentIndex = searchResult.identifier;
[[SKSearchService sharedInstance]startMultiStepSearchWithSettings:multiStepSearchObject];
}
}
-(void)searchServiceDidFailToRetrieveMultiStepSearchResults:(SKSearchService *)searchService
{
NSLog(#"Multi Level Search failed");
}
Whatever I put as a searchTerm, I end up with "MultiLevel Search Failed".
from this screenshot, you can see that my map package for Wyoming is included in my SKMaps.bundle:
(Also, if anyone can answer me this: Versioning was different in my app and in the simulator folder in the test app, from where I downloaded an offline package. So, for testing purposes, I made two folders and put Wyoming package in both of them(20140807 and 20140910). Are there any rules regarding this?)
What could be the problem?
Ok, after few days I managed to find the source of the problem.
First, I found out which version I'm using and it's the 20140910.
Second, For some reason, the entire folder containing maps was not recognised. So I took the entire SKMaps.bundle, together with some pre-bundled maps from the demo app, provided by the Skobbler team, and put it in my project and now everything works fine.

Is there a replacement for AUSplitter in iOS?

AUSplitter takes an audio signal and makes multiple copies of it. However, it is only available on OS X. How can I achieve the same effect in iOS?
For future reference, the kAudioUnitSubType_Splitter audio unit was added in iOS 6. From the AUComponent headers:
enum {
kAudioUnitSubType_AUConverter = 'conv',
kAudioUnitSubType_Varispeed = 'vari',
kAudioUnitSubType_DeferredRenderer = 'defr',
kAudioUnitSubType_Splitter = 'splt',
kAudioUnitSubType_Merger = 'merg',
kAudioUnitSubType_NewTimePitch = 'nutp',
#if !TARGET_OS_IPHONE
kAudioUnitSubType_TimePitch = 'tmpt',
kAudioUnitSubType_RoundTripAAC = 'raac'
#else
kAudioUnitSubType_AUiPodTime = 'iptm',
kAudioUnitSubType_AUiPodTimeOther = 'ipto'
#endif
};
I ended up creating a custom class called Splitter. The Splitter class allows you to set its upstream audio unit.
It also has a render method similar to AudioUnitRender. When its render method is called it alternates between asking its upstream audio unit to render and buffering the rendered data and simply returning the buffered copy of the last render operation.
Its only a 1-2 Splitter and it doesn't handle format conversions, but it worked for what I needed.

Resources