빠르고 유연한 앱 시작 환경 만들기

Windows 8 앱 개발자 블로그

Windows 8 엔지니어링 팀에서 제공하는 Windows 8용 Metro 스타일 앱 개발의 이해

빠르고 유연한 앱 시작 환경 만들기

  • Comments 0

앱 실행은 빠르고 유연한 Windows 8 경험의 중요한 요소이므로 앱의 시작 UX에 우선순위를 두는 것은 앱 개발에 있어 중요합니다. 매끄럽게 잘 시작하는 앱은 첫인상이 좋을 수밖에 없습니다. 이 글에서는 디자인이 뛰어나고 응답성이 좋은 앱 시작 환경을 제작하는 방법을 알아보고 앱 시작 순간이 사용자에게 좋은 인상을 주는 데 중요하게 작용하는 이유를 설명합니다. 앱에 적용할 수 있는 네 가지 앱 시작 디자인 패턴을 소개하고 Metro 스타일 앱을 개발할 때 유의해야 할 몇 가지 주의 사항도 짚어봅니다.

앱 시작 개요

라이브 앱을 위한 앱 수명 주기 관리 글을 이미 읽었다면 앱 수명 주기 상태에 대해서 잘 알고 있을 것입니다. 이 글에서는 앱 시작 또는 "실행 중 아님" 상태와 "실행 중" 상태 간의 전환을 다룹니다.

앱 시작이 전체 Metro 스타일 앱 수명 주기에서 차지하는 부분: 앱 시작은 "실행 중 아님" 상태에서 "실행 중" 상태로의 전환
  수명 주기 상태: 앱 시작은 "실행 중 아님" 상태에서 "실행 중" 상태로의 전환

앱 시작은 시각적으로 확연히 드러나기 때문에 이 전환을 잘 계획하는 것이 중요합니다. 전체 수명 주기에서 중요한 위치를 차지할 뿐 아니라 사용자가 반복적으로 경험하게 되는 단계이기도 합니다. 계약을 많이 구현할수록(이전 글: 앱에서 Windows 8 계약 활성화하기 참조) 사용자가 앱을 시작하게 될 기회도 그만큼 많아집니다. 이러한 전환을 어떻게 디자인하는지에 따라 앱의 첫인상은 물론, 결국에 사용자가 앱을 자주 사용하게 될지 여부가 결정됩니다.

앱 시작을 처리하는 몇 가지 방법을 소개하기 전에 이 전환 과정에서 이루어지는 작업의 순서를 살펴보도록 하겠습니다.

사용자가 앱의 타일을 클릭하면 앱이 활성화되고 시작 화면이 표시됩니다. 시작 애니메이션이 끝나면 앱에서 창이 열릴 때까지 시작 화면이 전체 화면으로 표시됩니다. 창이 열릴 때 시작 화면은 앱의 첫 번째 보기로 서서히 사라집니다.  앱 시작 시 작업 순서

사용자가 앱을 시작하면 바로 시작 화면이 나타납니다. 모든 Metro 스타일 앱에는 620x300 크기의 이미지와 단색 배경으로 구성된 시작 화면이 있습니다. 시작 화면을 사용자 지정하는 방법은 Quickstart: Adding a splash screen을 참조하십시오. 앱이 활성화되는 동안 사용자를 환영하는 의미로 여러분을 대신해 Windows가 대신 시작 화면으로 인사를 하는 셈입니다. 시작 시에 모든 앱은 activated 이벤트를 받게 되는데, 이 이벤트는 앱이 초기 UI를 제공하는 데 필요한 초기화 작업을 수행할 수 있게 해 줍니다. 초기화 작업에는 기본 설정을 읽고, 이동할 페이지를 결정하고, 다양한 계약 중에서 어느 계약에 대해 앱이 활성화되었는지를 식별하는 것 등이 포함됩니다. 초기화가 끝나면 시작 화면은 더 이상 필요하지 않게 되고 앱에서 첫 번째 창을 제공해야 합니다. JavaScript 앱의 경우 활성화 콜백이 반환될 때 초기화가 자동으로 이루어지기 때문에 따로 작업을 구현할 필요가 없습니다. 반면 C# 앱의 경우에는 Window.Current.Activate에 대한 호출을 통해 명시적으로 초기화 작업을 실행해야 합니다. 일정 시간(15초 이내) 내에 창이 표시되지 않으면 앱이 종료되므로 이 작업을 지연시키지 않도록 주의해야 합니다. 게다가 시작 화면을 불필요하게 오래 표시하면 사용자의 호감이 급격히 떨어지므로 가급적 빨리 창을 표시해야 합니다. 창을 2-3초 내에 표시하여 로우엔드급 하드웨어에서도 항상 사용자의 기대치에 맞게 앱이 시작되도록 하는 것이 좋습니다.

앱의 창이 표시되고 나면 시작 화면은 사라지고 앱이 환경을 제어하게 됩니다. 사용자에게 앱의 콘텐츠를 어떻게 선보일지는 개발자가 결정합니다. 앱에 따라 다른 전환 방식을 사용할 수 있습니다. 다음 몇 개 섹션에서는 앱의 요구 사항을 기준으로 적용할 수 있는 네 가지 앱 시작 디자인 패턴을 소개하겠습니다.

  • 기본 앱 시작

추가 로딩이 필요 없고 즉시 사용할 수 있는 앱에 적합합니다.

예: 사용자가 여러 가지 용어를 검색하거나 번역할 수 있는 사전 앱이 여기에 해당합니다. 방문 페이지는 사용자 입력을 위한 텍스트 상자로만 구성됩니다.

  • 골격형 앱 시작

시작 시에 방문 페이지가 점진적으로 채워지는 앱에 적합합니다.

예: 사용자의 서적, 잡지, 신문을 추적하는 구독 앱이 여기에 해당합니다. 앱을 시작하면 사용자의 라이브러리가 점진적으로 채워집니다.

  • 확장형 앱 시작

UI가 표시될 때까지 로딩 작업이 오래 걸리는 앱에 적합합니다. 로딩 작업에는 네트워크 호출이나 후속 파일 I/O 작업 등이 포함될 수 있습니다.

예: 최신 경기 결과와 주요 경기 내용을 보여 주는 스포츠 앱이 여기에 해당합니다. 이러한 앱은 REST API를 사용하여 네트워크에서 정보를 검색한 후 방문 페이지에 라이브 데이터를 표시합니다.

  • 지연형 앱 시작

시작 시에 앱 설정을 쿼리하여 최초 실행을 위한 설정을 확인하는 등의 기본 비동기 작업을 실행해야 하는 앱에 유용합니다.

예: 사용자가 이미 계정을 생성했는지를 확인해야 하는 게임이 여기에 해당합니다. 이 정보는 사용자에게 표시할 페이지를 결정하는 데 필요합니다.

기본 앱 시작

기본 앱 시작 흐름이 적합한 앱이 많습니다. 이 흐름에서는 Windows가 각 앱의 시작 화면을 표시하고 제거하는 작업을 처리합니다. 활성화가 끝나고 창이 나타나 앱의 방문 페이지로 전환하는 애니메이션 크로스페이드가 트리거될 때까지 시작 화면이 표시됩니다. 방문 페이지가 정적이고 추가 로딩 작업이 필요 없는 경우 기본 시작 방식을 사용하십시오. 콘텐츠가 곧바로 준비된다면 일부러 사용자의 환경을 지연시킬 필요가 없습니다. 사실, 그래서는 안 됩니다.

아래는 Consumer Preview에서 소개된 Internet Explorer 10을 사용한 기본 시작 흐름의 예입니다. 앱이 시작되면 시작 화면이 사용자에게 즉시 표시됩니다. 앱이 활성화될 때까지 시작 화면이 표시되고 앱이 활성화되면 시작 화면이 사라지면서 방문 페이지가 나타납니다. 이 예에서는 방문 페이지에 이전에 사용자가 방문했던 페이지가 나타납니다. 이러한 페이지는 이전 세션에서 저장되기 때문에 바로 사용할 수 있습니다.

아래 이미지에 나와 있는 프로세스는 다음과 같습니다.

  1. 사용자가 앱 타일을 클릭합니다.
  2. 시작 화면이 표시됩니다.
  3. 앱 방문 페이지가 표시됩니다.

타일을 클릭하면 시작 화면이 표시됩니다. 그리고 앱의 첫 번째 보기가 준비되면 시작 화면이 사라지고 앱의 방문 페이지가 나타납니다. 
기본 앱 시작 흐름

기본 시작 흐름을 구현할 때는 추가 작업이 필요 없습니다. 앱의 매니페스트에 620x300 시작 화면 이미지를 지정하고 정적 콘텐츠를 사용하여 방문 페이지를 디자인하기만 하면 됩니다. 활성화가 끝나면 시작 화면이 사라지고 방문 페이지가 나타나며 앱을 사용할 준비가 끝납니다.

골격형 앱 시작

대부분의 앱에는 기본 시작 방식을 사용하면 됩니다. 시작 화면이 사라지고 나면 바로 앱이 실행되고 사용자가 조작할 준비가 되는 식입니다. 하지만 시작 후에 콘텐츠를 동적으로 로드해야 하기 때문에 이 시점에 완전하게 준비가 되지 않는 앱도 있습니다. 이러한 종류의 앱의 경우 골격형 앱 시작 패턴을 사용해 앱을 최대한 신속하게 실행하면서 사용자에게 유용한 로딩 정보를 제공하는 것이 적합합니다. 이 패턴에서는 콘텐츠를 검색하는 동안 시작 화면이 골격 방문 페이지(콘텐츠가 없는 모습의 방문 페이지)로 전환됩니다. 이 경우 페이지에 진행률 표시줄을 추가하여 앱이 로드 중임을 나타낼 수 있습니다. 아래 이미지에서는 Consumer Preview에서 소개된 음악 앱을 사용하여 골격형 시작 흐름의 예를 보여 줍니다. 이 예에서는 최신 음악 콘텐츠를 검색하는 동안 골격 방문 페이지가 표시됩니다.

아래 이미지에 나와 있는 프로세스는 다음과 같습니다.

  1. 사용자가 앱 타일을 클릭합니다.
  2. 시작 화면이 표시됩니다.
  3. 골격 방문 페이지가 표시됩니다. 보기의 위쪽에 진행률 표시줄이 표시됩니다.
  4. 앱 방문 페이지가 표시됩니다.

타일을 클릭하면 시작 화면이 표시됩니다. 그런 다음 앱의 첫 번째 보기로 골격 방문 페이지가 나타납니다. 골격 방문 페이지란 콘텐츠가 없는 방문 페이지를 말합니다. 시작 화면이 골격 방문 페이지로 전환되면 앱이 점진적으로 페이지를 채우기 시작합니다.  골격형 앱 시작 흐름

골격형 시작 흐름을 구현하려면 앱 방문 페이지의 정적인 골격 보기를 만들어 시작 페이지로 표시합니다. 그런 다음 활성화하는 동안 콘텐츠가 없는 페이지를 채우는 데 필요한 로딩 작업을 시작합니다. 작업은 대부분 비동기로 실행되기 때문에 작업을 실행하는 동안 시작 화면이 부분적으로 표시될 수 있습니다. 즉, 사용자는 방문 페이지가 점진적으로 채워지는 모습을 보게 됩니다.

시작 화면이 언제 사라지는지를 알아보려면 시작 화면 API를 사용해보십시오. 이 API에는 시작 화면에서 앱 시작 페이지로의 전환이 언제 이루어지는지를 나타내는 SplashScreen.Dismissed 이벤트가 포함되어 있습니다. 이 이벤트는 골격형 방문 페이지가 표시되는 시점을 파악하는 데 유용합니다.

JavaScript

다음 예에서 살펴보겠지만 앱은 방문 페이지를 채우는 작업을 활성화된 콜백 내에서 시작할 수 있습니다. 시작 화면이 언제 사라지는지를 알아보려면 activated 이벤트 인수를 사용하여 splash screen 개체를 가져오십시오. 이 개체를 사용하면 dismissed 이벤트의 레지스터에 시작 화면의 해제 사실이 통보됩니다.

app.onactivated = function (eventArgs) {
if (eventArgs.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
// Begin executing setup operations.
performSetupTasks();

// Retrieve splash screen object.
var splash = eventArgs.detail.splashScreen;

// Register an event handler to be executed when the splash screen has been dismissed.
splash.addEventListener("dismissed", onSplashScreenDismissed, false);
...
}
};

function performSetupTasks() {
// Begin additional loading tasks here…
...
}

function onSplashScreenDismissed() {
// The splash screen has dismissed and the skeleton landing page is now in view.
...
}

C#

C#에서도 구현 방법은 동일합니다. 활성화하는 동안 방문 페이지를 채우는 데 필요한 작업을 시작합니다. 그런 다음 필요한 경우 activated 이벤트 인수에서 splash screen 개체를 가져옵니다. 그러면 시작 화면이 해제된 사실이 레지스터에 통보됩니다.

async protected override void OnLaunched(LaunchActivatedEventArgs args)
{
// Begin executing setup operations.
PerformSetupTasks();

// Retrieve splash screen object.
SplashScreen splashScreen = args.SplashScreen;

// Register an event handler to be executed when the splash screen has been dismissed.
splashScreen.Dismissed += new TypedEventHandler<SplashScreen, object>(eSplash.onSplashScreenDismissed);
...
}

internal void PerformSetupTasks()
{
// Begin additional loading tasks here…
...
}

internal void onSplashScreenDismissed(Windows.ApplicationModel.Activation.SplashScreen sender, object e)
{
// The splash screen has dismissed and the skeleton landing page is now in view.
...
}

확장형 앱 시작

시작 후에 로딩 작업을 추가로 실행하는 앱의 경우 골격형 앱 시작 방식이 적합합니다. 그런데 이 방식에는 단점이 하나 있습니다. 사용자가 바로 "골격" 페이지로 이동하기 때문에 전체적인 로딩 흐름이 일관성 없게 느껴질 수 있습니다. 시작 화면에서 골격 방문 페이지로의 전환 과정이 개별적인 로딩 작업이 두 부분으로 이루어진다는 인상을 줄 수 있는 것입니다. 이러한 단점이 문제가 되는 경우에는 확장형 앱 시작 패턴이 좋은 대안이 됩니다.

이 흐름에서는 '확장' 시작 화면이라는 개념을 사용하여 일체감 있는 하나의 로딩 환경을 만듭니다. 일반적인 시작 화면이 사라지면 앱에서 방문 페이지 대신 확장 시작 화면을 표시합니다. 확장 시작 화면은 온전히 앱에 포함된 것으로, 시작 화면 API를 사용하여 서식이 지정됩니다. 이 API는 확장 시작 화면이 시각적으로 시작 화면과 일치하는 모양과 느낌으로 표시(진행률 링 또는 로딩 정보는 예외)되도록 하는 위치 지정 정보를 제공합니다. 따라서 각각 별개인 것처럼 보이는 로딩 작업이 일체감 있게 바뀝니다. 확장 시작 화면이 표시되는 동안 앱은 방문 페이지를 채우는 데 필요한 작업을 계속 실행할 수 있습니다. 그리고 로딩이 완료되면 확장 시작 화면을 방문 페이지로 전환하면 됩니다.

확장형 시작 흐름은 초기화하는 데 시간이 오래 걸리는 경우(예: 네트워크 연결 상태가 불안정한 경우)에 특히 유용합니다. 시작 시에 어떤 식으로든 '복잡한 작업'을 실행해야 할 때는 확장 시작 화면을 선택하는 것이 이상적입니다. 또한 방문 페이지가 완전하게 업데이트된 상태로 전환되게 하려는 경우(캐시된 데이터를 표시하지 않으려는 경우)에도 적합합니다.

아래 예에서는 Windows 8 Consumer Preview에서 소개된 날씨 앱을 사용하여 확장형 시작 흐름을 보여 줍니다. 날씨 앱의 경우 네트워크에서 최신 날씨 데이터를 요청하는 동안 확장 시작 화면을 표시하면 되기 때문에 확장형 시작 패턴을 구현할 앱의 좋은 예가 됩니다. 캐시된 사용자 날씨 데이터에는 표시할 값이 별로 없기 때문입니다.

아래 이미지에 나와 있는 프로세스는 다음과 같습니다.

  1. 사용자가 앱 타일을 클릭합니다.
  2. 시작 화면이 표시됩니다.
  3. 진행률 링이 있는 확장 시작 화면이 표시됩니다.
  4. 앱 방문 페이지가 표시됩니다.

타일을 클릭하면 시작 화면이 표시됩니다. 그런 다음 앱의 첫 번째 보기로 확장 시작 페이지가 나타납니다. 확장 시작 화면은 시각적으로 시작 화면과 동일하지만 앱에서 처리한다는 점이 다릅니다. 이런 식으로 앱은 로딩 작업을 시작하고 준비되었을 때 실제 방문 페이지로 전환할 수 있습니다. 
확장형 앱 시작 흐름

확장형 시작 흐름을 구현하려면 시작 화면 API를 사용해야 합니다. 앱에서는 SplashScreen.ImageLocation을 사용하여 시작 화면 이미지의 좌표를 가져올 수 있습니다. 확장 시작 화면에서도 이미지가 정확히 동일한 위치에 배치되어야 사용자에게 전환 과정이 부드럽게 나타나기 때문에 이 단계는 매우 중요합니다. 이전 섹션에서 언급했듯이 이 API는 일반 시작 화면에서 확장 시작 화면으로 전환된 사실을 알리는 SplashScreen.Dismissed 이벤트도 노출합니다.

이전과 마찬가지로 활성화하는 동안 추가 작업을 트리거할 수 있습니다. 다음에서는 JavaScript와 C#에서 진행률 링을 선택적으로 사용하여 확장 시작 화면을 구현하는 과정을 살펴보겠습니다.

참고: 확장 시작 화면을 구현할 때는 맞추기, 맞춤 해제, 회전 등을 처리하는 것도 중요합니다. 이 글에서는 편의상 이러한 자세한 구현 방법은 생략합니다. 자세한 내용은 Splash screen sample을 참조하시기 바랍니다.

JavaScript

먼저 진행률 링이 있는 확장 시작 화면의 HTML 마크업을 시작 페이지에 추가합니다.

<div id="extendedSplashScreen" class="extendedSplashScreen hidden">
<img id="extendedSplashImage" src="/images/splash.png" style="position: absolute;" />
<progress id="extendedSplashProgress" style="color: white;" class="win-medium win-ring"></progress>
</div>
 

다음으로 확장 시작 화면의 CSS 스타일을 추가합니다.

.extendedSplashScreen {
position: absolute;
text-align: center;
background-color: #000000;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
}
.extendedSplashScreen.hidden {
display: none;
}

여기서도 마찬가지로 활성화하는 동안 추가 작업을 시작하려면 activated 이벤트 인수를 사용하여 splash screen 개체를 가져옵니다. 이때 dismissed 이벤트를 등록하고 확장 시작 화면을 설정하는 데 splash screen 개체가 사용됩니다. screen object 개체에서 시작 화면 이미지의 위치를 쿼리하고 그에 따라 레이아웃을 구성합니다.

app.onactivated = function (eventArgs) {
if (eventArgs.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
// Begin executing setup operations.
performSetupTasks();

// Retrieve splash screen object.
var splash = eventArgs.detail.splashScreen;

// Register an event handler to be executed when the regular splash screen has been dismissed.
splash.addEventListener("dismissed", onSplashScreenDismissed, false);

// Display the extended splash screen.
displayExtendedSplash(splash);

WinJS.UI.processAll();
}
};

function displayExtendedSplash(splash) {
// Position the extended splash screen image in the same location as the system splash screen image.
var extendedSplashImage = document.getElementById("extendedSplashImage");
extendedSplashImage.style.top = splash.imageLocation.y + "px";
extendedSplashImage.style.left = splash.imageLocation.x + "px";
extendedSplashImage.style.height = splash.imageLocation.height + "px";
extendedSplashImage.style.width = splash.imageLocation.width + "px";

// Position the extended splash screen's progress ring.
var extendedSplashProgress = document.getElementById("extendedSplashProgress");
extendedSplashProgress.style.marginTop = splash.imageLocation.y + splash.imageLocation.height + 32 + "px";

// After the extended splash screen is set up,
// apply the CSS style that will make the extended splash screen visible.
var extendedSplashScreen = document.getElementById("extendedSplashScreen");
WinJS.Utilities.removeClass(extendedSplashScreen, "hidden");
}

확장 시작 화면을 표시하는 동안 실행할 로딩 작업을 지정합니다. 로딩이 완료되면 확장 시작 화면을 제거합니다. 오류 상황이 올바르게 처리되도록 하십시오. 로딩 작업이 시간 초과되거나 실패하면 사용자에게 상황을 설명하는 페이지로 전환합니다.

function performSetupTasks() {
// Begin additional loading tasks here…
...

// Tear down the extended splash screen after all operations are complete.
removeExtendedSplash();
}

function onSplashScreenDismissed() {
// The splash screen has been dismissed and the extended splash screen is now in view.
...
}

function removeExtendedSplash() {
var extendedSplashScreen = document.getElementById("extendedSplashScreen");
WinJS.Utilities.addClass(extendedSplashScreen, "hidden");
}

C#

JavaScript와 마찬가지로 진행률 링이 있는 확장 시작 화면의 마크업을 추가해야 합니다. 이번에는 XAML을 사용합니다.

<!-- This snippet represents the ExtendedSplash class -->
<Canvas Grid.Row="0">
<Image x:Name="extendedSplashImage" Source="images/splash.png" />
<ProgressRing x:Name="ProgressRing" Foreground="White"
HorizontalAlignment="Center" IsActive="True"
MaxHeight="30" MinHeight="30" MaxWidth="30"
MinWidth="30"></ProgressRing>
</Canvas>

여기서도 먼저 활성화하는 동안 로딩 작업을 실행합니다. 그런 다음 activated 이벤트 인수에서 splash screen 개체를 가져오고 확장 시작 화면을 표시합니다.

async protected override void OnLaunched(LaunchActivatedEventArgs args)
{
// Begin executing setup operations.
PerformSetupTasks();

// Retrieve splash screen object.
SplashScreen splashScreen = args.SplashScreen;

ExtendedSplash eSplash = new ExtendedSplash(splashScreen);

// Register an event handler to be executed when the splash screen has been dismissed.
splashScreen.Dismissed += new TypedEventHandler<SplashScreen, object>(eSplash.onSplashScreenDismissed);
...

Window.Current.Content = eSplash;
Window.Current.Activate();
}

public ExtendedSplash(SplashScreen splash)
{
InitializeComponent();

// Position the extended splash screen image in the same location as the splash screen image.
this.extendedSplashImage.SetValue(Canvas.LeftProperty, splash.ImageLocation.X);
this.extendedSplashImage.SetValue(Canvas.TopProperty, splash.ImageLocation.Y);
this.extendedSplashImage.Height = splash.ImageLocation.Height;
this.extendedSplashImage.Width = splash.ImageLocation.Width;

// Position the extended splash screen's progress ring.
this.ProgressRing.SetValue(Canvas.TopProperty, splash.ImageLocation.Y + splash.ImageLocation.Height + 32);
this.ProgressRing.SetValue(Canvas.LeftProperty,
splash.ImageLocation.X +
(splash.ImageLocation.Width / 2) - 15);
}

확장 시작 화면이 표시되는 동안 필요한 로딩 작업을 실행한 다음 방문 페이지로 이동합니다.

internal void PerformSetupTasks()
{
// Begin additional loading tasks here…
...

// Tear down the extended splash screen after all operations are complete.
RemoveExtendedSplash();
}

internal void onSplashScreenDismissed(Windows.ApplicationModel.Activation.SplashScreen sender, object e)
{
// The splash screen has been dismissed and the extended splash screen is now in view.
...
}

void RemoveExtendedSplash()
{
Window.Current.Content = new LandingPage();
}

지연형 앱 시작

마지막으로 설명할 시작 패턴은 지연형 앱 시작입니다. 지연형 시작은 시작 화면 환경에서 방문 페이지로 전환하기 전에 방문 페이지를 준비할 수 있다는 점에서 확장형 시작과 유사합니다. 단, 비동기 작업을 시작하는 동안 '확장' 시작 화면을 표시하는 대신 일반 시작 화면의 해제를 지연시킨다는 점이 다릅니다. 앱에서 시작 화면 전환을 지연시킬 수 있는 시간은 한정되어 있기 때문에 지연형 패턴은 앱을 표시하기 전에 앱 설정을 읽는 등, 주로 간단한 비동기 작업을 수행하는 경우에 제한적으로 사용해야 합니다. 또한 지연 시간 동안 오류/예외를 제대로 처리하지 못하면 시작이 종료될 수도 있습니다. 따라서 앱에서 네트워크 호출을 해야 하거나 많은 양의 데이터를 처리해야 할 때는 골격형 또는 확장형 앱 시작 패턴을 사용해야 합니다.

아래는 Consumer Preview에서 소개된 사진 앱을 사용한 지연형 시작의 예입니다. 데스크톱에서 .jpg 파일을 열면 이 파일 형식의 기본 처리기로서 사진 앱이 시작됩니다. 이 사진 앱은 지연형 시작 패턴을 사용하여 시작 화면이 사라지기 전에 이미지 미리 보기를 로드합니다. 미리 보기 검색 작업은 비교적 짧은 시간 안에 완료할 수 있기 때문에 적절한 지연형 패턴의 사용 예라고 할 수 있습니다. 이후 사용자에게 앱이 표시되고 나면 고해상도 이미지를 비동기 방식으로 가져와 미리 보기를 대체할 수 있습니다. 이러한 흐름은 미리 보기가 화면에 표시된 상태로 사용자가 앱으로 전환되도록 합니다.

아래 이미지에 나와 있는 프로세스는 다음과 같습니다.

  1. 사용자가 .jpg 이미지를 클릭합니다(사진 앱이 기본 .jpg 처리기).
  2. 시작 화면이 표시됩니다.
  3. 미리 보기가 검색될 때까지 활성화가 지연됩니다.
  4. 미리 보기가 표시된 상태로 앱이 표시됩니다.

데스크톱에서 .jpg 파일을 클릭하면 .jpg 파일 처리기의 시작 화면이 표시됩니다. 그런 다음 앱이 활성화를 지연시켜 .jpg 파일을 처리할 때까지 시작 화면이 계속 표시되도록 합니다. .jpg 파일이 처리되면 앱이 지연을 끝내고 .jpg 미리 보기가 표시된 첫 번째 보기를 표시합니다. 
지연형 앱 시작 흐름

JavaScript에서 지연형 시작 흐름을 구현하려면 activation deferral을 사용해야 합니다. deferral에서는 앱이 비동기 작업이 완료될 때까지 활성화가 완료되는 것을 지연시킬 수 있습니다. 그렇지 않을 경우 콜백이 반환되면 활성화가 완료되어 버립니다. 대부분의 Windows Runtime API는 비동기식으로 실행되기 때문에 이는 초기 UI를 표시하기 전에 모든 작업을 완료해야 하는 앱에 유용합니다. C#에서는 Window.Current.Activate 호출을 지연하는 방법으로 앱의 지연을 구현할 수 있습니다. 아래에서는 두 가지 방법을 모두 살펴보겠습니다.

JavaScript

JavaScript에서는 앱이 활성화를 처리하는 방식에 따라 두 가지 방법으로 활��화 지연을 구현할 수 있습니다.

WinJS를 사용하여 활성화를 처리하는 앱(VS 프로젝트 템플릿의 기본 설정)의 경우 다음 코드를 사용합니다. activation 이벤트 인수에서 setPromise를 호출하면 두 가지 비동기 호출(WinJS.UI.processAll 및 asyncOperation)이 완료될 때까지 활성화의 완료가 지연됩니다.

app.onactivated = function (eventArgs) {
if (eventArgs.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
eventArgs.setPromise(WinJS.UI.processAll().then(function() {
return asyncOperation().done(function () { });
}));
}
};

activated 이벤트를 처리하도록 수동으로 등록하는 경우 ActivatedOperation.getDeferral 메서드를 사용하면 됩니다. 아래의 예에서는 활성화하는 동안 deferral 개체를 가져오고 비동기 작업이 완료되면 complete를 호출합니다.

참고: 비동기 호출의 성공 여부에 관계없이 complete를 호출해야 합니다. complete를 호출하지 않으면 앱이 활성화 작업 상태에서 전환되지 않고 앱 시작이 시간 초과됩니다. 이는 이 패턴을 사용할 때 많이 발생하는 문제로, 앱이 모든 오류 상황을 올바르게 처리하도록 하는 것이 중요합니다.

Windows.UI.WebUI.WebUIApplication.addEventListener("activated", onActivated, false);
function onActivated(eventArgs) {
if (eventArgs.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
var deferral = eventArgs.activatedOperation.getDeferral();
asyncOperation().done(function () {
deferral.complete();
}, function (error) {
deferral.complete();
});
}
}

C#

C#에서 지연을 구현하려면 로딩 작업이 완료될 때까지 Window.Current.Activate 호출을 연기하면 됩니다. 단, JavaScript와 마찬가지로 간단한 작업을 완료하는 짧은 시간 동안에만 이 호출을 연기해야 합니다. 앱이 일정 시간 내에 창을 성공적으로 활성화하지 못하면 시작 시간이 초과됩니다. 또한 지연 시간이 길어지면 앱의 성능에 대해 나쁜 인상을 주게 되고 사용자의 앱에 대한 흥미를 떨어뜨립니다.

protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
// Create a frame to act navigation context and navigate to the first page.
var rootFrame = new Frame();
rootFrame.Navigate(typeof(BlankPage));

// Place the frame in the current Window and ensure that it is active.
Window.Current.Content = rootFrame;

// Use “await” to execute an async operation prior to activating a window.
// Remember, avoid lengthy operations here.
await asyncOperation();

Window.Current.Activate();
}

결론

이 글에서는 세련된 시작 환경을 제작하기 위한 몇 가지 기법을 설명했습니다. 앱의 모양과 느낌을 차별화하기 위해 Metro 스타일 앱에 적용할 수 있는 네 가지 구체적인 디자인 패턴을 살펴보았습니다. 앱을 개발하면서 앱 시작의 중요성을 기억하고 이 글에서 소개한 패턴을 이용하시기 바랍니다. 앱이 시작되는 시간은 사용자에게 기억할 만한 첫인상을 남길 수 있는 좋은 기회니까요.

활성화, 시작 화면 또는 앱 수명 주기에 대한 자세한 내용은 다음 자료를 참조하십시오.

링크

유형

주요 내용

Adding a splash screen

문서

시작 화면과 확장 시작 화면에 대해 포괄적으로 다룹니다. 이 섹션에는 유용한 디자인 지침도 포함되어 있습니다.

Splash screen sample

샘플

JavaScript, C#, C++ 및 VB.NET의 확장형 앱 시작 패턴을 보여 주는 SDK 샘플입니다.

SplashScreen class

API 참조

splash screen 클래스에 대한 API 설명서입니다.

How to activate an app – VB/C#/C++ and XAML

빠른 시작

C#, C++ 또는 VB.NET에서 Metro 스타일 앱을 활성화하는 방법을 소개하는 자습서입니다.

How to activate an app – JavaScript and HTML

빠른 시작

JavaScript를 사용하여 Metro 스타일 앱을 활성화하는 방법에 대한 자습서입니다.

App activation and suspension sample

샘플

JavaScript에서 Metro 스타일 앱을 활성화하고 일시 중단하는 방법을 보여 주는 SDK 샘플입니다.

Windows.ApplicationModel.Activation namespace

API 참조

activation 네임스페이스에 대한 API 설명서입니다.

WebUIApplication.activated event

API 참조

activated 이벤트에 대한 API 설명서입니다.

Application lifecycle

기사

Metro 스타일 앱 수명 주기에 대해 설명하는 기사입니다.

- Windows User Experience 프로그램 관리자, Justin Cooperman

  • Loading...
Leave a Comment
  • Please add 8 and 4 and type the answer here:
  • Post