Работа с контактами в Xamarin

Автор:

Xamarin Developers

Интеграция функциональности контактов была общей задачей, которую меня на протяжении многих лет просили разрабатывать для мобильных приложений. Это варьировалось от полного каталога контактов до простой контактной информации внутри приложения. Большинство требуемых функций включают возможность звонка контакту, отправки SMS или электронной почты, а также навигацию к нужному местоположению. В прошлом мне приходилось самостоятельно реализовывать несколько родных API или устанавливать несколько библиотек, которые могли бы обеспечить такую функциональность. Сегодня с Xamarin.Essentials все эти функции доступны в одной библиотеке и могут быть реализованы всего в 4 строках кода! Итак, давайте построим приложение для контактов с Xamarin.Essentials и Xamarin.Forms.

Контакт

Первое, что нужно сделать, это определить класс Contact. В нем будет вся информация, необходимая при использовании Xamarin.Essentials API. Сюда входит номер телефона, адрес электронной почты и адрес

public class Contact
{
    public string Name { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set;& }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

Связаться с пользовательским интерфейсом

Существует множество способов представления контактной информации, и, например, мы можем использовать сетку для отображения всей информации. Мы можем использовать ImageButton для каждого элемента, чтобы позволить пользователям выполнять действия. Каждая команда привязана к методу, который будет вызываться из ViewModel, который я опишу ниже.

<Grid RowSpacing="8">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="44"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="44"/>
    </Grid.ColumnDefinitions>
 
    <!--Phone & SMS-->
    <ImageButton Source="phone.png" Grid.Row="0" VerticalOptions="Center"
                 Command="{Binding PhoneCommand}" BackgroundColor="Transparent" />
    <Label Grid.Column="1" Grid.Row="0"
           VerticalOptions="Center"
           Text="{Binding Contact.PhoneNumber}"/>
    <ImageButton Source="sms.png" Grid.Row="0" Grid.Column="2" VerticalOptions="Center"
                 Command="{Binding SmsCommand}" BackgroundColor="Transparent"/>
    
    <!--Email-->
    <ImageButton Source="email.png" Grid.Row="1"  VerticalOptions="Center"
                 Command="{Binding EmailCommand}" BackgroundColor="Transparent"/>
 
    <Label Grid.Column="1" Grid.Row="1"
           VerticalOptions="Center"
           Text="{Binding Contact.Email}"/>
 
    <!--Address-->
    <ImageButton Source="navigate.png" Grid.Row="2" VerticalOptions="Center"
                 Command="{Binding NavigateCommand}" BackgroundColor="Transparent"/>
 
    <StackLayout Grid.Column="1" Grid.Row="2" VerticalOptions="Center">
        <Label Text="{Binding Contact.Address}"/>
        <Label>
            <Label.FormattedText>
                <FormattedString>
                    <Span Text="{Binding Contact.City}"/>
                    <Span Text=" "/>
                    <Span Text="{Binding Contact.State}"/>
                    <Span Text=", "/>
                    <Span Text="{Binding Contact.ZipCode}"/>
                </FormattedString>
            </Label.FormattedText>
        </Label>
    </StackLayout>

</Grid>

Это даст нам очень красивый пользовательский интерфейс для нашего контакта.

Телефонный дозвон, SMS, электронная почта и навигация.

Каждая команда, связанная в пользовательском интерфейсе, имеет метод, который будет выполняться при нажатии этой кнопки. Каждый метод использует API Xamarin.Essentials для выполнения собственных функций из одной строки кода! Вот полная версия ViewModel из образца приложения

public class ContactViewModel
{
    public Command SmsCommand { get; }
    public Command EmailCommand { get; }
    public Command PhoneCommand { get; }
    public Command NavigateCommand { get; }
 
    public Contact Contact { get; }
 
    public ContactViewModel(Contact contact)
    {
        Contact = contact;
    }
 
    public ContactViewModel()
    {
        Contact = new Contact
        {
            Name = "James Montemagno",
            Address = "Microsoft Building 18",
            City = "Redmond",
            State = "WA",
            ZipCode = "98052",
            Email = "motz@microsoft.com",
            PhoneNumber = "555-555-5555"
        };
 
        SmsCommand = new Command(async () => await ExecuteSmsCommand());
        EmailCommand = new Command(async () => await ExecuteEmailCommand());
        PhoneCommand = new Command(ExecutePhoneCommand);
        NavigateCommand = new Command(async () => await ExecuteNavigateCommand());
    }
 
    async Task ExecuteSmsCommand()
    {
        try
        {
            await Sms.ComposeAsync(new SmsMessage(string.Empty, Contact.PhoneNumber));
        }
        catch (Exception ex)
        {
            ProcessException(ex);
        }
    }
 
    async Task ExecuteEmailCommand()
    {
        try
        {
            await Email.ComposeAsync(string.Empty, string.Empty, Contact.Email);
        }
        catch (Exception ex)
        {
            ProcessException(ex);
        }
    }
 
    void ExecutePhoneCommand()
    {
        try
        {
            PhoneDialer.Open(Contact.PhoneNumber);
        }
        catch (Exception ex)
        {
            ProcessException(ex);
        }
    }
 
    async Task ExecuteNavigateCommand()
    {
        try
        {
            await Map.OpenAsync(new Placemark
            {
                Thoroughfare = Contact.Address,
                Locality = Contact.City,
                AdminArea = Contact.State,
                PostalCode = Contact.ZipCode
            });
        }
        catch (Exception ex)
        {
            ProcessException(ex);
        }
    }
 
    void ProcessException(Exception ex)
    {
        if (ex != null)
            Application.Current.MainPage.DisplayAlert("Error", ex.Message, "OK");
    }
}

Обратите внимание, что на каждой платформе вызов метода упаковывается в блок Try/Catch. Это важно в том случае, если функция недоступна на конкретном устройстве. Кроме того, мы закончили! С помощью всего 4 крошечных строчек кода мы интегрировали множество замечательных функций в наше приложение для контактов!

Материалы по теме