xamarin IOS ReadToEnd() on stream from HttpWebResponse not working - xamarin

I have this code which is working fine in Android after I get a response from web service but fails in IOS. It was also working fine in ISO before I updated Visual studio. It fails during reader.ReadToEnd()
try
{
HttpWebResponse response=GetWebResponseAsync();
}
catch (exception ex)
{
var stream = ex.Response.GetResponseStream();
using (var reader = new StreamReader(stream))
{
retVal.ResponseText = reader.ReadToEnd();//It fails during
ReadToEnd()
}
}

Related

Create server TCP in Winodws Univeral App (Javascript) and client Android

I want create a tcp server in c# and use it in universal app javascript based project, and I create the folowing code (Server):
//C# Windows Runtime Component
public sealed class Server
{
public Server()
{
Debug.WriteLine("Server...");
}
public async void Connection()
{
IPAddress ip = IPAddress.Parse("192.168.0.10");
TcpListener server = new TcpListener(ip, portNumber);
TcpClient client = default(TcpClient);
try
{
server.Start();
Debug.WriteLine("Server started ... " + ip.ToString());
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
while (true)
{
client = await server.AcceptTcpClientAsync();
byte[] recievedBuffer = new byte[100];
NetworkStream stream = client.GetStream();
stream.Read(recievedBuffer, 0, recievedBuffer.Length);
string msg = Encoding.UTF8.GetString(recievedBuffer, 0, recievedBuffer.Length);
Debug.WriteLine(msg);
}
}
}
//in HTML
<script>
console.log("test");
var server = new Server.Server();
server.connection();
console.log("msg");
</script>
I don't know why Debug.WriteLine and console.log method don't work, nothing are printed in output or in javascript console.
The Server code works with Android client, if the server is "Console App" project but in "Universal App Javscript" nothing append, I don't have warning or error.
So I don't know if I'm doing bad, because console.log and Debug.WriteLine don't work.
I have a solution that work with windows universal app, I remove Connection and add followings methods:
public async void StartServer()
{
try
{
var streamSocketListener = new Windows.Networking.Sockets.StreamSocketListener();
streamSocketListener.ConnectionReceived += this.StreamSocketListener_ConnectionReceived;
await streamSocketListener.BindEndpointAsync(new HostName("192.168.0.10"), PortNumber);
}
catch (Exception ex){}
}
private async void StreamSocketListener_ConnectionReceived(Windows.Networking.Sockets.StreamSocketListener sender, Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs args)
{
string request;
using (var streamReader = new StreamReader(args.Socket.InputStream.AsStreamForRead()))
{
request = await streamReader.ReadLineAsync();
}
sender.Dispose();
}
//in main.js just call this method
new Server.Server().startServer();
But I still don't know why Debug.WriteLine() in c# and console.log() in javascript don't work.

Silverlight app freezes on Mac when file saved

Pretty simple code to launch SaveFileDialog and then save data.
Opens prompt, I can select where I save, it saves file and then whole tab/app freezes. Obviously works fine on Windows/IE. Any suggestions?
private void SavePDFFile()
{
var saveFileDialog = new SaveFileDialog
{
DefaultExt = "pdf",
Filter = string.Format("Document(.{0})|*.{0}", "pdf"),
FilterIndex = 1,
DefaultFileName = DateTime.Now.ToString("HHmmMMddyyyy")
};
var saveClicked = saveFileDialog.ShowDialog();
if (!saveClicked.HasValue || !saveClicked.Value) return;
var fileStream = saveFileDialog.OpenFile();
try
{
this.IsBusy = true;
fileStream.Write(this.PDFData, 0, this.PDFData.Length);
fileStream.Close();
}
catch (Exception ex)
{
this.DisplayErrorMessage("Error saving PDF file", ex);
}
finally
{
this.IsBusy = false;
}
}
Answering my own question. This is nothing to do with code itself. It is security issue. In order to allow this code to execute on Mac (and it seems new versions of IE as well) you need to give it more permissions.
On IE you need to add website to list of Trusted sites.
On Mac - you need to set Silverlight to run in "Unsafe" mode. This is in Preferences/Security/Silverlight and need to select website, hold "Option" key and then open dropdown to see that option. Took a while to find it..
#katit I also faced this issue while working on a Silverlight OOB application.. my app was working fine in Windows but in Mac it got freezed and I have to force quit to use it again.
I was actually reading a PDF (stored in field type - 'varbinary') from server and storing it to user's local machine.
The solution worked for me is to download file chunks in parts (I used buffer size - 1 MB).
Not sure what file size you are using when your application gets freeze.. but I think, writing 'PDFData' to filestream in small parts may help you.
Also, add filestream.Flush(); (see highlighted in below code) in your code and see if this helps:
private void SavePDFFile()
{
var saveFileDialog = new SaveFileDialog
{
DefaultExt = "pdf",
Filter = string.Format("Document(.{0})|*.{0}", "pdf"),
FilterIndex = 1,
DefaultFileName = DateTime.Now.ToString("HHmmMMddyyyy")
};
var saveClicked = saveFileDialog.ShowDialog();
if (!saveClicked.HasValue || !saveClicked.Value) return;
var fileStream = saveFileDialog.OpenFile();
try
{
this.IsBusy = true;
fileStream.Write(this.PDFData, 0, this.PDFData.Length);
**filestream.Flush();**
fileStream.Close();
}
catch (Exception ex)
{
this.DisplayErrorMessage("Error saving PDF file", ex);
}
finally
{
this.IsBusy = false;
}
}

Xamarin form Geolocation task cancelled exception

I am working on Xamarin form app with andorid, UWP and Windows 8 project. I am using Geolocation plugin created by Jamesmontemagno to get the current device location. It is working fine in windows 8 and UWP but whenever I am trying to run it against the android device I keep getting task cancelled exception. I have checked all the permissions that are required as per suggestion but still no luck. My code to access location is below
protected override void OnAppearing()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 100; //100 is new default
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
try
{
var position = locator.GetPositionAsync(timeoutMilliseconds: 60000).Result;
//var pp = helper.Setting.Location;
var Latitude = position.Latitude;
var Longitude = position.Longitude;
}
catch(Exception ex)
{
var exc = ex;
}
}
}
Below is an image for my settings for android manifest
For anyone else who gets a timeout even with the await, only on Android, and even though the device's Google Maps app works fine, you are probably running into this bug which only happens on certain Android devices, but quite a few of them at that.
The issue is an old one that Google has never fixed. The solution, and one possible reason the Google Maps app works fine, is to use Google Play Services' fused location provider.
Currently the Geolocator Plugin just uses the regular Android Location Provider, but James has mentioned that he would like to use the Fused provider at some point. I have yet to try the fused provider myself though.
Try using the await keyword like it is used in the original code:
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync (timeoutMilliseconds: 10000);
Console.WriteLine ("Position Status: {0}", position.Timestamp);
Console.WriteLine ("Position Latitude: {0}", position.Latitude);
Console.WriteLine ("Position Longitude: {0}", position.Longitude);
}
catch(Exception ex)
{
Debug.WriteLine("Unable to get location, may need to increase timeout: " + ex);
}
This should take care that there are no race condition and therefore TaskCancellationException.
Thanks to #Radinator below is the working solution.
protected async override void OnAppearing()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 100; //100 is new default
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
try
{
await SetLocation();
}
catch (Exception ex)
{
var exc = ex;
}
}
}
private async Task SetLocation()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 100; //100 is new default
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
try
{
var position = await locator.GetPositionAsync(timeoutMilliseconds: 60000);
var Latitude = position.Latitude;
var Longitude = position.Longitude;
}
catch (Exception ex)
{
//log ex;
throw ex;
}
}
}
Faced 'Task killed' issue with v3.0.4. The following worked for me:
Uninstall the app
Update Geolocator to prerelease 4.0

MediaLibrary.SavePicture method results in a System.UnauthorizedAccessException

I've got the following code which handles downloading and saving an Image to the phone's media library. It fails with a System.UnauthorizedAccessException as if there was some cross-thread access. To my understading all code below an await statement runs on the UI thread so this should not be an issue. In addition I've tried wrapping the code below var stream = await client.OpenReadTaskAsync(this.Url); with Deployment.Current.Dispatcher.BeginInvoke but it did not help. :(
I am running this on WP8 with the intention to port the code later to WP7.
private async void OnSaveImageCommand()
{
RunProgressIndicator(true, "Downloading image...");
var client = new WebClient();
try
{
var stream = await client.OpenReadTaskAsync(this.Url);
var bitmap = new BitmapImage();
bitmap.SetSource(stream);
using (var memoryStream = new MemoryStream())
{
var writeableBitmap = new WriteableBitmap(bitmap);
writeableBitmap.SaveJpeg(memoryStream, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, 0,
100);
memoryStream.SetLength(memoryStream.Position);
memoryStream.Seek(0, SeekOrigin.Begin);
var mediaLibrary = new MediaLibrary();
mediaLibrary.SavePicture("image.jpg", memoryStream);
MessageBox.Show("Image has been saved to the phone's photo album");
}
}
catch
{
MessageBox.Show("Failed to download image");
}
finally
{
RunProgressIndicator(false);
}
}
Did you add an ID_CAP_MEDIALIB_PHOTO capability to your app's manifest?
UnauthorizedAccessException is 99% of the time a missing capability.

Problems accessing SkyDrive from Windows Phone 7

We are using the Live Connect SDK 5.0 to retrieve pictures from SkyDrive from our Windows Phone 7.5 application.
The application code (simplified) below used to work until a few days ago. Now when we try to access the imageStream (or any other information captured in a callback) we get a System.Argument exception (HResult = -2147024809, "Value does not fall within the expected range", but as usual the offending value is not mentioned). We checked our code base and there were no code changes in this area of the product recently.
Were there any API changes? Is there a way (Fiddler, but for applications not IE) to inspect the network traffic in the hope that more information is transmitted from the server? Are there any local values that are being cached that might interfere?
Here's the relevant code:
public partial class OptionsPage : PhoneApplicationPage
{
private LiveConnectClient _liveClient = null;
public OptionsPage()
{
InitializeComponent();
}
private void OnSessionChanged(Object sender, LiveConnectSessionChangedEventArgs args)
{
if (args != null && args.Session != null && args.Session.Status == LiveConnectSessionStatus.Connected)
{
this._liveClient = new LiveConnectClient(args.Session);
this.GetUserPicture();
}
}
private void GetUserPicture()
{
var memoryStream = new MemoryStream();
_liveClient.DownloadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(this.GetUserPictureCallback);
_liveClient.DownloadAsync("/me/picture?return_ssl_resources=true", memoryStream, memoryStream);
}
private void GetUserPictureCallback(object sender, LiveOperationCompletedEventArgs e)
{
_liveClient.DownloadCompleted -= this.GetUserPictureCallback;
try
{
if (e.Error == null)
{
MemoryStream imageStream = e.UserState as MemoryStream;
BitmapImage b = new BitmapImage();
b.SetSource(imageStream);
}
else
{
MessageBox.Show(e.Error.Message, "Windows Live Error", MessageBoxButton.OK);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SkyDrive Exception", MessageBoxButton.OK);
}
}
}
And the SignInButton is defined as follows:
<live:SignInButton Content="Button" Height="65" HorizontalAlignment="Left" Margin="110,41,0,0"
Name="signInButton1" VerticalAlignment="Top" Width="215" ClientId="[REAL_CLIENT_ID]"
Scopes="wl.offline_access wl.signin wl.basic wl.skydrive wl.skydrive_update"
RedirectUri="https://oauth.live.com/desktop"
Branding="Skydrive"
TextType="SignIn"
Background="Red"
SessionChanged="OnSessionChanged" />
It appears that I was using the Beta version of the Live Connect SDK 5.0. Once I upgraded to the RTM version (and made the code changes required) it started working again.

Resources