Xamarin의 watchOS 백그라운드 작업

watchOS 3에서는 시계 앱이 정보를 최신 상태로 유지할 수 있는 세 가지 기본 방법이 있습니다.

  • 몇 가지 새로운 백그라운드 작업 중 하나를 사용 합니다.
  • 시계 얼굴에 합병증 중 하나를 갖는 (업데이트 할 수있는 여분의 시간을 제공).
  • 사용자가 앱에 고정하여 새 Dock(메모리에 보관되고 자주 업데이트되는 위치)에 고정합니다.

앱을 최신 상태로 유지

개발자가 watchOS 앱의 데이터와 사용자 인터페이스를 최신 상태로 유지하고 업데이트할 수 있는 모든 방법을 논의하기 전에 이 섹션에서는 일반적인 사용 패턴 집합과 사용자가 하루 중 시간과 현재 수행 중인 활동(예: 운전)에 따라 하루 종일 i전화 및 Apple Watch 간에 이동하는 방법을 살펴봅니다.

다음 예제를 참조하세요.

How a user might move between their iPhone and their Apple Watch throughout the day

  1. 아침에 커피를 기다리는 동안 사용자는 몇 분 동안 i전화 현재 뉴스를 찾아봅니다.
  2. 커피숍을 떠나기 전에, 그들은 신속하게 시계 얼굴에 합병증으로 날씨를 검사.
  3. 점심 식사 전에 i전화 지도 앱을 사용하여 근처 레스토랑을 찾고 고객을 만나기 위해 예약을 예약합니다.
  4. 레스토랑에 여행 하는 동안, 그들은 그들의 애플 시계에 알림을 받을 하 고 빠른 눈에, 그들은 그들의 점심 약속 늦게 실행 알고.
  5. 저녁에는 i전화 지도 앱을 사용하여 집으로 돌아가기 전에 트래픽을 검사.
  6. 집으로 가는 길에 Apple Watch에서 우유를 수령하라는 iMessage 알림을 받고 빠른 회신 기능을 사용하여 "확인"이라는 응답을 보냅니다.

사용자가 Apple Watch 앱을 사용하려는 방식의 "빠른 보기"(3초 미만) 특성으로 인해 일반적으로 앱이 원하는 정보를 가져오고 사용자에게 표시하기 전에 UI를 업데이트하는 데 충분한 시간이 없습니다.

Apple이 watchOS 3에 포함된 새 API를 사용하여 앱은 백그라운드 새로 고침예약하고 사용자가 요청하기 전에 원하는 정보를 준비할 수 있습니다. 위에서 설명한 날씨 합병증의 예를 들어 보세요.

An example of the Weather Complication

  1. 앱은 특정 시간에 시스템에 의해 해제되도록 예약합니다.
  2. 앱은 업데이트를 생성하는 데 필요한 정보를 가져옵니다.
  3. 앱은 새 데이터를 반영하도록 사용자 인터페이스를 다시 생성합니다.
  4. 사용자가 앱의 복잡성을 살펴보면 사용자가 업데이트를 기다릴 필요 없이 최신 정보가 있습니다.

위에서 볼 수 있듯이 watchOS 시스템은 하나 이상의 작업을 사용하여 앱을 깨우며, 그 중 매우 제한된 풀을 사용할 수 있습니다.

The watchOS system wakes the app using one or more Tasks

Apple은 앱이 자체 업데이트 프로세스를 완료할 때까지 이를 유지하여 이 작업을 최대한 활용하는 것이 좋습니다(앱에 대한 리소스가 제한되기 때문에).

시스템은 대리자의 새 HandleBackgroundTasks 메서드 WKExtensionDelegate 를 호출하여 이러한 작업을 제공합니다. 예시:

using System;
using Foundation;
using WatchKit;

namespace MonkeyWatch.MonkeySeeExtension
{
  public class ExtensionDelegate : WKExtensionDelegate
  {
    #region Constructors
    public ExtensionDelegate ()
    {
    }
    #endregion

    #region Override Methods
    public override void HandleBackgroundTasks (NSSet<WKRefreshBackgroundTask> backgroundTasks)
    {
      // Handle background request here
      ...
    }
    #endregion
  }
}

앱이 지정된 작업을 완료하면 완료된 것으로 표시하여 시스템에 반환합니다.

The Task returns to the system by marking it completed

새 백그라운드 작업

watchOS 3에서는 앱이 앱을 열기 전에 사용자에게 필요한 콘텐츠가 있는지 확인하는 정보를 업데이트하는 데 사용할 수 있는 몇 가지 백그라운드 작업을 소개합니다.

이러한 작업은 아래 섹션에서 자세히 설명합니다.

WKApplicationRefreshBackgroundTask

WKApplicationRefreshBackgroundTask 앱을 나중에 깨우도록 예약할 수 있는 일반 작업입니다.

A WKApplicationRefreshBackgroundTask woken at a future date

태스크의 런타임 내에서 앱은 복잡성 타임라인 업데이트하거나 필요한 일부 데이터를 NSUrlSession가져오는 등의 모든 종류의 로컬 처리를 수행할 수 있습니다.

WKURLSessionRefreshBackgroundTask

시스템은 데이터 다운로드가 WKURLSessionRefreshBackgroundTask 완료되고 앱에서 처리할 준비가 되면 다음을 보냅니다.

The WKURLSessionRefreshBackgroundTask when the data has finished downloading

데이터가 백그라운드에서 다운로드되는 동안 앱이 실행되지 않습니다. 대신 앱은 데이터 요청을 예약한 다음 일시 중단되고 시스템에서 데이터 다운로드를 처리하고 다운로드가 완료되면 앱을 다시 깨우게 됩니다.

WKSnapshotRefreshBackgroundTask

watchOS 3에서 Apple은 사용자가 좋아하는 앱을 고정하고 빠르게 액세스할 수 있는 Dock를 추가했습니다. 사용자가 Apple Watch에서 사이드 단추를 누르면 고정된 앱 스냅샷 갤러리가 표시됩니다. 사용자는 왼쪽이나 오른쪽으로 살짝 밀어 원하는 앱을 찾은 다음 앱을 탭하여 스냅샷을 실행 중인 앱의 인터페이스로 바꿉니다.

Replacing the Snapshot with the running apps interface

시스템은 주기적으로 앱의 UI 스냅샷 사용하고(전송WKSnapshotRefreshBackgroundTask) 해당 스냅샷 사용하여 Dock를 채웁니다. watchOS는 이 스냅샷을 만들기 전에 앱에 콘텐츠 및 UI를 업데이트할 수 있는 기회를 제공합니다.

스냅샷은 앱의 미리 보기 및 시작 이미지로 작동하므로 watchOS 3에서 매우 중요합니다. 사용자가 Dock의 앱에 정착하면 전체 화면으로 확장되고 포그라운드를 입력하고 실행을 시작하므로 스냅샷이 최신 상태여야 합니다.

If the user settles on an app in the Dock, it will expand to full screen

다시 말하지만, 시스템은 스냅샷 가져오기 전에 앱이 데이터 및 UI를 업데이트하여 준비할 수 있도록 발급 WKSnapshotRefreshBackgroundTask 합니다.

The app can prepare by updating the data and the UI before the snapshot is taken

앱이 완료된 WKSnapshotRefreshBackgroundTask 것을 표시하면 시스템에서 앱 UI의 스냅샷을 자동으로 만듭니다.

Important

앱이 새 데이터를 수신하고 사용자 인터페이스를 WKSnapshotRefreshBackgroundTask 업데이트한 후에는 항상 일정을 예약해야 합니다. 그렇지 않으면 사용자가 수정된 정보를 볼 수 없습니다.

또한 사용자가 앱에서 알림을 받고 탭하여 앱을 포그라운드로 가져오는 경우 스냅샷은 시작 화면으로도 작동하므로 최신 상태여야 합니다.

The user receives a notification from the app and taps it to bring the app to the foreground

사용자가 watchOS 앱과 상호 작용한 지 1시간이 넘은 경우 기본 상태로 돌아갈 수 있습니다. 기본 상태는 다른 앱과 다른 항목을 의미할 수 있으며, 앱의 디자인에 따라 기본 상태가 전혀 없을 수 있습니다.

WKWatch커넥트ivityRefreshBackgroundTask

watchOS 3에서 Apple은 새로운 WKWatchConnectivityRefreshBackgroundTask기능을 통해 백그라운드 새로 고침 API와 시계 연결을 통합했습니다. 이 새로운 기능을 사용하여 i전화 앱은 watchOS 앱이 백그라운드에서 실행되는 동안 해당 조사식 앱에 새 데이터를 제공할 수 있습니다.

An iPhone app can deliver fresh data to its watch app counterpart, while the watchOS app is running in the background

복잡한 푸시, 앱 컨텍스트를 시작하거나, 파일을 보내거나, i전화 앱에서 사용자 정보를 업데이트하면 Apple Watch 앱이 백그라운드에서 해제됩니다.

조사식 앱이 깨지면 WKWatchConnectivityRefreshBackgroundTask 표준 API 메서드를 사용하여 i전화 앱에서 데이터를 수신해야 합니다.

The WKWatchConnectivityRefreshBackgroundTask data flow

  1. 세션이 활성화되었는지 확인합니다.
  2. true이 있는 한 새 HasContentPending 속성을 모니터링합니다. 앱에 처리할 데이터가 계속 있습니다. 이전과 마찬가지로 앱은 모든 데이터 처리를 완료할 때까지 작업을 유지해야 합니다.
  3. 더 이상 처리할 데이터가 없으면(HasContentPending = false) 완료된 태스크를 표시하여 시스템에 반환합니다. 이렇게 하지 않으면 앱의 할당된 백그라운드 런타임이 소진되어 크래시 보고서가 발생합니다.

백그라운드 API 수명 주기

새 백그라운드 작업 API의 모든 부분을 함께 배치하면 일반적인 상호 작용 집합은 다음과 같습니다.

The Background API Lifecycle

  1. 먼저 watchOS 앱은 백그라운드 작업을 나중에 특정 시점으로 깨워지도록 예약합니다.
  2. 앱이 시스템에 의해 해제되고 작업을 보냈습니다.
  3. 앱은 태스크를 처리하여 필요한 작업을 완료합니다.
  4. 작업을 처리한 결과 앱은 나중에 더 많은 작업을 완료하기 위해 더 많은 백그라운드 작업을 예약해야 할 수 있습니다(예: 더 많은 콘텐츠를 사용하여 NSUrlSession다운로드).
  5. 앱은 완료된 작업을 표시하고 시스템에 반환합니다.

책임감 있게 리소스 사용

watchOS 앱은 시스템의 공유 리소스에 대한 드레이닝 제한을 통해 이 에코시스템 내에서 책임감 있게 동작하는 것이 중요합니다.

다음 시나리오를 살펴보세요.

A watchOS app limits its drain on the system's shared resources

  1. 사용자는 오후 1시에 watchOS 앱을 시작합니다.
  2. 앱은 2:00 PM에 1시간 안에 새 콘텐츠를 깨우고 다운로드하도록 작업을 예약합니다.
  3. 오후 1시 50분에 사용자는 이 시점에서 데이터 및 UI를 업데이트할 수 있는 앱을 다시 엽니다.
  4. 작업이 10분 후에 앱을 다시 깨우도록 하는 대신, 앱은 오후 2시 50분에 1시간 후에 실행되도록 작업을 다시 예약해야 합니다.

모든 앱은 다르지만 Apple은 시스템 리소스를 절약하기 위해 위에 표시된 것과 같은 사용 패턴을 찾는 것이 좋습니다.

백그라운드 작업 구현

예를 들어 이 문서에서는 축구 점수를 사용자에게 보고하는 가짜 MonkeySoccer 스포츠 앱을 사용합니다.

다음과 같은 일반적인 사용 시나리오를 살펴보세요.

The typical usage scenario

사용자가 가장 좋아하는 축구 팀은 오후 7시에서 오후 9시까지 큰 경기를 치르기 때문에 앱은 사용자가 정기적으로 점수를 검사 것으로 예상해야 하며 30분 업데이트 간격을 결정합니다.

  1. 사용자가 앱을 열고 30분 후에 백그라운드 업데이트를 위한 작업을 예약합니다. 백그라운드 API를 사용하면 지정된 시간에 한 가지 유형의 백그라운드 작업만 실행할 수 있습니다.
  2. 앱은 작업을 수신하고 해당 데이터 및 UI를 업데이트한 다음, 30분 후에 다른 백그라운드 작업을 예약합니다. 개발자는 다른 백그라운드 작업을 예약해야 합니다. 그렇지 않으면 더 많은 업데이트를 받기 위해 앱이 다시 해제되지 않습니다.
  3. 다시 말하지만, 앱은 작업을 수신하고 데이터를 업데이트하고, UI를 업데이트하고, 30분 후에 다른 백그라운드 작업을 예약합니다.
  4. 동일한 프로세스가 다시 반복됩니다.
  5. 마지막 백그라운드 작업이 수신되고 앱이 데이터 및 UI를 다시 업데이트합니다. 최종 점수이므로 새 백그라운드 새로 고침을 예약하지 않습니다.

백그라운드 업데이트 예약

위의 시나리오를 고려할 때 MonkeySoccer 앱은 다음 코드를 사용하여 백그라운드 업데이트를 예약할 수 있습니다.

private void ScheduleNextBackgroundUpdate ()
{
  // Create a fire date 30 minutes into the future
  var fireDate = NSDate.FromTimeIntervalSinceNow (30 * 60);

  // Create
  var userInfo = new NSMutableDictionary ();
  userInfo.Add (new NSString ("LastActiveDate"), NSDate.FromTimeIntervalSinceNow(0));
  userInfo.Add (new NSString ("Reason"), new NSString ("UpdateScore"));

  // Schedule for update
  WKExtension.SharedExtension.ScheduleBackgroundRefresh (fireDate, userInfo, (error) => {
    // Was the Task successfully scheduled?
    if (error == null) {
      // Yes, handle if needed
    } else {
      // No, report error
    }
  });
}

앱이 깨워지려고 할 때 30분 후에 새 NSDate 30분을 만들고 요청된 작업의 세부 정보를 저장할 수 있는 항목을 만듭니다 NSMutableDictionary . 이 ScheduleBackgroundRefresh 메서드 SharedExtension 는 작업 예약을 요청하는 데 사용됩니다.

요청된 NSError 작업을 예약할 수 없는 경우 시스템에서 반환합니다.

업데이트 처리

다음으로, 점수를 업데이트하는 데 필요한 단계를 보여 주는 5분 창을 자세히 살펴보겠습니다.

The 5 minute window showing the steps required to update the score

  1. 오후 7시 30분 02분에 시스템에 의해 앱이 각성되고 업데이트 백그라운드 작업이 제공됩니다. 첫 번째 우선 순위는 서버에서 최신 점수를 얻는 것입니다. 아래의 NSUrlSession 예약을 참조하세요.
  2. 7:30:05에 앱이 원래 작업을 완료하면 시스템에서 앱을 절전 모드로 설정하고 요청된 데이터를 백그라운드에서 계속 다운로드합니다.
  3. 시스템이 다운로드를 완료하면 다운로드한 정보를 처리할 수 있도록 앱을 해제하는 새 작업을 만듭니다. 아래의 백그라운드 작업 처리 및 다운로드 완료 처리를 참조하세요.
  4. 앱은 업데이트된 정보를 저장하고 완료된 작업을 표시합니다. 개발자는 현재 앱의 사용자 인터페이스를 업데이트하려고 할 수 있지만 Apple은 해당 프로세스를 처리하기 위해 스냅샷 태스크를 예약할 것을 제안합니다. 아래 스냅샷 업데이트 예약을 참조하세요.
  5. 앱은 스냅샷 태스크를 수신하고 사용자 인터페이스를 업데이트하며 완료된 작업을 표시합니다. 아래 스냅샷 업데이트 처리를 참조하세요.

NSUrlSession 예약

다음 코드를 사용하여 최신 점수 다운로드를 예약할 수 있습니다.

private void ScheduleURLUpdateSession ()
{
  // Create new configuration
  var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration ("com.example.urlsession");

  // Create new session
  var backgroundSession = NSUrlSession.FromConfiguration (configuration);

  // Create and start download task
  var downloadTask = backgroundSession.CreateDownloadTask (new NSUrl ("https://example.com/gamexxx/currentScores.json"));
  downloadTask.Resume ();
}

새 항목을 구성하고 만든 다음, 해당 세션을 사용하여 메서드를 사용하여 CreateDownloadTask 새 다운로드 작업을 만듭니다NSUrlSession. 다운로드 작업의 메서드를 호출 Resume 하여 세션을 시작합니다.

백그라운드 작업 처리

앱은 메서드를 HandleBackgroundTasks 재정의 WKExtensionDelegate하여 들어오는 백그라운드 작업을 처리할 수 있습니다.

using System;
using System.Collections.Generic;
using Foundation;
using WatchKit;

namespace MonkeySoccer.MonkeySoccerExtension
{
  public class ExtensionDelegate : WKExtensionDelegate
  {
    #region Computed Properties
    public List<WKRefreshBackgroundTask> PendingTasks { get; set; } = new List<WKRefreshBackgroundTask> ();
    #endregion

    ...

    #region Public Methods
    public void CompleteTask (WKRefreshBackgroundTask task)
    {
      // Mark the task completed and remove from the collection
      task.SetTaskCompleted ();
      PendingTasks.Remove (task);
    }
    #endregion

    #region Override Methods
    public override void HandleBackgroundTasks (NSSet<WKRefreshBackgroundTask> backgroundTasks)
    {
      // Handle background request
      foreach (WKRefreshBackgroundTask task in backgroundTasks) {
        // Is this a background session task?
        var urlTask = task as WKUrlSessionRefreshBackgroundTask;
        if (urlTask != null) {
          // Create new configuration
          var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration (urlTask.SessionIdentifier);

          // Create new session
          var backgroundSession = NSUrlSession.FromConfiguration (configuration, new BackgroundSessionDelegate (this, task), null);

          // Keep track of all pending tasks
          PendingTasks.Add (task);
        } else {
          // Ensure that all tasks are completed
          task.SetTaskCompleted ();
        }
      }
    }
    #endregion

    ...
  }
}

메서드는 HandleBackgroundTasks 시스템에서 앱을 보낸 모든 작업(in)에서 backgroundTasks검색을 순환합니다 WKUrlSessionRefreshBackgroundTask. 세션이 발견되면 세션에 다시 참가하고 다운로드 완료를 처리하기 위해 A NSUrlSessionDownloadDelegate 를 연결합니다(아래 다운로드 완료 처리 참조).

// Create new session
var backgroundSession = NSUrlSession.FromConfiguration (configuration, new BackgroundSessionDelegate (this, task), null);

컬렉션에 추가하여 작업이 완료될 때까지 작업 핸들을 유지합니다.

public List<WKRefreshBackgroundTask> PendingTasks { get; set; } = new List<WKRefreshBackgroundTask> ();
...

// Keep track of all pending tasks
PendingTasks.Add (task);

앱에 전송된 모든 작업을 완료해야 합니다. 현재 처리되고 있지 않은 작업의 경우 완료된 것으로 표시합니다.

if (urlTask != null) {
  ...
} else {
  // Ensure that all tasks are completed
  task.SetTaskCompleted ();
}

다운로드 완료 처리

MonkeySoccer 앱은 다음 NSUrlSessionDownloadDelegate 대리자를 사용하여 다운로드 완료를 처리하고 요청된 데이터를 처리합니다.

using System;
using Foundation;
using WatchKit;

namespace MonkeySoccer.MonkeySoccerExtension
{
  public class BackgroundSessionDelegate : NSUrlSessionDownloadDelegate
  {
    #region Computed Properties
    public ExtensionDelegate WatchExtensionDelegate { get; set; }

    public WKRefreshBackgroundTask Task { get; set; }
    #endregion

    #region Constructors
    public BackgroundSessionDelegate (ExtensionDelegate extensionDelegate, WKRefreshBackgroundTask task)
    {
      // Initialize
      this.WatchExtensionDelegate = extensionDelegate;
      this.Task = task;
    }
    #endregion

    #region Override Methods
    public override void DidFinishDownloading (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, NSUrl location)
    {
      // Handle the downloaded data
      ...

      // Mark the task completed
      WatchExtensionDelegate.CompleteTask (Task);

    }
    #endregion
  }
}

초기화할 때는 핸들을 생성한 ExtensionDelegate 핸들과 WKRefreshBackgroundTask 생성된 핸들을 모두 유지합니다. 다운로드 완료를 DidFinishDownloading 처리하도록 메서드를 재정의합니다. 그런 다음 이 CompleteTask 메서드를 ExtensionDelegate 사용하여 작업이 완료되었음을 태스크에 알리고 보류 중인 작업 컬렉션에서 제거합니다. 위의 백그라운드 작업 처리를 참조하세요.

스냅샷 업데이트 예약

다음 코드를 사용하여 스냅샷 태스크를 예약하여 최신 점수로 UI를 업데이트할 수 있습니다.

private void ScheduleSnapshotUpdate ()
{
  // Create a fire date of now
  var fireDate = NSDate.FromTimeIntervalSinceNow (0);

  // Create user info dictionary
  var userInfo = new NSMutableDictionary ();
  userInfo.Add (new NSString ("lastActiveDate"), NSDate.FromTimeIntervalSinceNow (0));
  userInfo.Add (new NSString ("reason"), new NSString ("UpdateScore"));

  // Schedule for update
  WKExtension.SharedExtension.ScheduleSnapshotRefresh (fireDate, userInfo, (error) => {
    // Was the Task successfully scheduled?
    if (error == null) {
      // Yes, handle if needed
    } else {
      // No, report error
    }
  });
}

위의 메서드와 마찬가지로 ScheduleURLUpdateSession 앱이 깨어날 때를 위한 새 NSDate 항목을 만들고 요청된 작업의 세부 정보를 저장할 수 있는 메서드를 만듭니다 NSMutableDictionary . 이 ScheduleSnapshotRefresh 메서드 SharedExtension 는 작업 예약을 요청하는 데 사용됩니다.

요청된 NSError 작업을 예약할 수 없는 경우 시스템에서 반환합니다.

스냅샷 업데이트 처리

스냅샷 태스크 HandleBackgroundTasks 를 처리하기 위해 메서드(위의 백그라운드 작업 처리 참조)는 다음과 같이 수정됩니다.

public override void HandleBackgroundTasks (NSSet<WKRefreshBackgroundTask> backgroundTasks)
{
  // Handle background request
  foreach (WKRefreshBackgroundTask task in backgroundTasks) {
    // Take action based on task type
    if (task is WKUrlSessionRefreshBackgroundTask) {
      var urlTask = task as WKUrlSessionRefreshBackgroundTask;

      // Create new configuration
      var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration (urlTask.SessionIdentifier);

      // Create new session
      var backgroundSession = NSUrlSession.FromConfiguration (configuration, new BackgroundSessionDelegate (this, task), null);

      // Keep track of all pending tasks
      PendingTasks.Add (task);
    } else if (task is WKSnapshotRefreshBackgroundTask) {
      var snapshotTask = task as WKSnapshotRefreshBackgroundTask;

      // Update UI
      ...

      // Create a expiration date 30 minutes into the future
      var expirationDate = NSDate.FromTimeIntervalSinceNow (30 * 60);

      // Create user info dictionary
      var userInfo = new NSMutableDictionary ();
      userInfo.Add (new NSString ("lastActiveDate"), NSDate.FromTimeIntervalSinceNow (0));
      userInfo.Add (new NSString ("reason"), new NSString ("UpdateScore"));

      // Mark task complete
      snapshotTask.SetTaskCompleted (false, expirationDate, userInfo);
    } else {
      // Ensure that all tasks are completed
      task.SetTaskCompleted ();
    }
  }
}

메서드는 처리 중인 작업의 형식을 테스트합니다. 작업인 WKSnapshotRefreshBackgroundTask 경우 작업에 대한 액세스 권한을 얻습니다.

var snapshotTask = task as WKSnapshotRefreshBackgroundTask;

이 메서드는 사용자 인터페이스를 업데이트한 다음 스냅샷이 부실할 때 시스템에 알릴 수 있는 메서드를 만듭니다 NSDate . 새 스냅샷을 NSMutableDictionary 설명하는 사용자 정보를 만들고 이 정보로 완료된 스냅샷 태스크를 표시합니다.

// Mark task complete
snapshotTask.SetTaskCompleted (false, expirationDate, userInfo);

또한 앱이 첫 번째 매개 변수의 기본 상태로 돌아가지 않는다는 것을 스냅샷 태스크에 알릴 수도 있습니다. 기본 상태의 개념이 없는 앱은 항상 이 속성을 .로 true설정해야 합니다.

효율적으로 작업

MonkeySoccer 앱이 효율적으로 작업하고 새 watchOS 3 백그라운드 작업을 사용하여 점수를 업데이트하는 데 걸린 5분 창의 위 예제에서 볼 수 있듯이 앱은 총 15초 동안만 활성화되었습니다.

The app was only active for a total of 15 seconds

이렇게 하면 앱이 사용 가능한 Apple Watch 리소스와 배터리 수명 모두에 미치는 영향을 낮추고 앱이 시계에서 실행되는 다른 앱에서 더 잘 작동할 수 있습니다.

일정 작동 방식

watchOS 3 앱은 포그라운드에 있는 동안 항상 실행되도록 예약되며 데이터 업데이트 또는 UI 다시 그리기와 같은 모든 유형의 처리를 수행할 수 있습니다. 앱이 백그라운드로 이동하면 일반적으로 시스템에 의해 일시 중단되고 모든 런타임 작업이 중지됩니다.

앱이 백그라운드에 있는 동안 시스템에서 특정 작업을 신속하게 실행하도록 대상으로 지정할 수 있습니다. 따라서 watchOS 2에서 시스템은 백그라운드 앱을 일시적으로 해제하여 긴 보기 알림을 처리하거나 앱의 복잡성을 업데이트하는 등의 작업을 수행할 수 있습니다. watchOS 3에는 백그라운드에서 앱을 실행할 수 있는 몇 가지 새로운 방법이 있습니다.

앱이 백그라운드에 있는 동안 시스템은 다음과 같은 몇 가지 제한을 적용합니다.

  • 지정된 작업을 완료하는 데 몇 초밖에 주어지지 않습니다. 시스템은 경과된 시간뿐만 아니라 앱이 이 제한을 파생하기 위해 소비하는 CPU 전력의 양도 고려합니다.
  • 해당 제한을 초과하는 모든 앱은 다음 오류 코드로 인해 종료됩니다.
    • CPU - 0xc51bad01
    • 시간 - 0xc51bad02
  • 시스템은 앱에 수행하도록 요청한 백그라운드 작업의 유형에 따라 다른 제한을 적용합니다. 예를 들어 WKApplicationRefreshBackgroundTaskWKURLSessionRefreshBackgroundTask 태스크는 다른 유형의 백그라운드 작업에 비해 약간 더 긴 런타임이 제공됩니다.

복잡성 및 앱 업데이트

Apple이 watchOS 3에 추가한 새로운 백그라운드 작업 외에도 watchOS 앱의 복잡성은 앱이 백그라운드 업데이트를 받는 방법과 시기에 영향을 줄 수 있습니다.

복잡성은 유용한 정보를 한 눈에 제공하는 작은 시각적 요소입니다. 선택한 시계 얼굴에 따라 사용자는 watchOS 3에서 시계 앱에서 제공할 수 있는 하나 이상의 합병증으로 시계 얼굴을 사용자 지정할 수 있습니다.

사용자가 시계 얼굴에 앱의 복잡성 중 하나를 포함하는 경우 앱에 다음과 같은 업데이트된 이점을 제공합니다.

  • 그러면 시스템에서 앱을 시작할 준비가 된 상태로 유지되고, 백그라운드에서 앱을 시작하려고 시도하고, 메모리에 보관하고, 업데이트할 추가 시간을 제공합니다.
  • 합병증은 하루에 최소 50개의 푸시 업데이트를 보장합니다.

개발자는 항상 위에 나열된 이유로 사용자가 시계 얼굴에 추가하도록 유도하기 위해 앱에 대한 강력한 복잡성을 만들기 위해 노력해야 합니다.

watchOS 2에서 복잡성은 백그라운드에서 앱이 런타임을 수신하는 기본 방식이었습니다. watchOS 3에서는 더 많은 런타임을 요청하여 복잡성을 업데이트하는 데 사용할 WKExtensions 수 있습니다.

연결된 i전화 앱에서 합병증을 업데이트하는 데 사용되는 다음 코드를 살펴보세요.

using System;
using WatchConnectivity;
using UIKit;
using Foundation;
using System.Collections.Generic;
using System.Linq;
...

private void UpdateComplication ()
{

  // Get session and the number of remaining transfers
  var session = WCSession.DefaultSession;
  var transfers = session.RemainingComplicationUserInfoTransfers;

  // Create user info dictionary
  var iconattrs = new Dictionary<NSString, NSObject>
    {
      {new NSString ("lastActiveDate"), NSDate.FromTimeIntervalSinceNow (0)},
      {new NSString ("reason"), new NSString ("UpdateScore")}
    };

  var userInfo = NSDictionary<NSString, NSObject>.FromObjectsAndKeys (iconattrs.Values.ToArray (), iconattrs.Keys.ToArray ());

  // Take action based on the number of transfers left
  if (transfers < 1) {
    // No transfers left, either attempt to send or inform
    // user of situation.
    ...
  } else if (transfers < 11) {
    // Running low on transfers, only send on important updates
    // else conserve for a significant change.
    ...
  } else {
    // Send data
    session.TransferCurrentComplicationUserInfo (userInfo);
  }
}

이 속성은 앱이 RemainingComplicationUserInfoTransfersWCSession 하루 동안 남긴 높은 우선 순위 전송 수를 확인하기 위해 해당 속성을 사용한 다음, 해당 수에 따라 작업을 수행합니다. 앱이 전송 시 낮게 실행되기 시작하면 사소한 업데이트 전송을 보류하고 중요한 변경이 있을 때만 정보를 보낼 수 있습니다.

예약 및 Dock

watchOS 3에서 Apple은 사용자가 좋아하는 앱을 고정하고 빠르게 액세스할 수 있는 Dock를 추가했습니다. 사용자가 Apple Watch에서 사이드 단추를 누르면 고정된 앱 스냅샷 갤러리가 표시됩니다. 사용자는 왼쪽 또는 오른쪽으로 살짝 밀어 원하는 앱을 찾은 다음 앱을 탭하여 실행 중인 앱의 인터페이스로 스냅샷 바꿉니다.

The Dock

시스템은 정기적으로 앱 UI의 스냅샷 사용하고 이러한 스냅샷 사용하여 Docs를 채웁니다. watchOS는 이 스냅샷 가져오기 전에 앱에 콘텐츠 및 UI를 업데이트할 수 있는 기회를 제공합니다.

도크에 고정된 앱에는 다음이 예상될 수 있습니다.

  • 시간당 업데이트된 최소 1개를 받게 됩니다. 여기에는 앱 새로 고침 태스크와 스냅샷 태스크가 모두 포함됩니다.
  • 업데이트 예산은 Dock의 모든 앱 간에 분산됩니다. 따라서 사용자가 고정한 앱이 적을수록 각 앱이 받을 수 있는 잠재적 업데이트가 늘어나게 됩니다.
  • 앱은 메모리에 유지되므로 Dock에서 선택하면 앱이 빠르게 다시 시작됩니다.

사용자가 실행한 마지막 앱은 가장 최근에 사용한 앱으로 간주되며 Dock의 마지막 슬롯을 차지합니다. 여기에서 사용자는 Dock에 영구적으로 고정하도록 선택할 수 있습니다. 가장 최근에 사용한 항목은 사용자가 Dock에 이미 고정한 다른 즐겨찾기 앱처럼 처리됩니다.

Important

홈 화면에만 추가된 앱에는 정기적인 일정이 제공되지 않습니다. 정기적인 예약 및 백그라운드 업데이트를 받으려면 Dock에 앱을 추가해야 합니다 .

이 문서의 앞부분에서 설명한 것처럼 스냅샷은 앱의 미리 보기 및 시작 이미지로 작동하므로 watchOS 3에서 매우 중요합니다. 사용자가 Dock에서 앱에 정착하는 경우 전체 화면으로 확장되어 포그라운드를 입력하고 실행을 시작하므로 스냅샷이 최신 상태여야 합니다.

시스템에서 앱 UI의 새 스냅샷이 필요하다고 결정하는 경우가 있을 수 있습니다. 이 경우 스냅샷 요청은 앱의 런타임 예산에 계산되지 않습니다. 다음은 시스템 스냅샷 요청을 트리거합니다.

  • 복잡성 타임라인 업데이트입니다.
  • 앱의 알림과 사용자 상호 작용
  • 전경에서 백그라운드 상태로 전환합니다.
  • 백그라운드 상태에 있는 1시간 후 앱이 기본 상태로 돌아갈 수 있도록 합니다.
  • watchOS가 처음 부팅되는 경우

좋은 연습 방법

Apple은 백그라운드 작업을 사용할 때 다음과 같은 모범 사례를 제안합니다.

  • 앱을 업데이트해야 하는 빈도만큼 예약합니다. 앱이 실행될 때마다 향후 요구 사항을 다시 평가하고 필요에 따라 이 일정을 조정해야 합니다.
  • 시스템에서 백그라운드 새로 고침 작업을 보내고 앱에 업데이트가 필요하지 않은 경우 업데이트가 실제로 필요할 때까지 작업을 연기합니다.
  • 앱에서 사용할 수 있는 모든 런타임 기회를 고려합니다.
    • 도킹 및 포그라운드 활성화.
    • 알림.
    • 복잡성 업데이트.
    • 백그라운드 새로 고침.
  • 다음과 같은 범용 백그라운드 런타임에 사용합니다 ScheduleBackgroundRefresh .
    • 정보를 위해 시스템을 폴링합니다.
    • 백그라운드 데이터를 요청하도록 미래를 NSURLSessions 예약합니다.
    • 알려진 시간 전환입니다.
    • 복잡성 업데이트 트리거

스냅샷 모범 사례

스냅샷 업데이트를 사용할 때 Apple은 다음과 같은 제안을 합니다.

  • 필요한 경우에만(예: 중요한 콘텐츠 변경이 있는 경우) 스냅샷을 무효화합니다.
  • 빈도가 높은 스냅샷 무효화를 방지합니다. 예를 들어 타이머 앱은 1초마다 스냅샷을 업데이트하지 않아야 하며 타이머가 종료된 경우에만 수행해야 합니다.

앱 데이터 흐름

Apple은 데이터 흐름을 사용하기 위해 다음을 제안합니다.

App Data Flow Diagram

외부 이벤트(예: Watch 커넥트ivity)가 앱을 깨우고 있습니다. 이렇게 하면 앱이 데이터 모델(앱 현재 상태를 나타낸)을 강제로 업데이트합니다. 데이터 모델 변경의 결과로 앱은 복잡성을 업데이트하고, 새 스냅샷을 요청하고, 배경을 NSURLSession 시작하여 더 많은 데이터를 끌어오고, 추가 백그라운드 새로 고침을 예약해야 합니다.

앱 수명 주기

Dock와 즐겨 찾는 앱을 고정할 수 있기 때문에 Apple은 사용자가 훨씬 더 많은 앱 간에 훨씬 더 자주 이동할 것이라고 생각하며 watchOS 2를 사용했습니다. 따라서 앱은 이 변경을 처리하고 포그라운드와 백그라운드 상태 간에 빠르게 이동할 준비가 되어 있어야 합니다.

Apple에는 다음과 같은 제안이 있습니다.

  • 포그라운드 정품 인증을 입력할 때 앱이 가능한 한 빨리 백그라운드 작업을 완료하는지 확인합니다.
  • 를 호출 NSProcessInfo.PerformExpiringActivity하여 배경을 입력하기 전에 모든 전경 작업을 완료해야 합니다.
  • watchOS 시뮬레이터에서 앱을 테스트할 때는 작업 예산이 적용되지 않으므로 앱이 기능을 제대로 테스트하는 데 필요한 만큼 새로 고칠 수 있습니다.
  • iTunes 커넥트 게시하기 전에 앱이 예산을 넘지 않는지 확인하기 위해 항상 실제 Apple Watch 하드웨어를 테스트합니다.
  • 애플은 테스트 및 디버깅 하는 동안 충전기에 애플 시계를 유지 제안.
  • 앱을 콜드 시작 및 다시 시작하는 것이 모두 철저히 테스트되었는지 확인합니다.
  • 모든 앱 작업이 완료되고 있는지 확인합니다.
  • Dock에 고정된 앱 수를 변경하여 최상의 시나리오와 최악의 시나리오를 모두 테스트합니다.

요약

이 문서에서는 Apple이 watchOS에 적용한 향상된 기능과 시계 앱을 최신 상태로 유지하는 데 사용할 수 있는 방법을 설명했습니다. 먼저 Apple이 watchOS 3에 추가한 새로운 백그라운드 작업을 모두 설명했습니다. 그런 다음, 백그라운드 API 수명 주기와 Xamarin watchOS 앱에서 백그라운드 작업을 구현하는 방법을 설명했습니다. 마지막으로 일정의 작동 방식을 알아보고 몇 가지 모범 사례를 제공했습니다.