UDP Address already in use Xamarin - ios

I'm trying to create a UDP server using SocketLite.PLC in Xamarin.
When running the iOS app I get the error Address already in use regardless of what port I try to listen to.
My code looks like this:
var udpReceived = new UdpSocketReceiver();
await udpReceived.StartListeningAsync(6932, allowMultipleBindToSamePort: false);
Why is this happening, and how can I fix it?

I would try something like this:
using (UdpSocketReceiver udpReceived = new UdpSocketReceiver())
{
//operations
await udpReceived.StartListeningAsync(6932, allowMultipleBindToSamePort: false);
udpReceived.Close();
}
I'm kind of betting on this being a similar issue to a thread I found regarding xamarin and the TcpListener (which can be found here).

Related

CrossGeolocator iOS Issue: Either just use events or your own delegate

I've been trying to fix this issue for two days now.
This is a Xamarin.Forms application. The Android side is working perfectly. On the iOS, however, I keept geeting this error.
I have a single button in the center of my screen. When it's clicked, it uses the CrossLocator class to get the Geolocation of the phone. However, this problem keeps ocurring:
Erro: Evento registration is overwriting existing delegate, Either just use events or your own delegate:Plugin.Geolocator.GeolocationSingle-UpdateDelegateCoreLocation.CLLocationManager+_CLLocationManagerDelegate
Here's my code:
`public static async Task<Tuple<Position, string>> GetLocalizacao()
{
var locator = CrossGeolocator.Current;
try
{
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(TimeSpan.FromMilliseconds(10000));
}
catch (Exception ex)
{
return new Tuple<Position, string>(null, $"Erro: {ex.Message}");
}
var localizacaoFinal = await locator.GetPositionAsync(TimeSpan.FromMilliseconds(10000));
return new Tuple<Position, string>(localizacaoFinal, "");
}`
The exception happens when it hits "GetPositionAsync". From there on, I don't know what to do, nor how to actually identify the issue itself.
If anyone stumbles upon this post, I've been stuck with this issue since I posted it. Still can't get it to work in these conditions. The only way my app worked was downgrading all packages I needed for this.
In order for it to work, it now has:
Xam.Plugin.Geolocator, version 4.5.0.6
Xamarin.Forms, version 5.0.0.2012
Xamarin Essentials, version 1.6.1
Plugin.Permissions, version 6.0.1

Question from Flutter novice developer about 'await'

I'm an iOS developer starting to look into Flutter. I'm following this tutorial from Ray Wenderlich and I'm facing a strange behaviour from this code.
_loadData() async {
var dataURL = "https://api.github.com/orgs/raywenderlich/members";
var response = await http.get(dataURL);
setState(() {
_members = json.decode(response.body);
});
}
Problem is that execution is stopped at var response = await http.get(dataURL);
I know is related to the await but I'm not sure why is happening. On the example code from the http package is using a similar code.
Can anyone help?
Thanks
So, the reason of the unresponsive await was due to the Android simulator. I don't know why but connection is not working on the simulator. I tested with the iOS simulator and worked.
if it is stopped it might be because the url does not return anything, maybe because the url is wrong? also i think string should use single quotations ' instead of ". try replacing it with single quotations?

Automate launching Safari from a iOS mobile app using appium

I am doing some automation with Appium on a iOS mobile app.
I need to:
open the app
do some tasks
open safari
I looked around how to do it but I've been reading that it's impossible due to a limitation in apple's framework, it doesn't allow you to sent commands to more than one app per session.
Does anyone know a way around this? Or if what I read is just not 100% true.
it doesn't allow you to sent commands to more than one app per session
Thats true, but you can run 2 sessions in a single test:
create instance of appium driver with app-based capabilities
do what you need in the app
quit driver
create instance of appium driver with browser-based capabilities
do what you need in the safari
quit driver
In a quick way it may look like:
#Test
public void testBothAppAndSafari() throws MalformedURLException {
URL appiumServerUrl = new URL("<your appium server host>");
DesiredCapabilities appCaps = new DesiredCapabilities();
// put required native app capabilities in appCaps
DesiredCapabilities safariCaps = new DesiredCapabilities();
// put required safari capabilities in safariCaps
IOSDriver driver = new IOSDriver(appiumServerUrl, appCaps);
driver.findElement(<locator for element in native app>).click();
// do whatever you want with mobile app
driver.quit();
driver = new IOSDriver(appiumServerUrl, safariCaps);
driver.findElement(<locator for element in web>).click();
// do whatever you want in safari
driver.quit();
}
You can use following approach,
Created two setup one for app and other for safari.
First launch application and perform task
clear first session
Created again new Appium object for safari ( call second setup )
Perform browser activity
Close safari appium session
You also can follow my approach without quit driver.
Go terminate application. (I've used javascript to run terminateApp cause native method not work for me.)
Find Safari on Home screen and then click on it
Use drive.get to open website as you expected.
In there you can change to WEBVIEW_*** to inspect web element.
Back to native context by NATIVE_APP keyword
Sample code:
System.out.println("Run application");
Map<String, Object> params = new HashMap<>();
params.put("bundleId", "com.example");
boolean terminalApp = (boolean) driver.executeScript("mobile: terminateApp", params);
System.out.println("terminateApp: " + terminateApp);
driver.findElementById("Safari").click();
Set<String> contextNames = appDriver.getContextHandles();
// Change context to WEBVIEW_***
appDriver.context(String.valueOf(contextNames.toArray()[1]));
driver.get("https://www.google.com.vn");
Thread.sleep(20000);
// Do something.
// ...
// If you want to communicate with NATIVE context just change to NATIVE_APP.
appDriver.context("NATIVE_APP");
you can activate system apps via driver.activateApp(BUNDLE_ID);
there is no need to kill the app driver and start browser driver to access browser, just switch between apps.
safari
driver.activateApp("com.apple.mobilesafari");
Here is how I resolved the issue:
driver2.activateApp("com.apple.mobilesafari");
Thread.sleep(5000);
boolean openSafariTab =
driver2.findElements(By.xpath("//XCUIElementTypeButton[#name=\"AddTabButton\"]")).size() > 0;
if (openSafariTab) {
driver2.findElement(By.xpath("//XCUIElementTypeButton[#name=\"AddTabButton\"]")).click();
} else { }
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeTextField[#name=\"TabBarItemTitle\"]")).click();
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeOther[#name=\"CapsuleViewController" +
"\"]/XCUIElementTypeOther[3]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]")).sendKeys("https://www.golfbpm.com");
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeButton[#name=\"Go\"]")).click();

Azure Storage api doesn't work for asnyc uploads

I am trying to upload so many files via Azure Blob Storage .NET api and using with the current latest version 4.0.1. In ASP.NET MVC application i use async action method to upload via await blobFile.UploadFromStreamAsync but it really doesn't work and even i don't see an exception. It silently stops in that method without success.
But if i change action method to none-async and upload via blobFile.UploadFromStream method then everything to works well. I may uploaded via async way with 1% success rate that means very very low stability.
Do you experience same thing ? Is it bug in Storage Api implementation ?
Here is short example. One is async and the other one is none async action methods. There is no any problem if i upload small files but problem appears on large downloads. In this example UploadBlobSec method upload in short time but UploadBlob takes endless time.
public async Task UploadBlob()
{
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString);
var blobContainer = storageAccount.CreateCloudBlobClient().GetContainerReference("files");
var blobFile = blobContainer.GetBlockBlobReference("song.mp3");
using (var stream = new WebClient().OpenRead("http://apolyonstorage.blob.core.windows.net/files/e8b1a1fa-8791-44dc-92ce-1a67a62f7b0f.mp3"))
{
await blobFile.UploadFromStreamAsync(stream);
}
}
public void UploadBlobSec()
{
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString);
var blobContainer = storageAccount.CreateCloudBlobClient().GetContainerReference("files");
var blobFile = blobContainer.GetBlockBlobReference("song.mp3");
using (var stream = new WebClient().OpenRead("http://apolyonstorage.blob.core.windows.net/files/e8b1a1fa-8791-44dc-92ce-1a67a62f7b0f.mp3"))
{
blobFile.UploadFromStream(stream);
}
}
Code snippet looks fine - although I am not sure what the application around it is doing. Have you turned on server logs to see what is happening server side? For large files you should see the async upload translated into a couple of PutBlocks and then a PutBlockList. If you don't see the PutBlockList them maybe something strange is happening in your application.
Then assuming you do see the operations in the server logs that obviously means the operations are occurring. At that point look at the E2ELatency numbers vs ServerLatency I think you will see a large difference with E2Latency being much higher as it incorporates the time spent client side - and it would be interesting to see if your client network could be contributing to the problem. For example on my connection the e2elatency on the first PutBlock was 1346 ms vs 137 for ServerLatency.
For more information on logging take a look here.
Jason

How to locate element in UIautomator if native keyboard come before your application?

As per project requirement i am working on Mobile App automation. Not problem arises when i executed same code which worked fine on emulator but when it comes to real device the same code were getting failed.the problem is UiAutomator is not able to locate element because of native keyboard come before an application during simulation. I executed this entire thing into Galaxy nexus which works on ANDROID API 18.hence no point to execute whole automation suites in Selendroid mode. in below code after filling value in first editbox,control should have reached to second editbox to fill value and so on. But it does not fill value there because native keyboard appear before application.
SwipeableWebDriver driver = new SwipeableWebDriver(
new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
List<WebElement> editTextList = driver.findElements(By
.className("android.widget.EditText"));
editTextList.get(0).sendKeys(c + "Bob");
editTextList.get(1).sendKeys("123");
editTextList.get(2).sendKeys("456");
el = driver.findElement(By.className("android.widget.Button"));
el.click();
Please anyone who have idea to resolve this issue?
Thanks in advance.
Priyank Shah
First of all you should realize whether the soft keyboard is active or not - Use the following command from your code to check "mInputShown" parameter - If "true" - Active Soft Keyboard.
adb shell dumpsys input_method | grep mInputShown
Use this code for hiding the native keyboard in Java-appium running older versions of appium.
driver.navigate().back()
P.S - The adb command is useless for emulators as the flag whose value is being checked is always set to true, whether your keyboard is active or not.
I don't think you can, and and it is not a appium limitation.
From what I observed even the UIAutomator can not find the elements hidden by the keyboard.
I know 2 solutions for this:
Dismiss the keyboard. (I didn't find any elegant ways of doing that so I'm not using this.
Swipe/scroll on the view until the element is exposed, and then you can action it. This works fine for me.
you should be able to dismiss the keyboard by sending
driver.findElement(By.name("Return")).click();
adding new line character works too
editTextList.get(2).sendKeys("456\n");
If you can detect that the keyboard is open, I would suggest calling UiDevice.pressBack() to dismiss the keyboard.
You could be able to dismiss the keyboard by using the following code
driver.hideKeyboard();
Put the following two lines:
driver.getKeyboard();
driver.hideKeyboard();
Here is a uiautomator ready fully functional method that will respond with true if the keyboard is Open and false if it is closed:
public static boolean isKeyboardDisplayed() {
String checkKeyboardCommand = "dumpsys input_method | grep mInputShown";
try {
Process process = Runtime.getRuntime().exec(checkKeyboardCommand);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
process.waitFor();
if (output.toString().contains("mInputShown=true")) {
return true;
} else {
return false;
}
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
You may need to enable unicodeKeyboard: true in your android capabilities and use the keyboard button Return to hide the keyboard if shown (this work for me on iOS and Android)
For example, I am using ruby:
element = $appium.find_element(id: field_id)
element.clear
element.send_keys(data)
element.send_keys(:return) if driver.is_keyboard_shown

Resources