Xamarin Forms: ModernHttpClient errorhandling in PCL - exception

My app connects to an api which requires an HTTPS-connection.
ModernHttpClients (NativeMessageHandler) works fine until an exception is thrown...
When there is no wifi available, an UnknownHostException is thrown on Android. Is it possible to make a catch that works on both Android and iOS? UnknownHostException is in the Java.Net library which can't be used in the iOS project.

You can use Xam.Plugin.Connectivity NuGet Package to Check Network Connectivity In Xamarin.Forms using following code
if (CrossConnectivity.Current.IsConnected) {
// your logic...
} else {
// write your code if there is no Internet available
}
OR
Refer http://www.c-sharpcorner.com/blogs/how-to-check-network-connectivity-in-xamarinforms

You can use the ConnectivityPlugin in your shared Xamarin Forms code to check for an internet connection before doing your request.

Personally I'm using a cross platform interface to handle network errors. You can for instance have something like (using MvvmCross in this example):
try
{
var client = new HttpClient();
var result = await client.GetAsync("http://some-url.com");
}
catch (Exception e)
{
var platformErrorChecker = Mvx.Resolve<IPlatformNetworkError>();
if (platformErrorChecker.IsNetworkError(e))
{
// Handle network error
}
else
{
// Other exception, just throw
throw;
}
}
And a service defined as:
public interface IPlatformNetworkError
{
bool IsNetworkError(Exception e);
}
Which you implement on each platform specifically, or only where needed. This is a simple example of course, you can have each platform provide more information about their specific network errors.

Related

How To Create Test Facebook Ads || How to Get Android Advertisement ID (AAID) programmatically?

How to create Test Device to Facebook Ads >> To Create Test Device you need Enter a device ID (IDFA, AAID):
sometimes we need to get the android advertisement id AAID for android device, when we place google ads or Facebook ads to our Android app or any other functions we need to place the unique AAID for testing purpose.
For Kotlin code
Thread{
AdvertisingIdClient.getAdvertisingIdInfo(activity).id?.let {
Log.i("myId",it)
}
}.start()
The first Step, get AdvertisingIdClient
public class AdvertisingIdClient extends Object
Helper library for retrieval of advertising ID and related information such as the limit ad tracking setting.
It is intended that the advertising ID completely replace existing usage of other identifiers for ads purposes (such as use of ANDROID_ID in Settings.Secure) when Google Play Services is available. Cases, where Google Play Services is unavailable, are indicated by a GooglePlayServicesNotAvailableException being thrown by getAdvertisingIdInfo().
Code >>>
#SuppressLint("StaticFieldLeak")
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String token = null;
AdvertisingIdClient.Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (IOException | GooglePlayServicesRepairableException | GooglePlayServicesNotAv
// ...
MessageLog.setLogCat("DEVICE_ID",""+e);
}
String android_id = adInfo.getId();
MessageLog.setLogCat("DEVICE_ID",android_id);
return android_id;
}
#Override
protected void onPostExecute(String token) {
MessageLog.setLogCat("DEVICE_ID","DEVICE_ID Access token retrieved:" + token);
}
};
task.execute();
Open Your Logcate of android studio
you will get Result like it
2020-07-23 19:32:37.225 19041-19093/com.packagename.example I/DEVICE_ID :: 1aaf7707-22b5-4627-xxx-xxxxxxxx
2020-07-23 19:32:37.738 19041-19041/com.packagename.example I/DEVICE_ID :: DEVICE_ID Access token retrieved:1aaf7707-22b5-4627-xxx-xxxxxxxx
1aaf7707-22b5-4627-xxx-xxxxxxxx is your device ID
Second Step: Open your Facebook Monetization Manager
write your device id in a device ID (IDFA, AAID): EditText and Write Name Device like the image.
The following code snippet might help lot of you in current cases.
Add this method in your code:
fun getIdThread() {
var adInfo: AdvertisingIdClient.Info? = null
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(this)
} catch (e: IOException) {
// Unrecoverable error connecting to Google Play services (e.g.,
// the old version of the service doesn't support getting AdvertisingId).
} catch (e: GooglePlayServicesAvailabilityException) {
// Encountered a recoverable error connecting to Google Play services.
} catch (e: GooglePlayServicesNotAvailableException) {
// Google Play services is not available entirely.
}
val id: String = adInfo?.id.orEmpty()
val isLAT: Boolean = adInfo?.isLimitAdTrackingEnabled?.orFalse() == true
}
And call from separate thread as like below.
Thread{
getIdThread()
}.start()
This simple snippet will give you the AD ID. Even if the user resets the advertising ID.
Note: [Don't forget to declare ad ID permission in your manifest]

How to unit test AsyncTask in android

Consider below code. How can I test this without using third party libraries? The Assert line is never executed, because it is a different thread and the vm stops running. Many thanks!
public class FileParserTask extends AsyncTask<File, Void, ArrayList<City>> {
private FileParserResult mResult;
public interface FileParserResult {
void onFinish(ArrayList<City> cities);
}
public FileParserTask(final FileParserResult result) {
mResult = result;
}
#Override
protected ArrayList<City> doInBackground(File... files) {
ArrayList<City> cities = new ArrayList<>();
try {
InputStream is = new FileInputStream(files[0]);
JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));
reader.beginArray();
while (reader.hasNext()) {
City city = new Gson().fromJson(reader, City.class);
cities.add(city);
}
reader.endArray();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
Collections.sort(cities, (o1, o2) -> o1.getName().compareTo(o2.getName()));
mResult.onFinish(cities);
return cities;
}
}
Test code:
#RunWith(AndroidJUnit4.class)
public class CityServiceTest {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "cities-medium.json");
#Test
public void givenInputAbuThenIShouldGetXResults() throws InterruptedException {
new FileParserTask(cities -> {
Assert.assertEquals("Input should give back 200 results", 3, cities.size());
}).execute(file);
}
}
Although the code you need to test:
Assert.assertEquals("Input should give back 200 results", 3, cities.size());
is being run in an AsyncTask, that's not really relevant to unit testing. AsyncTask has most likely been extensively tested by Google so you know that it will work as an AsyncTask. The real testing seems to be the functionality that needs to be run in the background, i.e. the business logic contained in doInBackground.
Thinking about it in terms of business logic, there is a need to populate an ArrayList<City> and propagate it to the app. Android prefers this to be done on a background thread and propagation can be handled by notifications etc, both of which have been tested and released as working by Google so you don't really need to include them in a unit test. How you populate ArrayList<City> is the real unit test.
AsyncTask would be relevant for an integration test but you'd most likely be testing a different aspect of the app for that, i.e. what it displays rather than what it receives from a background thread.
So for a unit test I'd refactor out the code in doInBackground so that it can be tested independently of how Android wants it to be run.
Sorry, did you override the onPostExecute method of the AsyncTask.
You are keeping the Result handler, but not using it anywhere.
#Override
protected void onPostExecute(Object result) {
mResult.processFinish(result);
}
As for the assertion it looks good to me as it is.
As you say, the problem is the AsyncTask running in a background thread, via an ExecutorService. Like with a Future though, it provides a get() method that will wait for, and return, the result.
new FileParserTask(cities -> {
Assert.assertEquals("Input should give back 200 results", 3, cities.size());
}).execute(file).get();

How to Handle RPC Failure error before reach to OnFailure() at client side ? in GWT

In GWT when RPC fail due to any reason at that time onfailure() method execute at client side.
When onFailure() called at that time actual error is visible in browser's Networks response.
So, My Question is simple how can hide / Modify this actual error with some user friendly Error?
You can override onFailure() method to display what you need, but you cannot modify what a browser shows in the Network tab.
This is an example from my code (LoginException and VersionException are exceptions that my RPC calls throw when necessary):
#Override
public void onFailure(Throwable caught) {
if (caught instanceof LoginException) {
// Redirect a user to login page
Window.Location.assign("/");
} else if (caught instanceof IncompatibleRemoteServiceException ||
caught instanceof VersionException) {
/*
* Here I tell a user that a new version is available,
* so a user needs to refresh the page
*/
} else {
// Here I show a simple message about a connection error
}
}

Protocol between parse.com and mobile app

*What is the protocol between parse.com backend and mobile app when using Android/IOS SDK?
For example in the following code how parseobject is returned? Over http as json(Rest), via socket , rpc etc..?
ParseQuery<ParseObject> query = ParseQuery.getQuery("GameScore");
query.fromLocalDatastore();
query.getInBackground("xWMyZ4YEGZ", new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
if (e == null) {
// object will be your game score
} else {
// something went wrong
}
}
});
*If it is not rest what is the pros of method over REST?
It does use the Parse REST API, which sends JSON data over HTTPS.
The client SDKs provide a nice, native, helpful experience. For the platforms we don't support first-party, the REST API is available directly.

NServiceBus without input queue

Is it possible to use NServiceBus in an application without having any input queues?
Reason is, I have an ASP.NET MVC application that sends messages to other applications when something happens (e.g. a new user registers). The web application never recieves any responses or other messages and therefore I would like not to bog the app. with the msmq peeking which throws an exception every second.
That is supported, just remove the msmstranport config section and all should be fine. This works against 2.0.1281.0 (net4) version of NServiceBus with no app.config present
using NServiceBus;
namespace SendOnlyEndpoint.Custom
{
public class Program
{
static void Main(string[] args)
{
var bus = Configure.With()
.DefaultBuilder()
.XmlSerializer()
.MsmqTransport()
.UnicastBus()
.CreateBus()
.Start();
bus.Send("SendOnlyDestination",new TestMessage());
}
}
public class TestMessage : IMessage
{
}
}
More info on send only endpoints here
I would try not configuring an input queue. Bus.Send will use an internal outbound queue to send messages.