objc.io

이오스 7 이전에는 개발자들이 앱이 포그라운드를 떠날 때 할 수 있는 일이 상당히 제한적이었다. 위치 기반 기능 외에도 백그라운드에서 코드를 실행하는 유일한 방법은 몇 분 동안 실행되는 것으로 제한된 백그라운드 작업을 사용하는 것이 었습니다. 오프라인으로 볼 수 있도록 큰 비디오를 다운로드하거나 사용자의 사진을 서버에 백업하려는 경우 작업의 일부만 완료할 수 있습니다.응용 프로그램의 사용자 인터페이스 및 콘텐츠를 백그라운드에서 업데이트하기 위한 두 개의 새로운 아피스가 추가되었습니다. 첫 번째 백그라운드 페치를 사용하면 일정한 간격으로 네트워크에서 새 콘텐츠를 가져올 수 있습니다. 두 번째 원격 알림은 푸시 알림을 활용하여 이벤트가 발생했을 때 앱에 알리는 새로운 기능입니다. 이 두 가지 새로운 메커니즘을 통해 앱의 인터페이스를 최신 상태로 유지할 수 있으며 새로운 백그라운드 전송 서비스에 대한 작업을 예약 할 수 있습니다.이 서비스를 통해 프로세스 외 네트워크 전송(다운로드 및 업로드)을 수행 할 수 있습니다.

백그라운드 가져 오기 및 원격 알림은 앱이 일시 중지되기 전에 작업을 수행 할 수있는 30 초의 벽시계 시간이있는 간단한 응용 프로그램 위임 후크입니다. 대신 대규모 영화 다운로드 또는 빠른 콘텐츠 업데이트 수행과 같이 장기 실행 네트워킹 요청을 대기열에 넣기 위한 것입니다.

사용자의 관점에서 볼 때,멀티태스킹에 대한 유일한 명백한 변화는 새로운 앱 스위처입니다. 이제 백그라운드 작업을 완료한 후 앱의 스냅샷을 업데이트하여 새 콘텐츠의 미리 보기를 표시할 수 있습니다. 소셜 네트워킹,뉴스 또는 날씨 앱은 이제 사용자가 앱을 열지 않고도 최신 콘텐츠를 표시 할 수 있습니다. 우리는 나중에 스냅 샷을 업데이트하는 방법을 볼 수 있습니다.

배경 가져 오기

배경 가져 오기는 소셜 네트워킹,뉴스 또는 날씨 앱과 같이 콘텐츠 업데이트가 자주 발생하는 앱에 가장 적합한 일종의 스마트 폴링 메커니즘입니다. 이 시스템은 사용자의 행동에 따라 앱을 깨우고 사용자가 앱을 실행하기 전에 백그라운드 페치를 트리거하는 것을 목표로합니다. 예를 들어,사용자가 항상 오후 1 시에 앱을 사용하는 경우 시스템은 학습 및 적응하여 사용 기간보다 앞서 페치를 수행합니다. 배경 가져 오기는 배터리 사용을 줄이기 위해 장치의 라디오에 의해 응용 프로그램을 통해 합체하고,당신이 가져 오는 동안 새로운 데이터를 사용할 수없는보고하는 경우,이 정보를 사용하여 적응 조용한 시간에 가져 오기를 방지 할 수 있습니다.

백그라운드 페치를 활성화하는 첫 번째 단계는 정보 플리스트의UIBackgroundModes키의 기능을 사용하도록 지정하는 것입니다. 이 작업을 수행하는 가장 쉬운 방법은 멀티 태스킹 옵션을 쉽게 구성 할 수있는 배경 모드 섹션을 포함 엑스 코드 5 의 프로젝트 편집기의 새로운 기능 탭을 사용하는 것입니다.

또는 키를 수동으로 편집할 수 있습니다:

<key>UIBackgroundModes</key><array> <string>fetch</string></array>

그런 다음 가져오려는 빈도를 알려줍니다:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ ; return YES;}

기본 가져 오기 간격은 결코,그래서 당신은 시간 간격을 설정해야합니다 또는 응용 프로그램은 지금까지 백그라운드에서 호출되지 않습니다. 값UIApplicationBackgroundFetchIntervalMinimum은 앱이 깨어날 때를 가능한 한 자주 관리하도록 시스템에 요청하지만,이것이 불필요한 경우 사용자 고유의 시간 간격을 지정해야 합니다. 예를 들어 날씨 앱은 매시간 조건만 업데이트할 수 있습니다. 이오스는 배경 가져 오기 사이에 적어도 지정된 시간 간격을 기다립니다.

응용 프로그램에서 사용자가 로그아웃을 허용하고 새 데이터가 없는 경우minimumBackgroundFetchIntervalUIApplicationBackgroundFetchIntervalNever로 다시 설정하여 좋은 시민이 되고 리소스를 보존할 수 있습니다.

마지막 단계는 응용 프로그램 대리자에 다음 메서드를 구현하는 것입니다:

- (void) application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{ NSURLSessionConfiguration *sessionConfiguration = ; NSURLSession *session = ; NSURL *url = initWithString:@"http://yourserver.com/data.json"]; NSURLSessionDataTask *task = ; // Start the task ;}

시스템에서 깨울 때 작업을 수행할 수 있습니다. 새 콘텐츠를 사용할 수 있는지 여부를 확인하고,새 콘텐츠를 처리하고,사용자 인터페이스를 업데이트하는 데 30 초 밖에 걸리지 않습니다. 이 네트워크에서 데이터를 가져 오기 및 사용자 인터페이스에 대한 몇 가지 축소판을 가져올 수있는 충분한 시간이어야하지만,훨씬 더. 네트워크 요청이 완료되고 사용자 인터페이스가 업데이트되면 완료 처리기를 호출해야 합니다.

완료 핸들러는 두 가지 용도로 사용됩니다. 먼저,시스템은 프로세스에서 사용하는 전력을 측정하고 전달한UIBackgroundFetchResult인수를 기반으로 새 데이터를 사용할 수 있는지 여부를 기록합니다. 둘째,완료 처리기를 호출하면 사용자 인터페이스의 스냅샷이 만들어지고 앱 전환기가 업데이트됩니다. 사용자는 앱을 전환할 때 새 콘텐츠를 볼 수 있습니다. 이 완료 처리기 스냅숏 동작은 새 멀티태스킹 실행기의 모든 완료 처리기에 공통적입니다.

실제 응용 프로그램에서는completionHandler을 응용 프로그램의 하위 구성 요소로 전달하고 데이터를 처리하고 사용자 인터페이스를 업데이트하면 호출해야 합니다.

이 시점에서 앱이 백그라운드에서 실행될 때 앱의 사용자 인터페이스를 스냅숏할 수 있는 방법과 백그라운드 가져오기와 함께 응용 프로그램 수명 주기가 어떻게 작동하는지 궁금할 수 있습니다. 앱이 현재 일시 중단된 경우 시스템은application: performFetchWithCompletionHandler:을 호출하기 전에 앱을 깨웁니다. 앱이 실행되고 있지 않으면 시스템에서application: didFinishLaunchingWithOptions:를 포함한 일반적인 대리자 메서드를 호출하여 앱이 실행됩니다. 이 앱은 사용자가 스프링보드에서 실행한 것과 정확히 같은 방식으로 실행된다고 생각할 수 있습니다.

대부분의 경우 포그라운드에서와 마찬가지로 백그라운드에서 응용 프로그램을 시작할 때 동일한 작업을 수행합니다.:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ NSLog(@"Launched in background %d", UIApplicationStateBackground == application.applicationState); return YES;}

백그라운드 가져 오기 테스트

백그라운드 가져 오기를 시뮬레이션 할 수있는 두 가지 방법이 있습니다. 가장 쉬운 방법은 엑스 코드에서 응용 프로그램을 실행하고 응용 프로그램이 실행되는 동안 엑스 코드의 디버그 메뉴에서 배경 가져 오기 시뮬레이션을 클릭하는 것입니다.

또는 구성표를 사용하여 엑스 코드가 앱을 실행하는 방법을 변경할 수 있습니다. 엑스 코드 메뉴 항목 제품 아래에서 구성표를 선택한 다음 구성표 관리를 선택합니다. 여기에서 새 구성표를 편집 또는 추가하고 아래 그림과 같이 배경 가져 오기 이벤트 체크 박스로 인해 실행을 확인하십시오.

원격 알림

원격 알림을 사용하면 중요한 이벤트가 발생할 때 앱에 알릴 수 있습니다. 새 인스턴트 메시지,속보 알림 또는 사용자가 좋아하는 최신 에피소드를 오프라인에서 볼 수 있도록 다운로드할 준비가 되어 있을 수 있습니다. 원격 알림은 백그라운드 가져오기 사이의 지연이 허용되지 않을 수 있는 산발적이지만 즉시 중요한 콘텐츠에 적합합니다. 또한 원격 알림은 필요한 경우에만 응용 프로그램이 실행되므로 백그라운드 페치보다 훨씬 효율적일 수 있습니다.

원격 알림은 실제로content-available플래그가 설정된 일반 푸시 알림입니다. 백그라운드에서 사용자 인터페이스를 업데이트하는 동안 사용자에게 문제가 발생했음을 알리는 경고 메시지가 포함된 푸시를 보낼 수 있습니다. 그러나 원격 알림은 앱의 인터페이스를 업데이트하거나 백그라운드 작업을 트리거하는 데만 사용되는 경고 메시지 또는 소리를 포함하지 않는 무음 일 수도 있습니다. 그런 다음 새 콘텐츠 다운로드 또는 처리가 완료되면 로컬 알림을 게시할 수 있습니다.

자동 푸시 알림은 속도 제한,그래서 응용 프로그램이 필요로하는만큼을 보내는 것을 두려워하지 않습니다. 그리고 당신은 너무 많은 전송에 대한 문제로 얻을 수 없습니다. 푸시 알림이 제한되는 경우 다음에 장치가 연결 유지 패킷을 보내거나 다른 알림을 받을 때까지 지연될 수 있습니다.

원격 알림 보내기

원격 알림을 보내려면 푸시 알림 페이로드에서 콘텐츠 사용 가능 플래그를 설정합니다. 콘텐츠 사용 가능 플래그는 뉴스 스탠드 앱에 알리는 데 사용되는 키와 동일하므로 대부분의 푸시 스크립트 및 라이브러리는 이미 원격 알림을 지원합니다. 원격 알림을 보낼 때 응용 프로그램에서 이벤트를 참조할 수 있도록 알림 페이로드에 일부 데이터를 포함할 수도 있습니다. 이렇게 하면 몇 가지 네트워킹 요청을 절약하고 앱의 응답성을 높일 수 있습니다.

나는 개발하는 동안 푸시 메시지를 보낼 노매드 클리의 휴스턴 유틸리티를 사용하는 것이 좋습니다,하지만 당신은 당신의 마음에 드는 라이브러리나 스크립트를 사용할 수 있습니다.

휴스턴을 노매드 클리루비 젬의 일부로 설치할 수 있습니다.:여기서-n플래그는 콘텐츠 사용 가능한 키가 포함되어야 함을 지정하고-d는 페이로드에 자체 데이터 키를 추가할 수 있도록 합니다.

결과 알림 페이로드는 다음과 같습니다:

{ "aps" : { "content-available" : 1 }, "content-id" : 42}

이 메서드는 콘텐츠 사용 가능 키가 포함된 푸시 알림을 받을 때 호출됩니다:

- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{ NSLog(@"Remote Notification userInfo is %@", userInfo); NSNumber *contentID = userInfo; // Do something with the content ID completionHandler(UIBackgroundFetchResultNewData);}

다시 앱이 백그라운드로 실행되고 완료 핸들러를 호출하기 전에 새 콘텐츠를 가져오고 사용자 인터페이스를 업데이트하는 데 30 초가 주어집니다. 백그라운드 가져오기 예제에서와 같이 빠른 네트워크 요청을 수행할 수 있지만 강력한 새 백그라운드 전송 서비스를 사용하여 대규모 다운로드 작업을 대기열에 넣고 완료되면 사용자 인터페이스를 업데이트하는 방법을 살펴보겠습니다.그러나,그것은 또한 재단 네트워킹의 새로운 기술을 의미한다. NSURLConnection을 대체하기 위해NSURL,NSURLRequestNSURLResponse와 같은 친숙한 개념과 클래스가 보존됩니다. NSURLConnection의 대체NSURLSessionTask을 사용하여 네트워크 요청을 수행하고 응답을 처리합니다. 세 가지 유형의 세션 작업(데이터,다운로드 및 업로드)이 각각NSURLSessionTask에 구문 설탕을 추가하므로 사용 사례에 적합한 작업을 사용해야 합니다.

NSURLSession는 이러한NSURLSessionTask중 하나 이상을 조정하고 생성 된NSURLSessionConfiguration에 따라 작동합니다. 여러 개의NSURLSession를 만들어 동일한 구성으로 관련 작업을 그룹화할 수 있습니다. 백그라운드 전송 서비스와 상호 작용하려면를 사용하여 세션 구성을 만듭니다. 백그라운드 세션에 추가된 작업은 외부 프로세스에서 실행되며 앱이 일시 중단되거나 중단되거나 종료된 경우에도 계속됩니다.

NSURLSessionConfiguration를 사용하면 기본 헤더를 설정하고 캐시 정책을 구성하며 셀룰러 네트워크 사용을 제한하는 등의 작업을 수행할 수 있습니다. 한 가지 옵션은discretionary플래그로,시스템이 최적의 성능을 위해 작업을 예약 할 수 있습니다. 이것이 의미하는 것은 장치가 충분한 전력이있을 때 전송은 무선 랜을 통해 갈 것입니다. 배터리가 부족하거나 셀룰러 연결만 사용할 수 있는 경우 작업이 실행되지 않습니다. discretionary플래그는backgroundSessionConfiguration:메서드를 호출하여 세션 구성 개체를 생성한 경우와 앱이 포그라운드에 있는 동안 백그라운드 전송이 시작된 경우에만 영향을 줍니다. 전송이 백그라운드에서 시작되면 전송은 항상 임의 모드로 실행됩니다.

이제NSURLSession에 대해 조금 알고 있으며 백그라운드 세션이 어떻게 작동하는지 원격 알림 예제로 돌아가서 백그라운드 전송 서비스에서 다운로드를 큐에 넣는 코드를 추가하겠습니다. 다운로드가 완료되면 파일을 사용할 수 있음을 사용자에게 알립니다.먼저 원격 알림을 처리하고 백그라운드 전송 서비스에서NSURLSessionDownloadTask을 큐에 넣겠습니다. backgroundURLSession에서는 백그라운드 세션 구성을 사용하여NURLSession를 만들고 응용 프로그램 대리자를 세션 대리자로 추가합니다. 이 설명서에서는 동일한 식별자로 여러 세션을 인스턴스화하는 것을 권장하지 않으므로dispatch_once를 사용하여 잠재적 인 문제를 방지 할 수 있습니다:

- (NSURLSession *)backgroundURLSession{ static NSURLSession *session = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSString *identifier = @"io.objc.backgroundTransferExample"; NSURLSessionConfiguration* sessionConfig = ; session = ]; }); return session;}- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{ NSLog(@"Received remote notification with userInfo %@", userInfo); NSNumber *contentID = userInfo; NSString *downloadURLString = ]; NSURL* downloadURL = ; NSURLRequest *request = ; NSURLSessionDownloadTask *task = downloadTaskWithRequest:request]; task.taskDescription = ]; ; completionHandler(UIBackgroundFetchResultNewData);}

NSURLSession클래스 메서드를 사용하여 다운로드 작업을 만들고 요청을 구성하고 나중에 사용할 설명을 제공합니다. 모든 세션 작업이 일시 중단된 상태에서 시작되므로 실제로 작업을 시작하려면를 호출해야 합니다.

이제 다운로드가 완료되면 콜백을 받기 위해NSURLSessionDownloadDelegate메서드를 구현해야 합니다. 세션 수명 주기에서 인증 또는 기타 이벤트를 처리해야 하는 경우NSURLSessionDelegate또는NSURLSessionTaskDelegate메서드를 구현해야 할 수도 있습니다. 이는 모든 유형의 세션 작업에 대한 전체 수명 주기를 설명합니다.

NSURLSessionDownloadDelegate대리자 메서드 중 선택 사항은 없지만 이 예제에서 조치를 취해야 하는 메서드는뿐입니다. 작업 다운로드가 완료되면 디스크에 있는 파일에 대한 임시 링크가 제공됩니다. 이 대리자 메서드에서 반환할 때 임시 저장소에서 제거되므로 파일을 앱의 저장소로 이동하거나 복사해야 합니다.

#Pragma Mark - NSURLSessionDownloadDelegate- (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ NSLog(@"downloadTask:%@ didFinishDownloadingToURL:%@", downloadTask.taskDescription, location); // Copy file to your app's storage with NSFileManager // ... // Notify your UI}- (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{}- (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{}

백그라운드 세션 작업이 완료될 때 앱이 여전히 포그라운드에서 실행 중이면 위의 코드로 충분합니다. 그러나 대부분의 경우 앱이 실행되지 않거나 백그라운드에서 일시 중단됩니다. 이러한 경우 시스템에서 응용 프로그램을 깨울 수 있도록 두 개의 응용 프로그램 대리자 메서드를 구현해야 합니다. 이전 대리자 콜백과 달리 세션 및 작업 대리자가 여러 메시지를 받을 수 있으므로 응용 프로그램 대리자는 두 번 호출됩니다. 앱 대리자 메서드application: handleEventsForBackgroundURLSession:는 이러한NSURLSession대리자 메시지를 보내기 전에 호출되고URLSessionDidFinishEventsForBackgroundURLSession은 이후에 호출됩니다. 이전 메서드에서는 배경completionHandler을 저장하고 후자에서는 사용자 인터페이스를 업데이트하기 위해 이 메서드를 호출합니다:

- (void) application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{ // You must re-establish a reference to the background session, // or NSURLSessionDownloadDelegate and NSURLSessionDelegate methods will not be called // as no delegate is attached to the session. See backgroundURLSession above. NSURLSession *backgroundSession = ; NSLog(@"Rejoining session with identifier %@ %@", identifier, backgroundSession); // Store the completion handler to update your UI after processing session events ;}- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{ NSLog(@"Background URL session %@ finished events.\n", session); if (session.configuration.identifier) { // Call the handler we stored in -application:handleEventsForBackgroundURLSession: ; }}- (void)addCompletionHandler:(CompletionHandlerType)handler forSession:(NSString *)identifier{ if () { NSLog(@"Error: Got multiple handlers for a single session identifier. This should not happen.\n"); } ;}- (void)callCompletionHandlerForSession: (NSString *)identifier{ CompletionHandlerType handler = ; if (handler) { ; NSLog(@"Calling completion handler for session %@", identifier); handler(); }}

이 2 단계 프로세스는 백그라운드 전송이 완료될 때 아직 포그라운드에 있지 않은 경우 앱 사용자 인터페이스를 업데이트하는 데 필요합니다. 또한 백그라운드 전송이 완료될 때 앱이 전혀 실행되지 않으면 백그라운드에서 앱이 실행되고 이전 응용 프로그램 및 세션 대리자 메서드는application:didFinishLaunchingWithOptions:이후에 호출됩니다.

구성 및 제한

백그라운드 전송의 힘에 대해 간략하게 설명했지만 사용 사례를 가장 잘 지원하는NSURLSessionConfiguration옵션을 살펴보아야 합니다. 예를 들어NSURLSessionTasksNSURLSessionConfigurationtimeoutIntervalForResource속성을 통해 리소스 시간 제한을 지원합니다. 당신은 당신이 완전히 포기하기 전에 전송을 완료 할 수 있도록 할 기간을 지정하려면이 옵션을 사용할 수 있습니다. 당신은 당신의 콘텐츠를 제한된 시간 동안 만 사용할 수 있습니다,또는 오류가 주어진 시간 내에 자원을 다운로드하거나 업로드하는 경우에이 기능을 사용할 수 있습니다인터뷰는 사용자가 충분한 무선 랜 대역폭이없는 것을 나타냅니다.

다운로드 작업 외에도NSURLSession는 업로드 작업을 완벽하게 지원합니다. 전송이 완료될 때 백그라운드에서 앱을 시작할 필요가 없는 경우NSURLSessionConfigurationsessionSendsLaunchEvents속성을NO로 설정하는 것이 좋습니다. 시스템 자원의 효율적인 사용은 이오스와 사용자 모두 행복 유지.

마지막으로 백그라운드 세션 사용에는 몇 가지 제한이 있습니다. 대리자가 필요하므로NSURLSession에서 간단한 블록 기반 콜백 메서드를 사용할 수 없습니다. 앱을 백그라운드로 시작하는 것은 상대적으로 비용이 많이 듭니다. 사용자 지정 프로토콜을 사용할 수 없습니다. 이 시스템은 사용 가능한 리소스를 기반으로 전송을 최적화하고 당신은 항상 백그라운드에서 진행 전송을 강제 할 수 없습니다.

또한NSURLSessionDataTasks는 백그라운드 세션에서는 전혀 지원되지 않으며 다운로드나 업로드가 아닌 수명이 짧은 작은 요청에만 이러한 작업을 사용해야 합니다.새로운 멀티태스킹과 네트워킹을 통해 새로운 앱과 기존 앱 모두를 위한 다양한 가능성을 열어줍니다. 처리되지 않은 네트워크 전송 및 최신 데이터의 이점을 활용할 수 있는 앱의 사용 사례를 고려해 보십시오. 일반적으로 응용 프로그램이 포그라운드에서 실행되는 것처럼 백그라운드 전송을 구현하여 적절한 사용자 인터페이스를 업데이트하고 대부분의 작업이 이미 완료되었습니다.

  • 앱 콘텐츠에 적합한 새 앱을 사용합니다.

  • 효율적이고 가능한 한 일찍 완료 핸들러를 호출하십시오.

  • 완료 처리기는 앱의 사용자 인터페이스 스냅샷을 업데이트합니다.

추가 읽기

  • 멀티 태스킹의 새로운 기능”

  • “재단 네트워킹의 새로운 기능”

  • 로드 시스템 프로그래밍 가이드

답글 남기기

이메일 주소는 공개되지 않습니다.