I am developing an APP with wechat login feature. After getting approval from wechat it will call a custom activity of my NativeScript APP. I am getting response correctly but how can I move to another page instated of the home page after doing some verification. I am using NativeScript + Angular.
Sample code
getJSON("https://api.weixin.qq.com/sns/oauth2/access_token?appid=ID&secret=SECRET&code=" + res.code + "&grant_type=authorization_code").then((res) => {
console.dir(res);
// ===> here I want navigation
}, err => {
console.dir(err);
})
I tried like this:
frame.topmost().navigate("src/app/login/login.component");
but getting error:
JS: Unhandled Promise rejection: Cannot set property '_moduleName' of undefined ; Zone: ; Task: Promise.then ; Value: TypeError: Cannot set property '_moduleName' of undefined TypeError: Cannot set property '_moduleName' of undefined
Please give me some suggestions. Thanks in advance :)
Fire an event from the Activity callback, something like
import { android } from "tns-core-modules/application";
...
public onResp(res: com.tencent.mm.opensdk.modelbase.BaseResp) {
console.log("onResp");
console.dir(res);
androidApp.notify(<AndroidActivityEventData>{ eventName: 'wxapiresponse', object: android, activity: this });
}
In app component, listen to the event
export class AppComponent implements OnInit {
constructor(private ngZone: NgZone, private routerExtensions: RouterExtensions) {}
ngOnInit() {
application.android.on('wxapiresponse', this.wxApiResponse, this);
}
wxApiResponse() {
// making sure the event callback runs inside Angular zone
this.ngZone.run(() => {
this.routerExtensions.navigate(...);
});
}
}
A similar problem cost me an entire Weekend, without knowing how the companion controller .js or .ts files look like I can only recommend you go to the basics / source:
https://docs.nativescript.org/core-concepts/navigation#frame
it helped me find the problem in my code.
If you wrote a custom Page that does not start from a template chances are you wrote the controller too and it's easy to overlook some line that is present in the samples - even thou it looks like you don't need it.
If you paste your controller JS we could understand your context.
For instance, here is piece of code you should definitely include to help you debug:
in your page-you-navigate-to.xml
<Page loaded="onPageLoaded" class="page">
...
</Page>
in your page-you-navigate-to.ts
import { EventData } from "tns-core-modules/data/observable";
import { Page } from "tns-core-modules/ui/page";
export function onPageLoaded(args: EventData): void {
const page = <Page>args.object;
var context = page.navigationContext;
page.bindingContext = context;
console.log("Target page Loaded.");
}
Start your debugger, and step through see where you have null values and read up on those method calls and their parameters.
Related
I am hooking an app now i m founding this error i have already tried many solutions one of which is following:
Java.perform(function() {
var main;
Java.choose('ca.c.edu.char.g', {
onMatch: function(instance) {
main = instance;
},
onComplete: function() {console.log(main.Key);}
});
});
Here Key is a method i found after decompiling it with jadx-gui but it is not working ..Any help??
in the function Java.choose char is package and its class is g
How to add an event listener to handle window message event in a WebView. I have tried this,
webView.evaluateJavascript("window.addEventListener('message', function (e) { Android.logData('HELLO')});", null);
But it is not working. Is there any way to achieve this?
After exploring I didn't find any way to get data from the website running in WebView to the app without adding any code to in the website. And finally, I decided to make the necessary changes on my website as well. And this is how I did it:
In App
Created a class
private class JsObject {
#JavascriptInterface
public void shareData(String data) {
Log.v(LOG_TAG, data);
}
}
Add an instance of the new class as Javascript Interface to the WebView with a name
ssWebView.addJavascriptInterface(new JsObject(), "Android");
This instance will be added to the window object of the WebView as Android(name, the second argument of the above function)
In Website
In the website to share data
window.Android && window.Android.shareData("This is the data from website");
I am rewriting my vanilla Xamarin app to use Prism Library.
The current app uses Azure ADB2C for authorisation using this framework.
Android needs to have its parent window set, which is achieved by adding this code into the MainActivity.cs of the Android project:
var authenticationService = DependencyService.Get<IAuthenticationService>();
authenticationService.SetParent(this);
This doesn't work for the Prism app, authenticationService is null. For the record, the DependencyService used here is Xamarin.Forms.DependencyService.
I also tried the example from the Prism docs and put this code into the AndroidInitializer:
public void RegisterTypes(IContainerRegistry container)
{
// Register any platform specific implementations
container.RegisterSingleton<IAuthenticationService, B2CAuthenticationService>("B2CAuthenticationService");
var authService = Container.Resolve<IAuthenticationService>();
authService.SetParent(this);
}
In this code, Container (which is a DryIoC Container) had no definition for Resolve.
For completeness, this is my App.cs RegisterTypes:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IAuthenticationService, B2CAuthenticationService>();
...
...
}
There are a few wrong assumptions you're making here. To start you'll notice that IContainerRegistry specifically has the name Registry in it to imply we don't want you resolving types here. This is why you don't see the Resolve method on it but rather the IContainerProvider instance.
By design, Prism no longer works directly with the Xamarin.Forms DependencyService as this is a complete anti-pattern. That said if you follow the guidance for registering Platform Specific types you can see how to use the IPlatformInitializer to register platform specific types. It is important to realize here that the IPlatformInitializer is called before RegisterTypes is called in PrismApplication.
What I would suggest is to introduce a IParentWindowProvider like:
public interface IParentWindowProvider
{
object Parent { get; }
}
You can then implement this on Android like:
public class MainActivity : IPlatformInitializer, IParentWindowProvider
{
object IParentWindowProvider.Parent => this;
void IPlatformInitializer.RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterInstance<IParentWindowProvider>(this);
}
}
Then in your Application you might do something like:
protected override void OnInitialized()
{
if(Container.IsRegistered<IParentWindowProvider>())
{
var provider = Container.Resolve<IParentWindowProvider>();
var authService = Container.Resolve<IAuthenticationService>();
authService.SetParent(provider.Parent);
}
}
For more info be sure to check out the relevant docs and sample
https://prismlibrary.com/docs/xamarin-forms/dependency-injection/platform-specific-services.html
https://github.com/PrismLibrary/Prism-Samples-Forms/tree/master/03-PlatformSpecificServices
I am trying to implement BetterVideoPlayer (implementation 'com.github.halilozercan:BetterVideoPlayer:1.2.alpha1') for NativeScript Android. So, in an Angular project I have created separate component like this:
import { View } from "tns-core-modules/ui/core/view";
declare var com, android;
export class BetterPlayer extends View {
public mediaPlayer;
public createNativeView(): any {
const nativeView = new android.widget.FrameLayout(this._context);
nativeView.addView(this._openVideo());
// or return this._openVideo(); // still not working..
return nativeView;
}
public _openVideo() {
let url = android.net.Uri.parse("http://jzvd.nathen.cn/c6e3dc12a1154626b3476d9bf3bd7266/6b56c5f0dc31428083757a45764763b0-5287d2089db37e62345123a1be272f8b.mp4");
this.mediaPlayer = new com.halilibo.bettervideoplayer.BetterVideoPlayer(this._context);
console.dir(this.mediaPlayer);
this.mediaPlayer.setSource(url);
this.mediaPlayer.setAutoPlay(true);
this.mediaPlayer.setHideControlsOnPlay(true);
return this.mediaPlayer;
}
}
Then from component I have registered it using registerElement
registerElement("BetterPlayer", () => BetterPlayer);
HTML:
<BetterPlayer height="200"></BetterPlayer>
But the problem is, it isn't showing the player. Only showing a black area. In where I did mistake? Please give me advice. Thanks in advance.
BetterVideoPlayer creates the actual media player within at onFinishInflate(), is a method called only when a View element is initiated via Android XML, programatic creation like you do in {N} won't trigger this method. So you could simply do this.mediaPlayer.onFinishInflate(); to force creating the media player and it should work, I was able to watch the video on device once I did.
I am effectively using geb-spock for our web application. I am new to geb spock appium and struggling with PageObject mechanism in Appium as I have comfortably achieved that for web application.
I am successfully able to launch the App and able to perform some actions on app with below code.
#Stepwise
class TC_001_DictionaryApp_Spec extends GebReportingSpec {
def "Step 1:Go to the login page of the WU"() {
when: "User is on Dictionary App"
// at AppHomePage
and: " User enters the value in Searh box"
/*page.textboxSearch.value("Obsess")*/
driver.findElement(By.id("com.dictionary.mr:id/input_text_view")).sendKeys("Obsess")
and: "Press the Enter"
then: "Word should be searched"
}
}
However if I try to use at or to block then its getting failed. (If you un-comment the code in the above test case it's not working) Below is my page object class
class AppHomePage extends Page {
static at = {}
static content ={
textboxSearch (wait:true) { driver.findElement(By.id("com.dictionary.mr:id/input_text_view")) }
}
}
Can you please guide me how I can achieve the page object mechanism with geb spock appium.
Thanks!
You haven't added an assertion in your "at" block so it will fail.
class AppHomePage extends Page {
static at = { title == "my title assertion"}
static content ={
textboxSearch (wait:true) { driver.findElement(By.id("com.dictionary.mr:id/input_text_view")) }
}
}