연습: 전화 번호 변환기 앱 만들기

완료됨

이 연습에서는 전화 걸기 앱에 대한 UI를 생성하고 이 UI 뒤에 있는 논리를 구현합니다.

.NET MAUI 및 .NET MAUI Essentials 패키지의 UI 기능을 활용하여 전화를 거는 UI를 빌드합니다.

앱을 사용하면 사용자가 텍스트를 입력 필드에 입력하고 해당 텍스트를 숫자로 변환시킬 수 있습니다. 전화 키패드에 표시되는 문자를 변환 기준으로 사용합니다. 예를 들어 2 숫자에는 a, b, c라는 세 개의 문자가 모두 있으므로 cab 문자는 222로 변환됩니다.

이전 연습에서 만든 Phoneword 솔루션을 사용하여 계속 진행합니다.

앱에 새 C# 원본 파일 추가

  1. 아직 열지 않은 경우 Visual Studio에서 Phoneword 솔루션을 엽니다.

  2. 솔루션 탐색기 창에서 Phoneword 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음, 클래스를 선택합니다.

  3. 새 항목 추가 대화 상자에서 클래스 파일 PhonewordTranslator.cs의 이름을 지정하고 추가를 선택합니다.

    A screenshot of the Add new item dialog box. The user has named the class file PhonewordTranslator.cs

변환 논리 추가

클래스 파일의 콘텐츠를 다음 코드로 바꾸고 파일을 저장합니다. PhonewordTranslator 클래스의 정적 메서드 ToNumber은(는) 영숫자 텍스트의 숫자를 일반 숫자 전화 번호로 변환합니다.

using System.Text;

namespace Core;

public static class PhonewordTranslator
{
    public static string ToNumber(string raw)
    {
        if (string.IsNullOrWhiteSpace(raw))
            return null;

        raw = raw.ToUpperInvariant();

        var newNumber = new StringBuilder();
        foreach (var c in raw)
        {
            if (" -0123456789".Contains(c))
                newNumber.Append(c);
            else
            {
                var result = TranslateToNumber(c);
                if (result != null)
                    newNumber.Append(result);
                // Bad character?
                else
                    return null;
            }
        }
        return newNumber.ToString();
    }

    static bool Contains(this string keyString, char c)
    {
        return keyString.IndexOf(c) >= 0;
    }

    static readonly string[] digits = {
        "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"
    };

    static int? TranslateToNumber(char c)
    {
        for (int i = 0; i < digits.Length; i++)
        {
            if (digits[i].Contains(c))
                return 2 + i;
        }
        return null;
    }
}

UI 만들기

  1. Phoneword 프로젝트에서 MainPage.xaml 파일을 엽니다.

  2. ScrollView 컨트롤과 해당 콘텐츠를 제거하고 ContentPage 컨트롤만 남깁니다.

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Phoneword.MainPage">
    
    </ContentPage>
    
  3. 세로 방향이며 간격이 15단위, 패딩이 20단위인 VerticalStackLayout 컨트롤을 ContentPage에 추가합니다.

    <ContentPage ... >
        <VerticalStackLayout Spacing="15" Padding="20">
    
        </VerticalStackLayout>
    </ContentPage>
    
  4. StackLayout에 Label 컨트롤을 추가합니다.

    <ContentPage ... >
        <VerticalStackLayout ...>
            <Label Text = "Enter a Phoneword"
                   FontSize ="20"/>
        </VerticalStackLayout>
    </ContentPage>
    
  5. 레이블 아래의 StackLayout에 Entry 컨트롤을 추가합니다. Entry 컨트롤은 사용자가 데이터를 입력할 수 있는 텍스트 상자를 제공합니다. 이 코드에서 x:Name 속성은 컨트롤에 이름을 지정합니다. 나중에 앱에 대한 코드에서 이 컨트롤을 참조합니다.

    <ContentPage ... >
        <VerticalStackLayout ...>
            <Label .../>
            <Entry x:Name = "PhoneNumberText"
                   Text = "1-555-NETMAUI" />
        </VerticalStackLayout>
    </ContentPage>
    
  6. Entry 컨트롤 뒤의 VerticalStackLayout에 두 개의 Button 컨트롤을 추가합니다. 두 단추 모두 현재 아무 작업도 수행하지 않으며 두 번째 단추는 처음에 사용하지 않도록 설정됩니다. 다음 작업에서 다음 두 단추에 대한 Clicked 이벤트를 처리하는 코드를 추가합니다.

    <ContentPage ... >
        <VerticalStackLayout ...>
            <Label .../>
            <Entry ... />
            <Button x:Name = "TranslateButton"
                    Text = "Translate"
                    Clicked = "OnTranslate"/>
            <Button x:Name = "CallButton"
                    Text = "Call"
                    IsEnabled = "False"
                    Clicked = "OnCall"/>
        </VerticalStackLayout>
    </ContentPage>
    

TranslateButton 단추 탭에 응답

  1. 솔루션 탐색기 창에서 MainPage.xaml 항목을 확장한 다음 MainPage.xaml.cs 코드 숨김 파일을 엽니다.

  2. MainPage 클래스에서 count 변수와 OnCounterClicked 메서드를 제거합니다. 이 클래스는 다음과 같이 표시되어야 합니다.

    namespace Phoneword;
    
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }
    
  3. 생성자 다음에, translatedNumber 문자열 변수와 다음 OnTranslate 메서드를 MainPage 클래스에 추가합니다. OnTranslate 메서드는 Entry 컨트롤의 Text 속성에서 전화 번호를 검색하여, 이전에 만든 PhonewordTranslator 클래스의 정적 ToNumber 메서드에 전달합니다.

    public partial class MainPage : ContentPage
    {
        ...
        string translatedNumber;
    
        private void OnTranslate(object sender, EventArgs e)
        {
            string enteredNumber = PhoneNumberText.Text;
            translatedNumber = Core.PhonewordTranslator.ToNumber(enteredNumber);
    
            if (!string.IsNullOrEmpty(translatedNumber))
            {
                // TODO:
            }
            else
            {
                // TODO:
            }
        }
    }
    

    참고

    다음 단계에서 이 코드의 누락된 TODO 비트를 채웁니다.

  4. OnTranslate 메서드에서 성공적으로 변환되면 전화 번호를 포함하도록 통화 단추의 Text 속성을 변경하는 코드를 추가합니다. translatedNumber 필드에 저장한 값을 사용할 수 있습니다. 또한 성공적인 변환에 따라 단추를 사용하거나 사용하지 않도록 설정합니다. 예를 들어 TranslateNumber에서 null을 반환하는 경우 단추를 사용하지 않도록 설정하지만, 성공한 경우에는 사용하도록 설정합니다.

    private void OnTranslate(object sender, EventArgs e)
    {
        string enteredNumber = PhoneNumberText.Text;
        translatedNumber = Core.PhonewordTranslator.ToNumber(enteredNumber);
    
        if (!string.IsNullOrEmpty(translatedNumber))
        {
            CallButton.IsEnabled = true;
            CallButton.Text = "Call " + translatedNumber;
        }
        else
        {
            CallButton.IsEnabled = false;
            CallButton.Text = "Call";
        }
    }
    

CallButton 단추에 대한 이벤트 메서드 만들기

  1. MainPage 클래스의 끝에 OnCall 이벤트 처리 메서드를 추가합니다. 이 메서드는 비동기 작업을 사용하므로 async로 표시합니다.

    public partial class MainPage : ContentPage
    {
    
        ...
        async void OnCall(object sender, System.EventArgs e)
        {
    
        }
    }
    
  2. OnCall 메서드에서 Page.DisplayAlert 메서드를 사용하여 사용자에게 번호로 전화를 걸 것인지 묻는 메시지를 표시합니다.

    DisplayAlert에 대한 매개 변수는 제목 및 메시지와, 수락과 취소 단추 텍스트에 사용할 두 문자열입니다. Accept 단추를 눌러 대화 상자를 닫았는지 여부를 나타내는 부울을 반환합니다.

    async void OnCall(object sender, System.EventArgs e)
    {
        if (await this.DisplayAlert(
            "Dial a Number",
            "Would you like to call " + translatedNumber + "?",
            "Yes",
            "No"))
        {
            // TODO: dial the phone
        }
    }
    

애플리케이션 테스트

  1. Visual Studio 도구 모음에서 Windows 컴퓨터 프로필을 선택하고 디버깅을 시작합니다.

  2. 변환 단추를 탭하여 기본 텍스트를 유효한 전화 번호로 변환합니다. 통화 단추의 캡션은 1-555-6386284 전화 걸기로 변경됩니다.

    A screenshot of the Phoneword UI. The user has translated the text to a valid phone number.

  3. 통화 단추를 탭합니다. 작업을 확인하라는 메시지가 표시되는지 확인합니다. 아니오를 선택합니다.

    A screenshot of the PhoneWord user interface's Dial a Number prompt.

  4. Visual Studio로 돌아가서 디버깅을 중지합니다.

전화 번호로 전화 걸기

  1. MainPage.xaml.cs 코드 숨김 파일에서 OnCall 메서드를 편집하고 TODO 주석을 다음 try/catch 블록으로 바꿉니다.

    async void OnCall(object sender, System.EventArgs e)
    {
        if (await this.DisplayAlert(
            "Dial a Number",
            "Would you like to call " + translatedNumber + "?",
            "Yes",
            "No"))
        {
            try
            {
                if (PhoneDialer.Default.IsSupported)
                    PhoneDialer.Default.Open(translatedNumber);
            }
            catch (ArgumentNullException)
            {
                await DisplayAlert("Unable to dial", "Phone number was not valid.", "OK");
            }
            catch (Exception)
            {
                // Other error has occurred.
                await DisplayAlert("Unable to dial", "Phone dialing failed.", "OK");
            }
        }
    }
    

    Microsoft.Maui.ApplicationModel.Communication 네임스페이스의 PhoneDialer 클래스는 Windows, Android, iOS(및 iPadOS) 및 macOS 플랫폼에 대한 전화 걸기 기능(및 기타)의 추상화를 제공합니다. 정적 Open 메서드는 전화 걸기를 사용하여 매개 변수로 제공된 번호를 호출하려고 시도합니다.

    다음 단계에서는 Android 전화 걸기를 사용할 수 있도록 Android 애플리케이션 매니페스트를 업데이트하는 방법을 보여 줍니다. Windows, iOS 및 MacCatalyst에서 애플리케이션은 매니페스트에서 다른 운영 체제 종속 기능을 지정한다는 점을 제외하고 동일한 일반 원칙을 따릅니다.

  2. 솔루션 탐색기 창에서 플랫폼 폴더를 확장하고 Android 폴더를 확장한 다음 AndroidManifest.xml 파일을 마우스 오른쪽 버튼으로 클릭하고 다음으로 열기>자동 편집기 선택기(XML)를 선택합니다. 확인을 선택합니다.

  3. 이 노드의 기존 콘텐츠 뒤에서 매니페스트 노드 안에 다음 XML 코드 조각을 추가합니다.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        ...
        <queries>
            <intent>
                <action android:name="android.intent.action.DIAL" />
                <data android:scheme="tel"/>
            </intent>
        </queries>
    </manifest>
    
  4. 파일을 저장합니다.

  5. Visual Studio 도구 모음에서 Android Emulators/Pixel 3a - API 30(또는 동급) 프로필을 선택하고 디버깅을 시작합니다.

  6. 앱이 에뮬레이터에 나타나면(몇 분 정도 걸릴 수 있음) 전화번호를 입력하거나 기본값을 수락하고 번역을 선택한 다음 통화를 선택합니다.

  7. 전화 걸기 경고에서 를 선택합니다. Android 전화 걸기가 앱에서 제공한 번호와 함께 표시되는지 확인합니다.

    The Android phone dialer containing the number provided by the app.

  8. Visual Studio로 돌아가서 디버깅을 중지합니다.

요약

이 연습에서는 페이지와 보기를 사용하여 사용자 지정 UI를 애플리케이션에 추가했습니다. 또한 Android에서 사용할 수 있는 플랫폼 특정 API를 사용하여 전화를 걸 수 있는 지원을 추가했습니다.