2017년 1월 12일 목요일

Xamarin.Forms DependencyService

Xamarin.Forms를 사용하다보면
Xamarin.Form에서 제공하지 않는 Platform 특화 기능들을 사용해야 할 필요가 있는데
이때 필수적으로 사용해야 하는 것이 Dependency Service임.

Cross Platform App을 만들기 위해
Shared Project 구조를 가진 Xamarin.Forms 프로젝트에서는
어쩔 수 없이 Platform project의 기능을 호출해야 하지만 이는 Shared code project에서 Platform project로의 strong dependency를 가지는 것이라 바람직하지 않음.
그래서 Dependency Service을 이용하면 다소 불편하기 하지만 언급된 문제를 회피하여 필요한 Platform dependent한 기능을 사용할 수 있음.

아래는 Xamarin documentation URL임.

Accessing Native Features with DependencyService
: https://developer.xamarin.com/guides/xamarin-forms/dependency-service/


간단히 보자면 DependencyService를 사용하기 위해서는 다음의 사항들이 필요하다.


DependencyService를 사용하는 Shared code project app 구조는 대충 이런 느낌이다.

App 만들 때 가장 기본적인 Device Orientation을 조회하는 기능을 DependencyService를 사용해서 해결하는 예제를 보면(... 이런것도 Xamarin.Forms에 없다는 것은 뭐.. 그냥.. )

Checking Device Orientation



구조는 대충 이런 느낌이다.

먼저 Shared code project에서 아래와 같이 Interface를 정의한다.
namespace DependencyServiceSample.Abstractions
{
    public enum DeviceOrientations
    {
        Undefined,
        Landscape,
        Portrait
    }

    public interface IDeviceOrientation
    {
        DeviceOrientations GetOrientation();
    }
}

Platform project에서 정의된 IDeviceOrientation에 맞춰 Class를 구현한다.
단 default 생성자 작성을 잊지 말자. default 생성자가 구현되어 있지 않다면 dependency service로 호출 시 exception이 발생한다.

using DependencyServiceSample.Droid;
using Android.Hardware;

namespace DependencyServiceSample.Droid
{
    public class DeviceOrientationImplementation : IDeviceOrientation
    {
        public DeviceOrientationImplementation() { }

        public static void Init() { }

        public DeviceOrientations GetOrientation()
        {
            IWindowManager windowManager = Android.App.Application.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();

            var rotation = windowManager.DefaultDisplay.Rotation;
            bool isLandscape = rotation == SurfaceOrientation.Rotation90 || rotation == SurfaceOrientation.Rotation270;
            return isLandscape ? DeviceOrientations.Landscape : DeviceOrientations.Portrait;
        }
    }
}

DependencyService에 IDeviceOrientation를 구현한 DeviceOrientationImplementation class를 dependency service에 등록을 위해 metadata를 선언하고 Xamarin.Forms의 dependency service의 register를 호출하여 등록한다.

using DependencyServiceSample.Droid; //enables registration outside of namespace
using Android.Hardware;

[assembly: Xamarin.Forms.Dependency (typeof (DeviceOrientationImplementation))]
namespace DependencyServiceSample.Droid {
    ...
Xamarin.Forms.Forms.Init(e, assembliesToInclude);
// register the dependencies in the same
Xamarin.Forms.DependencyService.Register<TextToSpeechImplementation>();

그럼 Shared code project에서 아래와 같이 사용 가능하다. 끝..

public MainPage ()
{
    var orient = new Button {
        Text = "Get Orientation",
        VerticalOptions = LayoutOptions.CenterAndExpand,
        HorizontalOptions = LayoutOptions.CenterAndExpand,
    };
    orient.Clicked += (sender, e) => {
       var orientation = DependencyService.Get<IDeviceOrientation>().GetOrientation();
       switch(orientation){
           case DeviceOrientations.Undefined:
                orient.Text = "Undefined";
                break;
           case DeviceOrientations.Landscape:
                orient.Text = "Landscape";
                break;
           case DeviceOrientations.Portrait:
                orient.Text = "Portrait";
                break;
       }
    };
    Content = orient;
}

댓글 없음:

댓글 쓰기