Opening app from email link in NativeScript vue iOS - nativescript

Edit For more explanation on how to use this plugin with vue, please see NativeScript vue, vuex and urlhandler
I'm trying to make it so that a link in an email can open an app I'm building (its a test app I'm building to learn NativeScript). I am using https://www.npmjs.com/package/nativescript-urlhandler with NativeScript vue on iOS.
In platforms/ios/######/app/App_Resources/iOS/Info.plist I have added
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.#######.######</string>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>mycustomappfoobar</string>
</array>
</dict>
</array>
And within app.js, I have added:
const handleOpenURL = require("nativescript-urlhandler").handleOpenURL;
handleOpenURL(function(appURL) {
console.log('Got the following appURL', appURL);
});
When tapping on mycustomappfoobar://test (link in email) nothing happens...
I looked at the Angular example, and handleOpenURL is being called on initialisation... So I tried putting handleOpenURL within vues mounted hook - but this doesn't work either. Really stumped...
new Vue({
mounted() {
handleOpenURL(function(appURL) {
console.log('Got the following appURL', appURL);
});
},
render: h => h("frame", [h(Home)]),
store: Store
}).$start();

You are updating wrong info.plist. Basically anything inside platforms folder is auto generated. Use the one within your App_Resources/iOS/info.plist.

You are calling handleOpenURL too late. This should be called prior to your Vue context being created so that the UIAppDelegate can be properly augmented behind the scenes.
From https://github.com/hypery2k/nativescript-urlhandler/blob/cd6939119910b6345e444055ad17716a7c0ad1d6/demo/app/app.ts
import { handleOpenURL, AppURL } from 'nativescript-urlhandler';
import './app.scss';
import './bundle-config';
import * as app from 'application';
handleOpenURL((appURL: AppURL) => {
console.log('handleOpenURL', appURL);
});
app.start({ moduleName: 'main-page' });

Related

Cypress.io custom command 'TypeError is not a function'

I'm getting an error when using a custom command I've added to my /support/commands.js file.
What is worth mentioning, all others custom commands I've added work fine.
I've followed some other solutions others have mentioned on this forum but none have helped.
I've restarted both VSCode and Cypress.io to no avail.
My cypress.json file is as follows (I'm missing my projectId, where do I find it?):
{
"supportFile": "cypress/support/index.js"
}
Cypress code:
// verify the stepper header
cy.verifyStepperHeader()
custom command:
// verify the stepper header
Cypress.Commands.add('verifyStepperHeader', () => {
cy.get('.stepper-header').scrollIntoView()
.should('be.visible').within(() => {
cy.contains('User Targets').should('be.visible')
cy.contains('Data Upload').should('be.visible')
cy.contains('Data Quality').should('be.visible')
cy.contains('Sensor Mapping').should('be.visible')
cy.contains('Tuning Mode').should('be.visible')
cy.contains('Tuning').should('be.visible')
cy.contains('Tuning Results').should('be.visible')
cy.contains('Validation').should('be.visible')
cy.contains('Validation Results').should('be.visible')
cy.contains('Summary').should('be.visible')
})
})
I've also got
// Import commands.js using ES2015 syntax:
import './commands'
in my index.js file which I think is the default.

VueJS Performance Questions

I'm working on a browser extension that uses Vue Cli with Vue Bootstrap. I've already optimized my Vue Bootstrap imports to only load the components and icons I use in the project. I also have lazy loaded route components, but I still see a long time to get to the created hook of my first component. Here's a code extract:
Main entry point
console.info("Loaded in " + (new Date().getTime() - global.start) + "ms")
require("#/App.js")
App.js
import Vue from "vue"
import * as Sentry from "#sentry/vue"
import { Integrations } from "#sentry/tracing"
import App from "#/App.vue"
import router from "#/common/router"
import store from "#/common/store"
import { get } from "#/common/api"
...
import {
ModalPlugin,
ButtonPlugin,
TabsPlugin,
DropdownPlugin,
AlertPlugin,
ToastPlugin,
FormInputPlugin,
FormRadioPlugin,
...
BIconArrowRightShort,
BIconArrowDownSquareFill,
} from "bootstrap-vue"
Vue.use(ModalPlugin)
Vue.use(ButtonPlugin)
Vue.use(TabsPlugin)
...
Vue.component("BIcon", BIcon)
Vue.component("BIconX", BIconX)
Vue.component("BIconArrowLeft", BIconArrowLeft)
Vue.component("BIconMailbox", BIconMailbox)
Vue.component("BIconFolderPlus", BIconFolderPlus)
Vue.component("BIconEnvelope", BIconEnvelope)
...
global.vm = new Vue({
router,
store,
render: h => h(App),
created() {
this.$router.push({ name: "Responses" })
...
})
}
And here's my component file that gets loaded first:
<template>
<div>
<div>
...
</div>
</div>
</template>
<script>
let now = new Date().getTime()
console.info("SFC file loaded in " + (now - global.start) + "ms")
import ... from "#/common/components/..."
export default {
...
mounted() {
let now = new Date().getTime()
...
</script>
<style lang="scss">
...
</style>
When I benchmark times, this is what I get:
SFC file loaded at 46ms (at the top of the script section)
Created Hook starts a 177ms
Mounted Hook starts at 308ms
I'm wondering what takes so long in the created hook (I don't do much, just checking the $route parameters). 150ms to just go through the created hook seems like a lot?
Here's the created hook:
console.info("Created Hook in " + (new Date().getTime() - global.start) + "ms")
if (this.$route.params.xx {
this.... = this.$store.state.xxxx.find(e => {
return e.uuid == .......
})
}
Performance loading the extension is important for the user experience, and it always feels a little sluggish when opening the extension popup.
Any idea on what could delay the loading like that?
Thanks!
The first thing that I notice is that you are doing a route.push on App created hook, that means that the router already solve the first route (probably '/') and after that you are adding another route (but not immediately) and then the router is solving that new route.
For a faster boot why don't you add a redirect to the route:
//...routes
{
path: '/',
redirect: {name: 'Responses'}
}
If you have the opportunity to change to Vue3 then maybe you could also perceive a performance boost since Vue2 has an always present GlobalAPI and Vue3 is doing a tree shaking and ignoring the unused stuff after building.
Note: Make sure you are testing it with a production environment, because if you are using the vue-cli to serve the content then the startup will include a lot of overhead
Thanks guys! Actually the default route is already redirecting to Responses, and removing the push doesn't change much.
Unfortunately I can't really migrate to Vue 3 as I rely on dependencies that do not fully support Vue 3 (Vue BS being an important one).
I'm guessing that's as much as I can do at this point. Just wondering if there's any way with Vue Cli to open the window browser extension popup immediately and load Vue afterwards (right now, it's waiting for the whole thing to be loaded and then opens the popup which gives a 300ms delay between the click and the window actually opening).
There is much more what happens between created and mounted hooks - it's not just the code in all created hooks what is running. Check the Vue component lifecycle
As you are using Vue SFC'c and probably Webpack, template compilation is out of the question but still, after created Vue is executing render functions of all components (producing VDOM) and creating real DOM elements based on VDOM (rendering whole app). So depending on number of components and elements, 150ms is not that bad...

How do I open in-app browser window in React native?

I'm trying to open the browser window without leaving the app when I click a URL (for both iOS and Android).
The behavior should be as follows (with airbnb app example):
Clicks in "Terms and conditions" link: links example
Open the browser in-app:
For iOS: in-app browser iOS
Same for Android.
How can I do this? Do I need to use any specified existing library?
I'm using react-native 0.37.
You can use the new InAppBrowser plugin for React Native, check the next example:
import { Linking } from 'react-native'
import InAppBrowser from 'react-native-inappbrowser-reborn';
...
async openLink() {
try {
const isAvailable = await InAppBrowser.isAvailable()
const url = 'https://www.google.com'
if (isAvailable) {
InAppBrowser.open(url, {
// iOS Properties
dismissButtonStyle: 'cancel',
preferredBarTintColor: 'gray',
preferredControlTintColor: 'white',
// Android Properties
showTitle: true,
toolbarColor: '#6200EE',
secondaryToolbarColor: 'black',
enableUrlBarHiding: true,
enableDefaultShare: true,
forceCloseOnRedirection: true,
}).then((result) => {
Alert.alert(JSON.stringify(result))
})
} else Linking.openURL(url)
} catch (error) {
Alert.alert(error.message)
}
}
...
On the other hand, you can use this plugin with deep linking, check the README of the project.
Opens Safa Module Method
On iOS SafariView 3rd party native module - https://github.com/naoufal/react-native-safari-view
On Android CustomTabs 3rd party native module - https://github.com/droibit/react-native-custom-tabs - however if the user does not have Chrome installed, it will pop open the link outside of your app in their default browser.
Alternative WebView Method
You can use a <WebView> but this is not using the real browser - http://facebook.github.io/react-native/releases/0.47/docs/webview.html#webview
import React, { Component } from 'react';
import { WebView } from 'react-native';
class MyWeb extends Component {
render() {
return (
<WebView
source={{uri: 'https://github.com/facebook/react-native'}}
style={{marginTop: 20}}
/>
);
}
}
Use React Native Custom Tabs to open in-app browser window in React native. It support both platform Android and iOS
You can use React Native In-App Browser Reborn. It works perfectly on both Android and iOS.
This library use react-native-safari-view (SafariView) on iOS and react-native-custom-tabs (ChromeView) on Android.
Use native react native linking to open a url
https://reactnative.dev/docs/linking

MeteorJS Package : Accessing "events" and "helpers" of a Template inside a package (internally)

I created a local package and added to my project, and added templating.
package.js
`Package.onUse(function(api) {
api.versionsFrom('1.4.2.3');
api.use('templating', 'client');
api.addFiles('server/main.js', 'server');
api.addFiles('client/main.js', 'client');
api.addFiles('client/main.html', 'client');
api.mainModule('pkgName.js');
});`
I created a template in client/main.html.
<template name="myTemplate">
<button>Test</button>
</template>
Then in client/main.js, i set the event listener:
Template.myTemplate.events({
'click button': function (e,t){ //do this on click };
})
But when i run the app - i get console error
Uncaught TypeError: Cannot read property 'events' of undefined
OK - after a couple of hours of research it seems that the Package.onUse function must list dependencies in the order that they should be loaded.
I thought the load order was only relevant to the 'packages' file in the main application, but it seems that you need to load the dependencies in order as well.
So this fixed it---
Package.onUse(function(api) {
api.versionsFrom('1.4.2.3');
api.addFiles('client/main.html', 'client');
// I moved the html file above the javascript - so the DOM loads first and then the template exists for the event listener to listen to.
api.use('templating', 'client');
api.addFiles('server/main.js', 'server');
api.addFiles('client/main.js', 'client');
api.mainModule('pkgName.js');
});

Change nativescript theme with nativescript-themes plugin in app launch

How can I change the NativeScript app theme during the app launch using the nativescript-themes plugin?
JS
import application = require("application");
let themes = require("nativescript-themes");
themes.applyTheme('dark-theme.css');
// TODO: Check if user is logged in
application.start({ moduleName: "views/signin/signin" });
This isn't working, and yes, this is TS but the transpiled JS doesn't work.
Actually the proper code is:
import application = require("application");
let themes = require("nativescript-themes");
application.cssFile = themes.getAppliedTheme('dark-theme.css');
application.start({ moduleName: "views/signin/signin" });
The theming system replaces the currently running "app.css"; so you no longer are using the default "app.css". If you need app.css still; then you just import into your theme.css files using the #import statement.
Please note; the 'dark-theme.css' that you are using in getAppliedTheme('dark-theme.css') is the default theme, if the theme has been changed/chosen by the user in the app and the app is starting up again, then it will use the actual chosen theme, not the default theme. ;-)
You can change the theme using the *
import { Theme } from "#nativescript/theme";
#Component({
selector: 'ns-app',
templateUrl: 'app.component.html',
})
export class AppComponent implements OnInit {
constructor() {}
ngOnInit(): void {
Theme.setMode(Theme.Light);
}
}
plugin then make changes in the main app.component.ts file as per the below code.
You can also change the mode by putting conditions in the ngOnInit lifecycle.

Resources