Creating native classes
Hello folks,
I was wondering if exist any example to create native classes? e.g: https://github.com/proyecto26/nativescript-inappbrowser/blob/develop/src/InAppBrowser.ios.ts#L36
Thanks for your help! <3
Hello, I'm testing this plugin and I'm getting this error
CONSOLE LOG file:///public/nativescript/index.js:794:16: Hello iOS 👋 🎉 ~ NativeScript Team
⚡️ Loading app at capacitor://localhost...
⚡️ To Native -> NativeScriptCap addListener 22549302
⚡️ To Native -> NativeScriptCap notify -1
⚡️ To Native -> NativeScriptCap notify -1
⚡️ To Native -> NativeScriptCap notify -1
⚡️ To Native -> NativeScriptCap notify -1
⚡️ To Native -> NativeScriptCap notify -1
⚡️ To Native -> NativeScriptCap notify -1
⚡️ To Native -> NativeScriptCap notify -1
⚡️ ------ STARTUP JS ERROR ------
⚡️ TypeError: Cannot convert a symbol to a string
⚡️ URL: capacitor://localhost/static/js/6.a9603605.chunk.js
⚡️ 6.a9603605.chunk.js:2:115618
⚡️ See above for help with debugging blank-screen issues
⚡️ WebView loaded
⚡️ To Native -> NativeScriptCap notify -1
⚡️ To Native -> NativeScriptCap notify -1
⚡️ [error] - {"line":2,"column":115618,"sourceURL":"capacitor://localhost/static/js/6.a9603605.chunk.js"}
⚡️ TO JS {"platform":false,"tracking":-1,"cmd":6}
⚡️ To Native -> NativeScriptCap notify -1
⚡️ To Native -> NativeScriptCap notify -1
check the code below:
import { native, nativeAPI } from '@nativescript/capacitor';
type SFSafariViewController = nativeAPI.SFSafariViewController;
type ASWebAuthenticationSession = nativeAPI.ASWebAuthenticationSession;
type SFSafariViewControllerDelegate = nativeAPI.SFSafariViewControllerDelegate;
type UIAdaptivePresentationControllerDelegate = nativeAPI.UIAdaptivePresentationControllerDelegate;
type ASWebAuthenticationPresentationContextProviding = nativeAPI.ASWebAuthenticationPresentationContextProviding;
const {
NSObject,
NSURL,
SFSafariViewControllerConfiguration,
SFSafariViewController,
UIApplication
} = native;
class InAppBrowserModule
extends NSObject
implements
SFSafariViewControllerDelegate,
UIAdaptivePresentationControllerDelegate,
ASWebAuthenticationPresentationContextProviding
{
public async open (
authUrl: string,
options?: any
) {
const url = NSURL.URLWithString(authUrl);
const config = SFSafariViewControllerConfiguration.alloc().init();
config.barCollapsingEnabled = options.barCollapsingEnabled;
config.entersReaderIfAvailable = options.readerMode;
const safariVC = SFSafariViewController.alloc().initWithURLConfiguration(url, config);
safariVC.delegate = this;
const ctrl = UIApplication.sharedApplication.keyWindow.rootViewController;
ctrl.presentViewControllerAnimatedCompletion(safariVC, options.animated, () => null);
}
public presentationAnchorForWebAuthenticationSession(_: ASWebAuthenticationSession) {
return UIApplication.sharedApplication.keyWindow;
}
public safariViewControllerDidFinish(controller: SFSafariViewController): void {
// TODO: Resolve promise
console.log('BROWSER Closed')
}
}
native.InAppBrowser = <InAppBrowserModule>InAppBrowserModule.new()
Please let me know what you think, thanks in advance!
Hello folks, now I'm getting another error:
file:///public/nativescript/index.js:1602:18: JS ERROR ReferenceError: Can't find variable: window
2021-03-21 19:09:29.584023-0500 App[15212:713562] *** Terminating app due to uncaught exception 'NativeScript encountered a fatal error: ReferenceError: Can't find variable: window
But I'm not using window or something like that, this is my code:
import { native, nativeAPI } from '@nativescript/capacitor';
import '@nativescript/capacitor/bridge';
type SFSafariViewController = nativeAPI.SFSafariViewController;
type ASWebAuthenticationSession = nativeAPI.ASWebAuthenticationSession;
type SFSafariViewControllerDelegate = nativeAPI.SFSafariViewControllerDelegate;
type UIAdaptivePresentationControllerDelegate = nativeAPI.UIAdaptivePresentationControllerDelegate;
type ASWebAuthenticationPresentationContextProviding = nativeAPI.ASWebAuthenticationPresentationContextProviding;
@NativeClass()
class InAppBrowserModule
extends native.NSObject
implements
SFSafariViewControllerDelegate,
UIAdaptivePresentationControllerDelegate,
ASWebAuthenticationPresentationContextProviding
{
public static ObjCProtocols = [
native.SFSafariViewControllerDelegate,
native.UIAdaptivePresentationControllerDelegate,
native.ASWebAuthenticationPresentationContextProviding
];
public open (
authUrl: string,
options?: any
) {
const url = native.NSURL.URLWithString(authUrl);
const config = native.SFSafariViewControllerConfiguration.alloc().init();
config.barCollapsingEnabled = options.barCollapsingEnabled;
config.entersReaderIfAvailable = options.readerMode;
const safariVC = native.SFSafariViewController.alloc().initWithURLConfiguration(url, config);
safariVC.delegate = this;
const ctrl = native.UIApplication.sharedApplication.keyWindow.rootViewController;
ctrl.presentViewControllerAnimatedCompletion(safariVC, !!options.animated, () => null);
}
public presentationAnchorForWebAuthenticationSession(_: ASWebAuthenticationSession) {
return native.UIApplication.sharedApplication.keyWindow;
}
public safariViewControllerDidFinish(controller: SFSafariViewController) {
// TODO: Resolve promise
//console.log('BROWSER Closed')
}
}
let InAppBrowserModuleInstance: any;
if (typeof InAppBrowserModuleInstance === 'undefined') {
InAppBrowserModuleInstance = InAppBrowserModule.new();
}
native.InAppBrowser = <InAppBrowserModule>InAppBrowserModuleInstance
Thanks for your help! <3
Hi @jdnichollsc thanks for mentioning this. We will add a page to the docs about this specifically. Basically what it comes down to is where/when you need to import { native } from '@nativescript/capacitor';.
The answer is never from within the src/nativescript folder. Inside there, native is globally and inherently accessible all the time.
You only ever need to import { native } from '@nativescript/capacitor'; from within your web components to access the native api helper methods you add (augmented by native-custom.d.ts).
Further when creating your InAppBrowser class you did everything above well. Only need to modify like this:
// you don't need to declare this if you have typings for them already
// you can include the typings in the src/nativescript/references.d.ts
// but you can also do this:
declare var SFSafariViewControllerDelegate, UIAdaptivePresentationControllerDelegate, ASWebAuthenticationPresentationContextProviding;
// also make sure Capacitor Podfile for example includes the pod for inappbrowser if a Cocoapod is used for it.
@NativeClass()
class InAppBrowserModule extends NSObject {
public static ObjCProtocols = [
SFSafariViewControllerDelegate,
UIAdaptivePresentationControllerDelegate,
ASWebAuthenticationPresentationContextProviding
];
The src/nativescript folder is a full blown {N} environment meaning you can type/use {N} as you may already be used to.
The other recommendation is to create helper methods to create and do the things you need to call on from your web components, for example using example above, something like this would be nice:
native.openInAppBrowser = (authUrl: string, options?: any) => {
if (typeof InAppBrowserModuleInstance === 'undefined') {
InAppBrowserModuleInstance = InAppBrowserModule.new();
}
InAppBrowserModuleInstance.open(authUrl, options);
}