catch System.Reflection.TargetInvocationException - xamarin.android

I've created an android application using Xamarin.android that consumes an asmx webservice.the latter connects my app to sql server. the app works perfectly with good internet connection. but when I have bad internet service, I get an exception in visual studio (while deploying my app to a physical device). the exception is: System.Reflection.TargetInvocationException. and when my phone is not connected to my laptop and I run the app with poor connection, my phone gets out from the app. I am trying to catch this exception so that the app doesn't crash and at least give me an alert dialog that my connection failed so I did this:
WSitems.WebService1 ws = new WSitems.WebService1();
try
{
ws.itemsinfoAsync();
ws.itemsinfoCompleted += Ws_itemsinfoCompleted;
}
catch(Exception exp )
{
Context context = this.Context;
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.SetTitle("Connection to Server failed");
alert.SetMessage("Please, check your internet connection!");
alert.SetPositiveButton("okay",( senderAlert, args) => {
alert.Dispose();
});
_dialog = alert.Create();
_dialog.Show();
}
but the problem wasn't solved. what should I do?
thanks in advance.

Related

Workaround for missing "Web Push" on Safari for my PWA

I am developing a PWA that requires Push-Notifications. Sadly IOS/Safari does not support https://w3c.github.io/push-api/#pushmanager-interface for now, so I think i might have to wrap a native APP around in some way.
In Android (before their "Trusted Web Activities" was a thing) you could use a WebView to basically display a headless Chrome-View in your App. Whats the equivalent in IOS and how does the interaction between push-notifications and the Webapp (the browser need to jump to a specific page) work?
One more thing I need is integration with our companys Mobile Device Management, which is Microsoft Intune. Having integrated MDMs in Android in the past i Know that this might be a major pain in the a**, so i'm considering to build the wrapper myself, for maximum flexibility. Another option would be something like Ionic, not sure now.
This may not necessarily work in your situation, but I had the exact same issue with a PWA for Safari and I solved it by just using long polling. It will allow you to get around all of the limitations with Safari and I was able to redirect and load sections within our SPA.
async function subscribe() {
let response = await fetch("/subscribe");
if (response.status == 502) {
// Status 502 is a connection timeout error,
// may happen when the connection was pending for too long,
// and the remote server or a proxy closed it
// let's reconnect
await subscribe();
} else if (response.status != 200) {
// An error - let's show it
showMessage(response.statusText);
// Reconnect in one second
await new Promise(resolve => setTimeout(resolve, 1000));
await subscribe();
} else {
// Get and show the message
let message = await response.text();
showMessage(message);
// Call subscribe() again to get the next message
await subscribe();
}
}
subscribe();
https://javascript.info/long-polling

NEHotspotConfigurationErrorDomain Error on some devices

I've implemented a WiFi auto-join feature in my app -> Click a button and connect to a named SSID. This works on some devices but also fails on others - meaning it won't even show the Apple pop up asking to join the network. The device might be the same device model, same iOS but fails on some and not on others. This is the error that I see being returned when it fails:
Error Domain=NEHotspotConfigurationErrorDomain Code=10 "cannot modify system configuration." UserInfo={NSLocalizedDescription=cannot modify system configuration.
This is the code used to attempt auto-join:
let WiFiConfig = NEHotspotConfiguration(ssid: "MYSSID")
WiFiConfig.joinOnce = true
NEHotspotConfigurationManager.shared.apply(WiFiConfig) { error in
if error == nil {
//success
} else {
//fail
}
}
Any ideas?
Thanks!
Jennie
I figured out this is unique to our devices using an Embedded Event Manager with a SSID prefilled on the register. That SSID cannot be joined to via the Auto-join feature.

How to reconnect signalR properly after disconnected

In my angular6 website with ASP.NET server application ,
I want the singnalR client should always stay connected with Hub(Server). For that purpose started the connection on disconnected event with below code snap.
this.connection.start().done((data: any) => {
console.log('Now connected');
this.connectionId = this.connection.id;
this.connectionEstablished.emit(true);
this.connectionExists = true;
}).fail((error: any) => {
this.connectionEstablished.emit(false);
});
this.connection.reconnecting(() => {
this.tryingToReconnect = true;
});
this.connection.reconnected(() => {
this.tryingToReconnect = false;
});
this.connection.error((error: any) => {
this.initialize();
});
this.connection.disconnected(() => {
if (this.tryingToReconnect) {
setTimeout(() => {
this.initialize();
}, 5000);
}
});;
Because of that above code, signalr creates the problem such as
crashes the client browser and memory leaks in below cases such as,
If there is problem in client internet connection for some hours , that time singalr continuously tries to create the connection with hub. Because of internet problem , logging the connection error in browser console infinitely until the successful connection with hub
If i close the server, that time also singalR logging the connection error in browser console infinitely until the successful connection with hub
How to rectify the problems for signalr always stay connected with Hub?
I would create an incremental value and each reconnect time out would be increased and showing a retry now option, same way Gmail does, is a good practice and would solve both problems.

Connection problems from a netty client in Android

I am using a Netty server in linux with one netty client in Android. (Netty 4.0.23).
It works perfect most of the time. However, sometimes, my client is not able to connect to server.
The ChannelFuture received when trying to connect tells me that connection is done but not success (with cause not null) so it is completed with failure.
About the failure I received it is a java.net.socketException - EHOSTUNREACH error (No route to host).
I am quite sure that the problem is not in server.
Important:
I always run the server and the client in the same lan wifi network
with local ip addresses.
I have tested it in two different wifi
networks. In one of them, the reported error occurs rarely and in the
other occurs quite often.
CONNECT_TIMEOUT_MILLIS is configured with enough time in both contexts
I attach the way I do the connection from client:
.............
final ChannelFuture futureConnection = bootstrap.connect(HOST, PORT);
futureConnection.awaitUninterruptibly();
if (futureConnection.isDone()){
if (futureConnection.isCancelled()) {
// log error
}
else if (futureConnection.isDone() && futureConnection.isSuccess()){
// do something
}
else if (futureConnection.isDone() && (futureConnection.cause() != null)) {
// log error THIS IS THE ERROR REPORTED
}
else {
// log error
}
}
............

Get iOS client to respond to SignalR request when app is backgrounded

I'm quite new to xamarin iOS programming, so this might be a dumb question..
Background:
I'm making an application that should send alarms to users within a certaint range of an incident location. Sice the incidens can happen "anywhere", geofencing is not an option. I have tried using remote notifications, but I need to alert just the clients that is within range of incident, and not disturb the rest of the clients (that are too far from the incident). That means that i first have to get the current location of all users, and the notify just the ones that are within range. So i thought maybe SignalR might be a solution.
How can i get the ios application (iOS 7 and 8) to respond to a request from a SignalR hub when the application is backgrounded (as in user pressed home button on phone so that the application is no longer in the foreground). I need to be able to ask the client to send its current location back to the server when the server requests it. I might add that the client sends significant location changes back to the server, so the application is enabled for background tasks.
I have set up the hub to send a GetLocation request:
public void SendLocationRequest()
{
Clients.Others.locationRequestReceived();
}
On the client in the ViewDidLoad method:
_client.OnLocationRequestReceived +=
(sender, message) => InvokeOnMainThread(() => LocRequestReceived());
and the LocReuestReceived (i have just set it up to display a local notification for now):
void LocRequestReceived()
{
var notification = new UILocalNotification
{
FireDate = DateTime.Now.AddSeconds(1),
AlertAction = "Get Location",
AlertBody = "Should retrieve currentLocation",
ApplicationIconBadgeNumber = 1,
SoundName = UILocalNotification.DefaultSoundName
};
UIApplication.SharedApplication.ScheduleLocalNotification(notification);
}
this woks fine as long as the app is on the foreground on the phone, but nothing happens when the app is bacgrounded. (it works on the simulator when backgrounded, but that migh be a bug in the simulator see http://krumelur.me/2014/09/23/my-ios8-adventure-as-a-xamarin-developer/ )
I quess my problem is that im calling InvokeOnMainThread(() => LocRequestReceived()), where I should perhaps call it on a background thread??
As i've said, i just started xamarin iOS development, so any input is greatly appreciated.
I ended up with a slightly different approach. I used native CFStreams to set up a persistent tcp connection instead of SignalR.
public CFReadStream readStream;
public CFWriteStream writeStream;
public void Connect()
{
if (readStream == null) {
CFStream.CreatePairWithSocketToHost ("SERVER_ADDRESS", "PORT", out readStream, out writeStream);
ConfigureStream (readStream);
//Added handler for streamevents
.....
readStream.Open ();
}
}
To enable the stream to be open even if app is backgrounded, this is essential (in addition to add the necessary background modes in Info.plist):
void ConfigureStream(CFStream stream)
{
var nsstream = new NSStream (stream.Handle);
if (stream.GetType () == typeof(CFReadStream)) {
**nsstream [NSStream.NetworkServiceType] = NSStream.NetworkServiceTypeVoIP;**
}
}

Resources