in my xamarin forms project, i have two models. the first model contains the information relating to a document (ID, Title, number, date, description), and the second model **contains the types of documents (Id, type of document).** When entering information on the form, the second model is used as a spinner which displays the document types. what i want is to be able to save the type of document selected in the sqlite database and be able to retrieve it in the info update interface****
how to use two models in mvvm constructor with ID to fetch data ?
Xamarin.Forms iOS Error: NavigationPage must have a root Page before being used.
I'm using MVVM in my project, and there is a class (named NavigationService) which is responsible for navigation within the app.
When I'm running the app for Android platform, everything works well.
But when I'm running the app in iOS platform, I'm getting this error.
Some background:
The first screen is NavigationPage for login and forgotpassword pages.
After successful login, NavigationService replaces the NavigationPage with a MasterDetail where the Detail is a new NavigationPage.
After I login the logic follows these steps:
- Create a MasterDetail page, bind to ViewModel and set it to be the CurrentApplication.MainPage
- In the MasterDetail Init, use NavigationService to navigate to the navigationPage (in this case the NavigationService will check and create the Navigation page and assign it to be the MasterDetail.Detail in case its not created yet.)
But the crash happens when I am assigning the MasterDetail page to be the MainPage. I cant understand why it thinks that I'm trying to put a NavigationPage....
This is the code for the NavigationService (The main navigation logic happens in InternalNavigateToAsync function):
using MoblieCP.Bootstrap;
using MoblieCP.Contracts.Services.General;
using MoblieCP.Pages;
using MoblieCP.ViewModels;
using MoblieCP.ViewModels.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace MoblieCP.Services.General
{
class NavigationService : INavigationService
{
private readonly Dictionary<Type, Type> _mappings;
protected Application CurrentApplication => Application.Current; public NavigationService() { _mappings = new Dictionary<Type, Type>(); CreatePageViewModelMappings(); } public async Task InitializeAsync() { bool loginTestNavigation = false; if (loginTestNavigation) { await NavigateToAsync<MainViewModel>(); } else { await NavigateToAsync<LoginViewModel>(); } } public Task NavigateToAsync<TViewModel>() where TViewModel : ViewModelBase { return InternalNavigateToAsync(typeof(TViewModel), null); } public Task NavigateToAsync<TViewModel>(object parameter) where TViewModel : ViewModelBase { return InternalNavigateToAsync(typeof(TViewModel), parameter); } public Task NavigateToAsync(Type viewModelType) { return InternalNavigateToAsync(viewModelType, null); } public async Task ClearBackStack() { await CurrentApplication.MainPage.Navigation.PopToRootAsync(); } public Task NavigateToAsync(Type viewModelType, object parameter) { return InternalNavigateToAsync(viewModelType, parameter); } public async Task NavigateBackAsync() { if (CurrentApplication.MainPage is MainPage mainPage) { await mainPage.Detail.Navigation.PopAsync(); } else if (CurrentApplication.MainPage != null) { await CurrentApplication.MainPage.Navigation.PopAsync(); } } public virtual Task RemoveLastFromBackStackAsync() { if (CurrentApplication.MainPage is MainPage mainPage) { mainPage.Detail.Navigation.RemovePage( mainPage.Detail.Navigation.NavigationStack[mainPage.Detail.Navigation.NavigationStack.Count - 2]); } return Task.FromResult(true); } public async Task PopToRootAsync() { if (CurrentApplication.MainPage is MainPage mainPage) { await mainPage.Detail.Navigation.PopToRootAsync(); } } protected virtual async Task InternalNavigateToAsync(Type viewModelType, object parameter) { Page page = CreateAndBindPage(viewModelType, parameter); if (page is MainPage) { try { CurrentApplication.MainPage = page; //<---- EXCEPTION HAPPENS HERE IN IOS!!! } catch(Exception ex) { var msg = ex.Message; } } else if (page is LoginPage) { CurrentApplication.MainPage = new MobileCpLoginNavigationPage(page); } else if (CurrentApplication.MainPage is MobileCpLoginNavigationPage loginNavigationPage) { if (page is ForgotPasswordPage) { var currentLoginPage = loginNavigationPage.CurrentPage; if (currentLoginPage.GetType() != page.GetType()) { await loginNavigationPage.PushAsync(page); } } } else if (CurrentApplication.MainPage is MainPage) { var mainPage = CurrentApplication.MainPage as MainPage; if (mainPage.Detail is MobileCpNavigationPage navigationPage) { var currentPage = navigationPage.CurrentPage; if (currentPage.GetType() != page.GetType()) { await navigationPage.PushAsync(page); } } else { navigationPage = new MobileCpNavigationPage(page); mainPage.Detail = navigationPage; } mainPage.IsPresented = false; } else { var navigationPage = CurrentApplication.MainPage as MobileCpNavigationPage; if (navigationPage != null) { await navigationPage.PushAsync(page); } else { CurrentApplication.MainPage = new MobileCpNavigationPage(page); } } await (page.BindingContext as ViewModelBase).InitializeAsync(parameter); } protected Type GetPageTypeForViewModel(Type viewModelType) { if (!_mappings.ContainsKey(viewModelType)) { throw new KeyNotFoundException($"No map for ${viewModelType} was found on navigation mappings"); } return _mappings[viewModelType]; } protected Page CreateAndBindPage(Type viewModelType, object parameter) { Type pageType = GetPageTypeForViewModel(viewModelType); if (pageType == null) { throw new Exception($"Mapping type for {viewModelType} is not a page"); } Page page = Activator.CreateInstance(pageType) as Page; ViewModelBase viewModel = AppContainer.Resolve(viewModelType) as ViewModelBase; page.BindingContext = viewModel; return page; } private void CreatePageViewModelMappings() { _mappings.Add(typeof(LoginViewModel), typeof(LoginPage)); _mappings.Add(typeof(MainViewModel), typeof(MainPage)); _mappings.Add(typeof(MenuViewModel), typeof(MenuPage)); _mappings.Add(typeof(HomeViewModel), typeof(HomePage)); _mappings.Add(typeof(ChangePasswordViewModel), typeof(ChangePasswordPage)); _mappings.Add(typeof(MeterDetailViewModel), typeof(MeterDetailPage)); _mappings.Add(typeof(ContactUsViewModel), typeof(ContactUsPage)); _mappings.Add(typeof(UpdateUserInfoViewModel), typeof(UpdateUserInfoPage)); _mappings.Add(typeof(TransactionHistoryViewModel), typeof(TransactionHistoryPage)); _mappings.Add(typeof(MeterTariffsViewModel), typeof(MeterTariffsPage)); _mappings.Add(typeof(COTTokenViewModel), typeof(COTTokenPage)); _mappings.Add(typeof(MeterNotificationsViewModel), typeof(MeterNotificationsPage)); _mappings.Add(typeof(MeterPaymentInfoViewModel), typeof(MeterPaymentInfoPage)); _mappings.Add(typeof(CreditCardInfoViewModel), typeof(CreditCardInfoPage)); _mappings.Add(typeof(ReadingsAndConsumptionViewModel), typeof(ReadingsAndConsumptionPage)); _mappings.Add(typeof(ForgotPasswordViewModel), typeof(ForgotPasswordPage)); _mappings.Add(typeof(PaymentRedirectViewModel), typeof(PaymentRedirectPage)); } }
}
This is the code for MainPage and its ViewModel - which is the MasterDetail:
<MasterDetailPage.Master>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
</MasterDetailPage.Detail>
ViewModel:
public class MainViewModel : ViewModelBase { private MenuViewModel _menuViewModel; public MainViewModel(INavigationService navigationService, IDialogService dialogService, IConnectionService connectionService, MenuViewModel menuViewModel) : base(navigationService, dialogService, connectionService) { _menuViewModel = menuViewModel; } public MenuViewModel MenuViewModel { get => _menuViewModel; set { _menuViewModel = value; OnPropertyChanged(); } } public override async Task InitializeAsync(object data) { await Task.WhenAll ( _menuViewModel.InitializeAsync(data), _navigationService.NavigateToAsync<HomeViewModel>() //<---HERE THE LOGIC OF CREATING THE NAV PAGE HAPPENS ); } }
macOS: Global keyboard shortcuts
Hi,
is there a way to simple add global keyboard shortcuts?
The best would be that they are can be changed at runtime.
Accessing file in Internal Storage/Download (path problem?)
I'm writing my first ever android application, and I'm at a point where I have a text file on the internal storage's Download folder, which I'd like to access and read. First I tried this:
string path = Path.Combine(Android.OS.Environment.DirectoryDownloads, "families.txt"); File.WriteAllText(path, "Write this text into a file!");
But it doesn't work, I get and unhandled exception. I have set the permissions to read and write to external storage (even though this is internal).
I also tried it with this:
string content; using (var streamReader = new StreamReader(@"file://" + path )) // with and without file:// { content = streamReader.ReadToEnd(); }
But I got the same unhandled exception. I came to the conclusion that the path is the problem, since I get the else part here:
Java.IO.File file = new Java.IO.File(path); if (file.CanRead()) testText.Text = "The file is there"; else testText.Text = "The file is NOT there\n" + path;
Which is weird, because the path seems to be correct.
Longpress and uiview animation in tableview cell
Android bitmap conversion
Hello,
How to convert rapidly ; An Android.Graphics.Bitmap
To a SkiaSharp.SKBitmap
Thx,
cjacquel
Does MVVMLight support Xamarin Mac
Hi,
Just wanted to ask if anyone is using the MVVMLight framework with Xamarin Mac, we use Prism on WPF and are now porting
our app to MacOS. Are there any issues with it? So far from researching online it seems to be targeted at WPF and Mobile platforms not much
about MacOS support mentioned.
Thanks
Have to clean/rebuild project every time
Hi,
I've just started to use Xamarin Forms and every time I want to run an iOS application in the simulator I have to clean/rebuild the solution. If I don't then it appears to still compile, but always runs the previously cleaned/built version... Am I missing something? From Googling it seems I'm the only one with this issue! Tried 2 separate PCs and a fresh install of everything. Also tried going back a few versions of Xamarin Forms but no luck
It's incredibly annoying and rendering it almost unusable.
Thanks!
VS 2019 16.1.6
Xamarin Forms 4.1.0.581479
Push Notification not working after Xamarin.Forms upgrade
My app was upgraded from Xamarin.Forms 3.1 to 4.1. Before upgrade, my push notification was working perfectlty, receiving notifications when in foreground, background or closed.
After the upgrade, my app is only receiving notifications when it is in foreground or background. If my remove my app from "apps recent list" or simply do not open it after cellphone reboot, i do not receive any notification.
I am sending my notifications using firebase portal and postman. Below, is my json format:
{ "data": { "title": "Título da Mensagem - data 1", "body": "Essa é uma mensagem longa, com muito conteúdo que precisa ser visualizado por inteiro na notificação do aplicativo !!!", "sound": "true" }, "notification": { "title": "Título da Mensagem - notification 1", "body": "Essa é uma mensagem longa, com muito conteúdo que precisa ser visualizado por inteiro na notificação do aplicativo !!!", "content_available": "true" }, "priority": "high", "to": "cezjmhzWaKM:APA91bGkEUQ......." }
Every notification sent by postman, receives the confirmation, like the example below:
{ "multicast_id": 2772544695401950510, "success": 1, "failure": 0, "canonical_ids": 0, "results": [ { "message_id": "0:1574816910300590%6671412c6671412c" } ] }
I do not receive any error, when my app is closed. So, I think the notification is received by my app, but it is not processed.
I am using FCM (Firebase Cloud Messaging).
Below, is my AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="215" android:versionName="2.0.9" package="com.algorix.myapp" android:installLocation="auto"> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" /> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="myapp.permission.MAPS_RECEIVE" android:protectionLevel="signature" /> <uses-permission android:name="myapp.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.VIBRATE" /> <application android:label="@string/app_name" android:icon="@mipmap/icon"> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_stat_logo_notification" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/accent_color" /> <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" /> <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="${applicationId}" /> </intent-filter> </receiver> <uses-library android:name="org.apache.http.legacy" android:required="false" /> <meta-data android:name="com.google.android.geo.API_KEY" android:value="AIza......." /> </application> </manifest>
I have also tried add the flag "FLAG_INCLUDE_STOPPED_PACKAGES", but without any change. Below, is my class which intercepts the notifications:
[Service] [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })] public class MyFirebaseMessagingService : FirebaseMessagingService { /// public override void OnMessageReceived(RemoteMessage message) { if (message.Data.Count > 0) { Log.Debug("Data - ", "Message data: " + message.Data.ToString()); SendNotification(message.Data); } else { if (message.GetNotification() != null) { Log.Debug("Notification - ", "Message notification: " + message.Data.ToString()); SendNotification(message.GetNotification()); } } } /// public void SendNotification(IDictionary<string, string> data) { try { var intent = new Intent(this, typeof(MainActivity)); intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.IncludeStoppedPackages); foreach (string key in data.Keys) { intent.PutExtra(key, data[key]); } var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot); messageTitle = intent.GetStringExtra("title"); messageBody = intent.GetStringExtra("body"); messageSoundEnabled = intent.GetStringExtra("sound"); SetNewAlert(messageTitle, messageBody); MountAlert(messageTitle, messageBody, pendingIntent); } catch (Exception ex) { _services.SendError(ex.GetType().Name, ex.Message, "Android Project", "SendNotification", _version.GetVersion()); } } /// public void SendNotification(RemoteMessage.Notification notification) { try { var intent = new Intent(this, typeof(MainActivity)); intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.IncludeStoppedPackages); var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot); messageTitle = notification.Title; messageBody = notification.Body; SetNewAlert(messageTitle, messageBody); MountAlert(messageTitle, messageBody, pendingIntent); } catch (Exception ex) { _services.SendError(ex.GetType().Name, ex.Message, "Android Project", "SendNotification", _version.GetVersion()); } } /// private void MountAlert(string title, string message, PendingIntent intent) { try { string channelIdAndroid = Android.App.Application.Context.Resources.GetString(Resource.String.appnotificationchannel); string channelNameAndroid = "Android Channel"; Notification.Builder notification = null; if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop) { notification = new Notification.Builder(this, channelIdAndroid) .SetSmallIcon(Resource.Drawable.ic_stat_logo_notification) .SetContentTitle(title) .SetContentText(message) .SetAutoCancel(true) .SetStyle(new Notification.BigTextStyle().BigText(message)) .SetContentIntent(intent); notificationManager = NotificationManager.FromContext(this); } else { if ((Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop) && (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.O)) { notification = new Notification.Builder(this, channelIdAndroid) .SetSmallIcon(Resource.Drawable.ic_stat_logo_notification) .SetLargeIcon(BitmapFactory.DecodeResource(Android.App.Application.Context.Resources, Resource.Mipmap.icon)) .SetColor(Resource.Color.accent_color) .SetContentTitle(title) .SetContentText(message) .SetAutoCancel(true) .SetStyle(new Notification.BigTextStyle().BigText(message)) .SetContentIntent(intent); notificationManager = NotificationManager.FromContext(this); } else { if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O) { NotificationChannel androidChannel = new NotificationChannel(channelIdAndroid, channelNameAndroid, NotificationImportance.Default); androidChannel.EnableVibration(true); androidChannel.SetSound(null, null); androidChannel.ShouldShowLights(); androidChannel.EnableLights(true); androidChannel.SetShowBadge(true); androidChannel.LightColor = Resource.Color.accent_color; androidChannel.LockscreenVisibility = NotificationVisibility.Public; notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService); notificationManager.CreateNotificationChannel(androidChannel); notification = new Notification.Builder(this, channelIdAndroid) .SetSmallIcon(Resource.Drawable.ic_stat_logo_notification) .SetLargeIcon(BitmapFactory.DecodeResource(Android.App.Application.Context.Resources, Resource.Mipmap.icon)) .SetColor(Resource.Color.accent_color) .SetContentTitle(title) .SetContentText(message) .SetAutoCancel(true) .SetStyle(new Notification.BigTextStyle().BigText(message)) .SetContentIntent(intent); } } } if (notificationManager != null && notification != null) { notificationManager.Notify(RandomGenerator(), notification.Build()); if (messageSoundEnabled != null && messageSoundEnabled.Length > 0) { bool soundEnabled; bool.TryParse(messageSoundEnabled, out soundEnabled); if (soundEnabled) { var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current; player.Load("notification.mp3"); player.Play(); } } } } catch (Exception ex) { _services.SendError(ex.GetType().Name, ex.Message, "Android Project", "MountAlert", _version.GetVersion()); } }
And my last try, was to upgrade Xamarin.Forms to 4.3, but also nothing happenned.
Please, any clue to solve this problem ???
First WebRequest slow.
I've made an app that's suppossed to make several requests to a Website.
When sending the first request using WebRequests, the process is extremely slow.
Being new to Xamarin I obviously tried google, but alas, no solution found.
That is why, I'm turning towards you for help.
I ran the exact same sequence of requests twice on an Android Emulator. You can see the Debug Log, and the code used below.
The Website requested to uses SSL, eg. HTTPS:// example.com/
My Debug Log:
pastebin.com/8DyfPPFf
My code snippet:
pastebin.com/HTSCHy4i
CarouselView with contentpages / switch between views in a page
Hi All,
I am trying to implement tabs to switch between content views/pages in a page. Alternatively I thought i could do this
with a carouselView where i bind pages to it ( but haven't been successful in binding pages as i can only do photos).
Any help would be appreciated!!! Picture attached ! I have been trying this for days and still no luck
Best wishes, Lou
Horizontal Text Alignment Like Article Mode
Hi everyone !
As you can see in the picture, the text appears only start on the left side. My goal is to make the text appear flat on both sides. Like microsoft word article mode.
Please help, how can i solved?
Thanks in advance!
How do I make HTTP requests using proxy settings?
On the face of it this may seem to be a simple question with a simple answer, but the past couple of weeks have proven that to not be the case.
First of all I'm working on a Xamarin.Forms application, using Xamarin.Forms 2.3.3.193 (I can't upgrade as .Net Framework 4.7+ is not compatible with my version of Windows 10 Enterprise edition)
The general workflow when my app starts is:
1) Ping the server
2) If the server does not respond, push a modal navigation page onto the stack
I have a proxy set up on my network which I can turn on and off at a whim (it's FreeProxy)
On my devices I configure the wifi connection to go through that proxy. When the proxy is off, all network traffic should result in an error (probably a 404 error). When on, all traffic should go through. Similarly, when the devices don't have a proxy configured, the proxy should be irrelevant.
On Android it was frustrating, but I finally managed to get it working by asking the device for the proxy settings, and if they exist, implementing them into the HttpClientHandler configuration:
public HttpClient GetClient() { var handler = new HttpClientHandler(); string host = Java.Lang.JavaSystem.GetProperty("http.proxyHost"); string port = Java.Lang.JavaSystem.GetProperty("http.proxyPort"); if (!string.IsNullOrEmpty(host)) { host = host.TrimEnd('/'); } if (!string.IsNullOrEmpty(host) && !string.IsNullOrEmpty(port)) { handler.Proxy = new WebProxy($"{host}:{port}", true); handler.UseProxy = true; } return new HttpClient(handler); }
On iOS, however, not only can I not get this working properly, but I'm getting some incredibly odd results.
I can get the proxy settings via
CFNetwork.GetSystemProxySettings();
but then implementing those settings into any form of request is proving to be nigh on impossible.
If I do like I do on Android, using HttpClientHandler, the proxy settings are ignored.
If I instead use ModernHttpClient, the proxy settings are ignored.
Currently I'm using NSUrlSessionHandler:
public HttpClient GetClient() { var configuration = NSUrlSessionConfiguration.DefaultSessionConfiguration; var settings = CFNetwork.GetSystemProxySettings(); string host = settings.HTTPProxy; string port = settings.HTTPPort.ToString(); if (!string.IsNullOrEmpty(host)) { host = host.TrimEnd('/'); } if (!string.IsNullOrEmpty(host) && !string.IsNullOrEmpty(port)) { NSObject[] values = new NSObject[] { NSObject.FromObject(host), //ProxyHost NSNumber.FromInt32 (settings.HTTPPort), //Port NSNumber.FromInt32 (1), //Enable HTTP proxy NSObject.FromObject(host), //ProxyHost NSNumber.FromInt32 (settings.HTTPPort), //Port NSNumber.FromInt32 (1), //Enable HTTP proxy }; NSObject[] keys = new NSObject[] { NSObject.FromObject("HTTPProxy"), NSObject.FromObject("HTTPPort"), NSObject.FromObject("HTTPEnable"), NSObject.FromObject("HTTPSProxy"), NSObject.FromObject("HTTPSPort"), NSObject.FromObject("HTTPSEnable") }; NSDictionary proxyDict = NSDictionary.FromObjectsAndKeys(values, keys); configuration.ConnectionProxyDictionary = proxyDict; } var handler = new NSUrlSessionHandler(configuration); var client = new HttpClient(handler); return client; }
Or
public async Task<RequestResultDto> MakeRequest(RequestDto dto) { var returnDto = new RequestResultDto(); var configuration = NSUrlSessionConfiguration.DefaultSessionConfiguration; var settings = CFNetwork.GetSystemProxySettings(); string host = settings.HTTPProxy; string port = settings.HTTPPort.ToString(); if (!string.IsNullOrEmpty(host)) { host = host.TrimEnd('/'); } if (!string.IsNullOrEmpty(host) && !string.IsNullOrEmpty(port)) { NSObject[] values = new NSObject[] { NSObject.FromObject(host), //ProxyHost NSNumber.FromInt32 (settings.HTTPPort), //Port NSNumber.FromInt32 (1), //Enable HTTP proxy NSObject.FromObject(host), //ProxyHost NSNumber.FromInt32 (settings.HTTPPort), //Port NSNumber.FromInt32 (1), //Enable HTTP proxy }; NSObject[] keys = new NSObject[] { NSObject.FromObject("HTTPProxy"), NSObject.FromObject("HTTPPort"), NSObject.FromObject("HTTPEnable"), NSObject.FromObject("HTTPSProxy"), NSObject.FromObject("HTTPSPort"), NSObject.FromObject("HTTPSEnable") }; NSDictionary proxyDict = NSDictionary.FromObjectsAndKeys(values, keys); configuration.ConnectionProxyDictionary = proxyDict; } var session = NSUrlSession.FromConfiguration(configuration); var request = new NSUrlRequest(new NSUrl(dto.uri), NSUrlRequestCachePolicy.UseProtocolCachePolicy, dto.timeout); //var requestTask = await session.CreateDataTaskAsync(request); var requestTask = await NSUrlSession.SharedSession.CreateDataTaskAsync(request); if (requestTask != null) { var data = requestTask.Data; var response = requestTask.Response; //the response always has a 200 status code } return returnDto; }
but, as you might be able to guess, the proxy settings are ignored.
I also tried using WebRequest and HttpWebRequest, but those have the same problem.
Now, here's the truly bizarre part. If I try to use CFNetworkHandler, I get absolutely no traffic whether or not the device has a proxy set up. Not only that, but this breaks all threading in the application!
The aforementioned error page gets pushed onto the stack within Device.BeginInvokeOnMainThread (since the validation is itself on a different thread), but if I use CFNetworkHandler no calls to Device.BeginInvokeOnMainThread invoke any code!
Does anyone know how to ensure that HTTP requests actually respect the proxy settings that are on the device, or at least the ones I provide to it?
MSAL.NET and On-premises STS/ADFS
Can anyone help me find a good example of how to to use MSAL.NET libraries to request a security token (OAuth) from an** on-premises** STS/ADFS ? I have seen a lot of examples using it for Azure AD but that is not our case.
Beginner question on bluetooth scales
Hi all,
My bathroom scale has died, so need a new one. Oh look, bluetooth scales - that'd be handy! (save me manually entering the data) I have an Android phone with Samsung Health (S Health) on it (which I already track some other stuff with). They list several scales that are compatible. Of course, none of these are available at my local shops (would have to buy online, pay more, and wait). :-(
However there ARE bluetooth scales available at my local shops, but not listed in S Health, and they mention "these apps are compatible (lists 1 Android and 1 iOS)" (S Health not listed, of course).
So my question is, surely it's possible to write a Xamarin app myself to get the data over bluetooth? Or do these apps have some kind of exclusive licensing deal with the scale makers? Do some of them have API's available? (this info not shown in shop listing of course) Never done anything with bluetooth before, so have no idea at all about this stuff. Would be good to start though. :-)
P.S. this is one available locally, but no idea if I can get it to sync with either S Health or a Xamarin app that I've written myself - https://www.kmart.com.au/product/bluetooth-body-analysis-scale/1330516
thanks,
Donald.
Xamarin.Android Buid Error : Expected reference but got (raw string) #000000
Hello,
I got an unpredictable error when i build the android project in xamarin forms.
error is looks like,
Bind Label visibility to List being empty or not
How can I bind the visibility of a Label, where the Label is visible if a list is empty? Below doesn't work.
bool _showAllUsersEmptyLabel; public bool ShowAllUsersEmptyLabel { get { return _showAllUsersEmptyLabel; } set { _showAllUsersEmptyLabel = (AllUsers != null && !AllUsers.Any()); this.OnPropertyChanged(nameof(this._showAllUsersEmptyLabel)); } }
ContentView bindings not working
Hi everyone, I'm trying to create a custom control that allows me to show an horizontal list after having loaded the data from an online resource.
I'm still new to creating custom controls with property binding and this is quite frustrating to be honest .
In order to do what I want I derived a ContentView and this are its XAML an code-behind:
<?xml version="1.0" encoding="UTF-8"?> <ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:ff="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" x:Class="AppName.Controls.BrandsCarousel" x:Name="brands_carousel" HeightRequest="120"> <ContentView.Content> <StackLayout BindingContext="{x:Reference brands_carousel}"> <ActivityIndicator IsVisible="{Binding IsLoading}" IsRunning="{Binding IsLoading}" /> <CollectionView IsVisible="{Binding IsNotLoading}" ItemsSource="{Binding Brands}"> <CollectionView.ItemsLayout> <GridItemsLayout Orientation="Horizontal" Span="1" HorizontalItemSpacing="8" /> </CollectionView.ItemsLayout> <CollectionView.ItemTemplate> <DataTemplate> <ff:CachedImage LoadingPlaceholder="tab_home" Source="{Binding Image}" WidthRequest="150" Aspect="AspectFit" /> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </StackLayout> </ContentView.Content> </ContentView> using System.Collections; using System.Runtime.CompilerServices; using Xamarin.Forms; namespace AppName.Controls { public partial class BrandsCarousel : ContentView { public static readonly BindableProperty BrandsProperty = BindableProperty.Create(nameof(Brands), typeof(IEnumerable), typeof(BrandsCarousel), null, propertyChanged: OnBrandsChanged, defaultBindingMode: BindingMode.OneWay); public static readonly BindableProperty IsLoadingProperty = BindableProperty.Create(nameof(IsLoading), typeof(bool), typeof(BrandsCarousel), null, propertyChanged: OnIsLoadingChanged, defaultBindingMode: BindingMode.OneWay); private static void OnBrandsChanged(BindableObject bindable, object oldValue, object newValue) { var control = (BrandsCarousel)bindable; control.Brands = newValue as IEnumerable; } private static void OnIsLoadingChanged(BindableObject bindable, object oldValue, object newValue) { var control = (BrandsCarousel)bindable; control.IsLoading = (bool)newValue; } public IEnumerable Brands { get => (IEnumerable)GetValue(BrandsProperty); set => SetValue(BrandsProperty, value); } public bool IsLoading { get => (bool)GetValue(IsLoadingProperty); set { SetValue(IsLoadingProperty, value); OnPropertyChanged(nameof(IsNotLoading)); } } public bool IsNotLoading { get => !(bool)GetValue(IsLoadingProperty); } public BrandsCarousel() { InitializeComponent(); } } }
This is the view in which I'm including the custom control:
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:ff="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" xmlns:controls="clr-namespace:AppName.Controls" xmlns:vm="clr-namespace:AppName.ViewModels" x:Class="AppName.Views.HomePage" Title="Home"> <ContentPage.BindingContext> <vm:HomeViewModel /> </ContentPage.BindingContext> <ContentPage.Content> <StackLayout Spacing="0"> <Label Text="Our brands" StyleClass="SectionTitleLabel" /> <controls:BrandsCarousel Brands="{Binding Brands}" IsLoading="{Binding LoadingBrands}" /> </StackLayout> </ContentPage.Content> </ContentPage> using Xamarin.Forms; namespace AppName.Views { public partial class HomePage : ContentPage { public HomePage() { InitializeComponent(); } } }
And this is the view model associated with the view, responsible of loading the data from the online resource
using System.Collections.ObjectModel; using System.Threading.Tasks; using AppName.Models; using AppName.Services; using AsyncAwaitBestPractices.MVVM; namespace AppName.ViewModels { public class HomeViewModel : INotifyPropertyChanged { private ObservableCollection<Brand> _brands; public ObservableCollection<Brand> Brands { get => _brands; set => SetProperty(ref _brands, value); } public IAsyncCommand LoadBrandsCommand { get; set; } private bool _loadingBrands; public bool LoadingBrands { get => _loadingBrands; set => SetProperty(ref _loadingBrands, value); } public HomeViewModel() { LoadBrandsCommand = new AsyncCommand(LoadBrands, _ => !LoadingBrands); LoadBrandsCommand.Execute(null); } private async Task LoadBrands() { LoadingBrands = true; var brands = await BrandsDataStore.GetBrandsAsync(); Brands = new ObservableCollection<Brand>(brands); LoadingBrands = false; } protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName]string propertyName = "", Action onChanged = null) { if (EqualityComparer<T>.Default.Equals(backingStore, value)) return false; backingStore = value; onChanged?.Invoke(); OnPropertyChanged(propertyName); return true; } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { var changed = PropertyChanged; if (changed == null) return; changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion } }
The problem I'm facing is that the BrandsCarouse.Brands
property gets correctly notified of the change happening inside of HomeViewModel.LoadBrands
but the BrandsCarousel.IsLoading
does not. What could be the reason?
DB Locked in Android SQLite Xamarin Forms
I'm working on a App that have more than 50 tables and can work without internet connection, so in background the app can sync up with the API and get all the information and make the CRUD operation in local.
Sometimes when the app is sync up with the API, I'm getting the error "database is LOCKED", when I'm making another operation on the App.
So I need help to solve this, I know that there are a lot of post about this problem, but base on my implamentation with my database, it seems not to be enough to solve my problem.
Nugets:
Xamarin.Forms 3.0.0 482510
sqlite-net-pcl 1.5.166-beta
I use a class DataService.cs where that class connect with the DataContext.cs and make the connection with database and methods CRUD.
All methods in the DataService have the same way to connect with DataContext
//This is a resume of DataService.cs public class DataService { public T Insert<T>(T model) { try { using (var da = new DataContext()) { da.Insert(model); return model; } } catch (Exception error) { error.ToString(); return model; } } }
In DataContext.cs we have the connection with the local database and all the methods with the local database .
All methods have the collisionLock (to avoid conflict with database) and cnn.Dispose() (To close connection with the database and avoid the error Fatal signal 11 (SIGSEGV));
DataContext.cs
public interface IBusinessEntity { int ID { get; set; } } //This is a resume of DataContext.cs public class DataContext : IDisposable { #region Attributes public SQLiteConnection cnn; private static object collisionLock = new object(); #endregion #region Constructors public DataContext() { cnn = DependencyService.Get<IConfiguracion>().GetConnection(); ... } #endregion #region MetodosGenericosZulu public void Insert<T>(T model) { try { // Use locks to avoid database collisions lock (collisionLock) { cnn.Insert(model); cnn.Dispose(); } } catch (Exception error) { Application.Current.MainPage.DisplayAlert( "Error", "Un error a ocurrido con la DB (Insert): " + error.Message.ToString(), "Ok"); } } public void Update<T>(T model) { try { lock (collisionLock) { cnn.Update(model); cnn.Dispose(); } } catch (Exception error) { Application.Current.MainPage.DisplayAlert( "Error", "Un error a ocurrido con la DB (Actualizar): " + error.Message.ToString(), "Ok"); } } ... #endregion } }
Implentation on Android project.
public class Configuracion : IConfiguracion { public Configuracion(){ } public SQLite.SQLiteConnection GetConnection() { var sqliteFileName = "FN_Desarrollo.db3"; string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); var path = Path.Combine(documentsPath, sqliteFileName); var conn = new SQLite.SQLiteConnection(path, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.SharedCache); return conn; } }
So I need your help guys to solve the problem (database locked) and review if my implementation with the SQLite is OK.
I'm hearing all the suggestions.
Thanks in advance.
Erreur provoqué lors de l'upload de plusieurs images
I try to upload at least 30 pictures to a web server but my program catch errors. They appear randomly, sometimes at the first image, sometimes third etc.
ERREUR
{System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: Unable to write data to the transport connection: Connection reset by peer. ---> System.Net.Sockets.SocketException: Connection reset by peer at System.Net.Sockets.Socket.EndSend (System.IAsyncResult asyncResult) [0x0000c] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/System/net/System/Net/Sockets/Socket.cs:3874 at System.Net.Sockets.NetworkStream.EndWrite (System.IAsyncResult asyncResult) [0x00057] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/System/net/System/Net/Sockets/NetworkStream.cs:1043 --- End of inner exception stack trace ---
OR
Read error: ssl=0x7e46332e08: I/O error during system call, Connection reset by peer
PROCESS
I explain you the process : I got an array with image path and I created a loop to upload each image on my web server.
public static async Task CreateUploadTask(string file, string id, string user_id, string user_login)
{
string requestResult = ""; var cont = new MultipartFormDataContent(); var image = new StreamContent(File.OpenRead(file)); image.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "file", FileName = "imageToUpload.jpeg" }; image.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); cont.Add(image); string id_level = id string uri = // private uri using (var client = new HttpClient()) { var response = await client.PostAsync(uri, cont); if (response.StatusCode != System.Net.HttpStatusCode.OK) { return "error"; } requestResult = response.Content.ReadAsStringAsync().Result; Console.WriteLine("DATA FINAL" + requestResult); } return requestResult; }
Tell me if you already got this errors when you uploading files. How to solve it, I saw in some topics, some people have the same issue. It can be usefull to resolve this issue. Thank you in advance.
UPDATE
public async void LaunchImagesUpload()
{
for (int i = startIndex; i < picturesToUpload.Count; i++)
{
try
{
currentPath = i;
await UploadSinglePicture(i);
}
catch (Exception e)
{
if (e.Message.Equals("The operation was canceled.")) { currentPictureGrid.ActivateCancelledMode("Temps de transfert trop long."); if (!picturesToReupload.Contains(i)) picturesToReupload.Add(i); } else if (e.Message.Equals("Error while copying content to a stream.")) { currentPictureGrid.ActivateCancelledMode("Error, retry"); if (!picturesToReupload.Contains(i)) await UploadSinglePicture(i); } else { await UploadSinglePicture(i); } } } }