전체 페이지뷰

2017년 1월 31일 화요일

Chapter 2. Anatomy of an app, part 1

현대 UI는 다양한 종류의 시각 객체로 구성됩니다. OS에 따라 이러한 시각적 개체는 컨트롤, 요소, 뷰, 위젯 등 다른 이름으로 표시 될 수 있지만 모두 프레젠테이션이나 상호 작용 작업에 사용됩니다.



Xamarin.Forms에서 화면에 나타나는 객체를 통칭 "visual element"라고 부르며, 그것들은 세 가지 주요 카테고리로 나뉩니다.

  • page
  • layout
  • view

이것은 결코 추상적 개념이 아닙니다. Xamarin.Forms API(application programming interface)는 VisualElement, Page, Layout, View라는 클래스를 정의하고 있습니다.
이들 클래스와 그 서브클래스는 Xamarin.Forms UI의 골격을 형성하고 있습니다.
VisualElement는 Xamarin.Forms에서도 특히 중요한 클래스입니다. VisualElement 객체는 화면상에 나타나는 것들 전체를 나타냅니다.

Xamarin.Forms 응용 프로그램은 하나 이상의 페이지로 구성됩니다. 일반적으로 페이지는 화면의 전체 (또는 적어도 넓은 영역)를 차지합니다. 여러 페이지를 오가는 앱이 있는 반면에, 어떤 응용 프로그램은 단일 페이지로만 구성되는데, 이 책의 초반 챕터에서는 ContentPage라는 한 유형의 페이지만 볼 수 있습니다.

각 페이지에서 visual element는 parent-child 계층 구조로 구성됩니다. ContentPage의 child는 일반적으로 비주얼을 구성하는 레이아웃입니다. 일부 레이아웃에는 하위 항목이 하나만 존재하지만, 많은 레이아웃에는 여러 개의 child가 있습니다. 이 child는 다른 layout이거나 view일 수 있습니다. 서로 다른 유형의 레이아웃은 child를 스택, 2 차원 그리드 등의 여러 방식으로 정렬합니다. 그러나 이 장에서 우리 페이지는 단 한 명의 child만 포함합니다.

Xamarin.Forms에서 view라는 용어는 여러 형식의 presentation, interaction 객체입니다.(예를 들어 text, bitmap, button, text-entry field, slider, switch, progress bar, date and time picker 등) 그리고 이것들은 다른 OS 상에서는 control이나 widget으로도 불립니다. 이 책에서는 그것들을 통칭하여 view라고 부르겠습니다. 이번 장에서는 텍스트 표시를 위한 Label view를 만나시게 될 겁니다.

Say hello

Visual studio나 Xamarin studio의 standard template 를 사용하여, 새로운 Xamarin.Forms 앱을 생성합니다. 그렇게 하면 여섯 개의 project가 포함된 하나의 솔루션을 생성하게 될겁니다. 여섯개의 포르젝트란 각각 iOS, Android, UWP, Windows 8.1, Windows Phone 8.1의 플랫폼별  프로젝트와, 앱에 있어서 큰 비율을 차지하게 될 common project입니다.

Visual Studio에서는 파일>새로 만들기>프로젝트를 선택하고, 이어서 새 프로젝트 창 왼쪽에서 Visual C#>Cross-Platform을 선택합니다. 그러면 창 가운데에 선택 가능한 여러개의 항목들이 보일 겁니다. 그 중 Xamarin.Forms와 관련된 Blank App은 
  • Blank App (Xamarin.Forms Portable)
  • Blank App (Xamarin.Forms Shared)
  • Class Library (Xamarin.Forms)
Blank App을 골라야 하는 것은 확실한데..어떤 종류의 앱을 골라야 할까요?

자마린 스튜디오의 경우에도 조금 다른 종류이긴 하지만 혼란스럽긴 마찬가지인데, Xamarin Studio에서 새 Xamarin.Forms 앱을 생성하려면 File> New> Solution을 선택하고 New Project 대화창에서 Multiplaform 아래에 있는 App을 선택하고, Forms App을 고른 후 Next를 누릅니다.

다음 화면 하단에는 Shared Code라는 버튼이 있습니다. 이 버튼을 사용하여 다음 옵션 중 하나를 선택할 수 있습니다.
  • Use Portable Class Library
  • Use Shared Library
이 글에서 "Portable"이라는 용어는 PCL(Portable Class Library)을 의미합니다. 모든 공통 application 코드는, 모든 개별 플랫폼 프로젝트에서 참조하는 동적 연결 라이브러리 (DLL)가 됩니다.

그리고, "Shared"라는 단어는 SAP(Shared Asset Project)로서, 개별 플랫폼 간에 공유되는 루즈한 코드 파일을 의미합니다.

지금 단계에서는, Visual Studio의 Blank App (Xamarin.Forms Portable) ,또는 Xamarin Studio라면 Use Portable Class Library을 선택하십시오. 프로젝트에 이름을 지정하십시오 (예 : Hello). 대화 상자 (Visual Studio의 경우) 또는 Xamarin Studio에서는 Next 버튼을 다시 누른 후 나타나는 대화 상자에서 저장 위치를 선택하십시오.

Visual Studio에서는 5개의 개별 플랫폼 프로젝트와 한개의 공통 프로젝트(PCL), 총 6개의 프로젝트가 포함된 한 개의 솔루션이 Hello라는 이름으로 생성될 겁니다.

  • Hello : PCL 프로젝트
  • Hello.Droid : 안드로이드용
  • Hello.iOS : iOS용
  • Hello.UWP  : Windows 10, Windows Mobile 10용
  • Hello.Windows : Windows 8.1용
  • Hello.WinPhone : Windows Phone 8.1 용
(맥에서 자마린 스튜디오를 구동하는 경우 Windows와 Windows Phone 프로젝트는 생성되지 않습니다)

새로운 Xamarin.Forms 솔루션을 만들면, Xamarin.Forms 라이브러리 (및 다양한 지원 라이브러리)가 NuGet 패키지 관리자에 의해 자동으로 다운로드됩니다. Visual Studio와 Xamarin Studio는 이러한 라이브러리를 솔루션 디렉토리의 packages 디렉토리에 저장합니다. 다운로드 된 Xamarin.Forms 라이브러리의 특정 버전은 솔루션 템플릿에 국한되며 최신 버전을 사용할 수 있습니다.

Visual Studio의 화면 오른쪽 끝에있는 솔루션 탐색기에서 솔루션 이름을 우클릭하고 솔루션에 대한 솔루션용 NuGet 패키지 관리를 선택합니다. 나타난 대화 상자 왼쪽에는 NuGet 패키지가 설치되어 있는지 확인하고 다른 패키지를 설치할 수 있는 항목이 있습니다. Update 항목을 선택하여 Xamarin.Forms 라이브러리를 업데이트 할 수도 있습니다.

Xamarin Studio에서는, Solution 목록의 솔루션 이름 오른쪽에 있는 도구 아이콘을 선택하고 Update NuGet Packages를 선택할 수 있습니다.

진도를 나가기 전에 프로젝트 설정이 올바른지 확인해 봅시다.
Visual Studio에서는 빌드>구성 관리자를 선택합니다. 관리자 창이 나타나면 6개의 프로젝트가 보일 겁니다. 빌드 상자가 전부 체크 되어 있는지 확인하고, 배포의 경우 회색으로 아웃처리된 것들 외에는 전부 체크 되었는지 확인합니다.

다음으로 Platform 줄에 속한 것들을 확인합니다.
HelloHello.DroidAny CPU로 표시되어야 합니다(Any CPU가 유일한 옵션입니다).
Hello.iOS는 원하는 환경에 따라 iPhoneiPhoneSimulator 중 선택하십시오.
Hello.UWP에서 윈도우 데스크탑용이나 스크린 에뮬레이터를 사용 배포시에는 x86, 전화용 배포를 원할 때에는 ARM을 선택합니다.
Hello.WinPhone의 경우, 스크린 에뮬레이터 사용시 x86, 실제 폰에 배포시 ARM, 둘 다라면 Any CPU를 선택합니다.

프로젝트가 Visual Studio에서 컴파일되거나 배포되지 않는 것 같으면 구성 관리자(Configuration Manager) 대화 상자에서 설정을 다시 확인하십시오. 때로는 다른 구성이 활성화되어 PCL 프로젝트가 포함되지 않을 수 있습니다.

Mac에서 Xamarin Studio를 사용하는 경우, Project> Active Configuration 메뉴 항목을 통해 iPhone과 iPhone 시뮬레이터로의 배포 사이를 전환 할 수 있습니다.

Visual Studio에서 iOS와 Android toolbar를 표시할 수 있습니다. 이 툴바를 이용하여 실 기기, 에뮬레이터 사이를 전환할 수 있습니다. 메인 메뉴에서 보기>도구 모음>iOS보기>도구 모음>Android가 체크되어 있는지 확인하십시오.

이 솔루션에는 2개에서 6개의 프로젝트가 포함되어 있으므로, application을 실행하거나 디버깅하도록 선택할 때 시작할 프로그램을 골라주어야 합니다.

Visual Studio의 솔루션 탐색기에서 다섯 개의 응용 프로그램 프로젝트 중 하나를 마우스 오른쪽 단추로 클릭하고 메뉴에서 시작 프로젝트로 설정 항목을 선택합니다. 그런 다음 에뮬레이터 또는 실제 장치에 배포하도록 선택할 수 있습니다. 프로그램을 빌드하고 실행하려면 메인 메뉴에서 디버그> 디버깅 시작 항목을 선택하십시오.

Xamarin Studio 사용 시, Solution 목록에서 선택한 프로젝트의 오른쪽에 나타나는 작은 도구 아이콘을 클릭하고 메뉴에서 Set As A Startup Project를 선택합니다. 그런 다음 주 메뉴에서 Run>Start Debugging을 선택할 수 있습니다

모든 것이 문제없이 잘 되었다면, 템플릿의 skeleton 앱이 실행되고 짧은 메세지를 볼 수 있을 겁니다.


보시다시피,이 플랫폼들은 색상 구성이 다릅니다. iOS 및 Windows 10 Mobile 화면은 밝은 배경에 어두운 텍스트를 표시하고, Android 장치는 검정색 배경에 밝은 텍스트를 표시합니다. 기본적으로 Windows 8.1 및 Windows Phone 8.1 플랫폼은 Android와 같습니다.

기본적으로 모든 플랫폼에서 방향을 변경할 수 있습니다. 휴대 전화를 옆으로 돌리면 텍스트가 새 센터에 맞게 조정됩니다.

앱을 기기나 에뮬레이터에서 실행시키는 것을 넘어 배포도 가능합니다. 그것은 전화 또는 에뮬레이터에 다른 app과 함께 나타나고 거기에서 실행할 수 있습니다. 응용 프로그램 아이콘이나 응용 프로그램 이름이 마음에 들지 않으면 개별 플랫폼 프로젝트에서 변경할 수 있습니다.

Inside the files

Xamarin.Forms 템플릿에 의해 생성된 프로그램은 매우 간단하므로, 생성된 코드 파일을 검사하고 상호 관계 및 작동 방식을 파악하기에 좋습니다.

위의 화면에서 보는 텍스트를 출력하는 코드부터 시작하겠습니다. 이것은 Hello 프로젝트의 App 클래스입니다. Visual Studio에서 만든 프로젝트에서 App 클래스는 App.cs 파일에 정의되어 있지만 Xamarin Studio에서는 Hello.cs 파일입니다. 이 장이 작성된 이후로 프로젝트 템플릿이 너무 많이 변경되지 않았다면 다음과 같이 보일 것입니다 :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
namespace Hello
{
    public class App : Application
    {
        public App()
        {
            // The root page of your application
            var content = new ContentPage
            {
                Title = "Hello",
                Content = new StackLayout
                {
                    VerticalOptions = LayoutOptions.Center,
                    Children = {
                        new Label {
                            HorizontalTextAlignment = TextAlignment.Center,
                            Text = "Welcome to Xamarin Forms!"
                        }
                    }
                }
            };
            MainPage = new NavigationPage(content);
        }
        protected override void OnStart()
        {
            // Handle when your app starts
        }
        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }
        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}
cs

네임 스페이스는 프로젝트 이름과 같습니다. 이 App 클래스는 public으로 정의되며, Xamarin.Forms Application 클래스에서 파생됩니다. 생성자는 Application 클래스의 MainPage 속성을 Page 타입의 오브젝트로 설정하기만 하면 됩니다.


Xamarin.Forms 템플릿이 만든 이 코드는, 생성자를 정의하는 매우 간단한 방법을 보여줍니다. ContentPage 클래스는 Page에서 파생되며 단일 페이지 Xamarin.Forms 응용 프로그램에서 널리 쓰입니다.

ContentPage는 안드로이드 화면 상단의 상태 바, 하단의 버튼, 또는 윈도우폰의 상단 상태바를 제외한 폰 화면의 거의 대부분을 차지합니다(차차 보게 되겠지만 iOS의 상태 바는 단일 페이지 앱에서 ContentPage의 일부입니다).

ContentPage 클래스는 Content라는 프로퍼티를 정의하고 Content는 페이지 내용을 정의하는데 쓰입니다. 일반적으로 이 content는 여러 개의 뷰를 포함하는 레이아웃이며, 이 경우 StackLayout으로 설정되어 스택에 자식을 정렬합니다.

StackLayout에는 child가 하나인데, 그것이 Label입니다. Label 클래스는 View에서 파생되며 Xamarin.Forms 응용 프로그램에서 텍스트 단락까지 표시하는 데 사용됩니다. VerticalOptionsHorizontalTextAlignment 속성은 이 장의 뒷부분에서 자세히 설명합니다.

단일 페이지 Xamarin.Forms 응용 프로그램을 만드는 경우, 일반적으로 ContentPage에서 파생된 자체 클래스를 정의하게 됩니다. 그런 다음 App 클래스의 생성자는 정의한 클래스의 인스턴스를 MainPage 속성으로 설정합니다. 곧 이것이 어떻게 작동하는지 보게 될 것입니다.

Hello 솔루션에는 PCL을 생성하는 AssemblyInfo.cs 파일과, 프로그램에서 요구하는 NuGet 패키지가 포함 된 packages.config 파일도 표시됩니다. 솔루션 목록의 Hello 아래에 있는 참조 섹션에는 이 PCL에 필요한 최소 네 개 이상의 라이브러리가 표시됩니다.

  • .NET(Xamarin Studio에서는 .NET Portable Subset)
  • Xamarin.Forms.Core
  • Xamarin.Forms.Platform
  • Xamarin.Forms.Xaml

Xamarin.Forms app을 작성할 때 많은 관심 두어야 하는 것이 이 PCL 프로젝트 입니다. 경우에 따라서 이 프로젝트의 코드는 다양한 플랫폼에 맞게 조정해야 할 수도 있는데, 곧 그 방법에 대해서도 알아 보겠습니다. 다섯 개의 응용 프로그램 프로젝트에 platform-specific 코드를 포함시킬 수도 있습니다.

이 다섯 개의 프로젝트는 각자 아이콘이나 메타데이터 형태의 asset을 가지고 있고, 앱을 출시하려는 경우에는 특별히 관심을 두어야 겠지만, 앱 만드는 공부를 하는 동안에는 asset을 무시하도록 하겠습니다.

개별 앱의 참조 섹션에는 공통 PCL 프로젝트(여기서는 Hello)말고도 .NET 어셈블리, 아래에 열거된 Xamarin.Forms 어셈블리 등 많은 항목들이 존재합니다.


  • Xamarin.Forms.Platform.Android
  • Xamarin.Forms.Platform.iOS
  • Xamarin.Forms.Platform.UAP (UWP 프로젝트에 명시적으로 표시되진 않음)
  • Xamarin.Forms.Platform.WinRT
  • Xamarin.Forms.Platform.WinRT.Tablet
  • Xamarin.Forms.Platform.WinRT.Phone

각 라이브러리는 해당 플랫폼에 대한 Xamarin.Forms 시스템을 초기화하는 Xamarin.Forms 네임 스페이스에서 정적(static) Forms.Init 메서드를 정의합니다. 각 플랫폼의 시작 코드는 이 메서드를 호출해야 합니다.

여러분은 이미 PCL 프로젝트가 Application에서 파생 된 App이라는 공용 클래스를 파생시킨 것도 보았습니다. 각 플랫폼의 시작 코드는 이 App 클래스도 인스턴스화해야합니다.

iOS, Android 또는 Windows Phone 개발에 익숙한 사람은, 플랫폼 시작 코드가 이러한 작업을 처리하는 방법을 알고 싶을 것입니다.

the iOS project

iOS 프로젝트는 일반적으로 UIApplicationDelegate에서 파생된 클래스를 포함합니다. 그러나 Xamarin.Forms.Platform.iOS 라이브러리는 FormsApplicationDelegate라는 대체 기본 클래스를 정의합니다. Hello.iOS 프로젝트에서 이 AppDelegate.cs 파일을 볼 수 있습니다. 아래 코드는 거기에서 불필요한 지시문과 주석들을 제거한 모습입니다.

using Foundation;
using UIKit;
 
namespace Hello.iOS
{    
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {       
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
 
            return base.FinishedLaunching(app, options);
        }
    }
}
cs

FinishedLaunching 오버 라이드는 Xamarin.Forms.Platform.iOS 어셈블리에 정의된 Forms.Init 메서드를 호출함으로써 시작합니다. 그런 다음 FormsApplicationDelegate에 정의 된 LoadApplication 메서드를 호출하여, shared PCL의 Hello 네임 스페이스에 정의된 App 클래스의 새 인스턴스를 넘겨줍니다. 이 App 객체의 MainPage 프로퍼티에 넘겨진 page객체는 UIViewController 객체를 만드는게 사용되고, UIViewController는 페이지 내용을 렌더링합니다.

the Android project

Android 앱에서, MainActivity 클래스는 Xamarin.Forms.Platform.Android 어셈블리에 정의 된 FormsApplicationActivity라는 Xamarin.Forms 클래스에서 파생되어야 하며 Forms.Init 호출에는 몇 가지 추가 정보가 필요합니다.

using Android.App;
using Android.Content.PM;
using Android.OS;
 
namespace Hello.Droid
{
    [Activity(Label = "Hello", Icon = "@drawable/icon", Theme = "@style/MainTheme"
        MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {            
            base.OnCreate(bundle);
 
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    }
}
cs

Hello 네임스페이스에 존재하는 App 클래스의 새 인스턴스는 FormsApplicationActivity에 정의된 LoadApplication 메서드에 전달됩니다. MainActivity 클래스에 설정된 attribute는 전화기가 방향을 변경 (세로에서 가로로 또는 뒤로)하거나 화면의 크기가 바뀔 때 다시 활성화가 되지 않는다는 것을 의미합니다.

the Universal Windows Platform project

UWP 프로젝트 (또는 두 Windows 프로젝트 중 하나)에서 프로젝트 파일 목록의 App.xaml 파일 하위에 있는 App.xaml.cs 파일을 먼저 살펴보십시오.  OnLaunched 메서드에서 event argument를 사용하여 Forms.Init을 호출한 것을 볼 수 있습니다.

Xamarin.Forms.Forms.Init(e);

다음으로 프로젝트 파일 목록의 MainPage.xaml 파일 하위에 있는 MainPage.xaml.cs 파일을 살펴보십시오. 이 파일은 일반적인 MainPage 클래스를 정의하지만 실제로는 MainPage.xaml 파일의 루트 요소로 지정된 Xamarin.Forms 클래스에서 파생됩니다. 새로 인스턴스화 된 App 클래스는 이 기본 클래스에서 정의한 LoadApplication 메서드에 전달됩니다.

namespace Hello.UWP
{
    public sealed partial class MainPage
    {
        public MainPage()
        {
            this.InitializeComponent();
 
            LoadApplication(new Hello.App());
        }
    }
}
cs

Nothing special!

Visual Studio에서 Xamarin.Forms 솔루션을 만든 후, 원치 않는 플랫폼이 있다면 해당 프로젝트를 삭제하면 됩니다.

나중에 마음이 바뀌어 새 플랫폼을 추가하고 싶을 때는 솔루션에 원하는 프로젝트를 추가할 수 있습니다. 새 프로젝트 추가 대화 상자에서 iOS 프로젝트 Universal>Blank App 템플릿을 선택하여 Unified API (Classic API 아님) Xamarin.iOS 프로젝트를 만들 수 있습니다. Android Blank App 템플리트로 Xamarin.Android 프로젝트를 만들 수 있고,  창>Universal (UWP 프로젝트의 경우)을 선택하거나 창>Windows 8>Windows 또는 창>Windows 8>Windows Phone을 선택한 다음 비어 있는 앱을 선택하여 Windows 프로젝트도 추가할 수 있습니다.

이러한 새 프로젝트의 경우 표준 Xamarin.Forms 템플릿으로 생성된 프로젝트를 참조하여 올바른 참조와 상용구 코드를 얻을 수 있습니다.

요약 : Xamarin.Forms 라이브러리를 제외하고, Xamarin.Forms 앱은 일반적인 Xamarin 또는 Windows Phone 프로젝트와 비교할 때 특별한 것이 없습니다.


댓글 없음:

댓글 쓰기