0

에서 호출되지 : URLSessionDownloadDelegate didFinishDownloadingTo이 같은 조치 연장 (<code>ActionRequestHandler</code>)에서 다운로드를 시작 배경

private lazy var urlSession: URLSession = { 
    let config = URLSessionConfiguration.background(withIdentifier: "de.stefantrauth.Downloader") 
    config.sharedContainerIdentifier = "group.de.stefantrauth.Downloader" 
    return URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) 
}() 

private func initiateDownloadOfFileFrom(url: URL) { 
    urlSession.downloadTask(with: url).resume() 
    completeRequest() // this tells the system the action extension is done with its work 
} 

그런 다음 다운로드가 백그라운드에서 아이폰 OS에 의해 처리된다.

이제 다운로드가 완료되면 iOS에서 호출하기 때문에 내 기본 응용 프로그램 AppDelegate에서 완료된 다운로드를 처리하려고합니다.

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping() -> Void) { 
    print("handleEventsForBackgroundURLSession") 
    urlSessionBackgroundCompletionHandler = completionHandler 
} 

이 메서드는 예상대로 백그라운드에서 호출됩니다.

AppDelegate도 다운로드 업데이트를 처리하기 위해 URLSessionDelegateURLSessionDownloadDelegate을 구현합니다. handleEventsForBackgroundURLSession이 배경에서 호출있어 이후에 특히 흥미

func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { 
    DispatchQueue.main.async { 
     print("urlSessionDidFinishEvents") 
     self.urlSessionBackgroundCompletionHandler?() 
     self.urlSessionBackgroundCompletionHandler = nil 
    } 
} 

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { 
    print("download finished to \(location.absoluteString)") 
    do { 
     let documentsURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) 
     let savedURL = documentsURL.appendingPathComponent(location.lastPathComponent) 
     try FileManager.default.moveItem(at: location, to: savedURL) 
     print("moved file to: \(savedURL.absoluteString)") 
    } catch { 
     print ("file error: \(error)") 
    } 
} 

모두 urlSessionDidFinishEventsdidFinishDownloadingTo가 호출되지 않는

있습니다. 앱을 포 그라운드로 다시 시작한 후에야 대리자 메서드가 호출됩니다.

왜 전화를받지 못하고 그 문제를 해결하려면 어떻게해야합니까?

는이 같은 handleEventsForBackgroundURLSessionURLSession을 만드는 시도 :

private func initUrlSessionWith(identifier: String) { 
    let config = URLSessionConfiguration.background(withIdentifier: identifier) 
    config.sharedContainerIdentifier = "group.de.stefantrauth.Downloader" 
    urlSession = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) 
} 

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping() -> Void) { 
    print("handleEventsForBackgroundURLSession") 
    initUrlSessionWith(identifier: identifier) 
    urlSessionBackgroundCompletionHandler = completionHandler 
} 

그러나이 문제가 해결되지 않았다.

질문하기 전에 : 예 시뮬레이터에 백그라운드 작업 처리에 문제가 있으므로 실제 장치에서이를 테스트하고 있습니다.

+0

코드가 내게 잘 보이기 때문에이 문제가 확장 프로그램에만 해당된다는 느낌이 들었습니다. 이것은 아마 Quinn 질문 일 것입니다. 개발자 포럼에 질문하십시오. 일반적인 팁에 관해서는 메인 스레드에서 세션 콜백을 실행할 이유가 없습니다. 당신은 이미 하나의 중요한 콜백을 주 스레드로 보내고있다. 그냥 아무것도주지 마라. 그러나 나는 이것이 당신의 문제의 원인이 아니라고 확신합니다. – dgatwood

답변

0

내 코드가 실제로 정확합니다. 내 디버깅 방법이 문제였습니다. Xcode를 통해 디버깅하는 대신 콘솔 로깅을 사용하면 정상적으로 작동합니다.

백그라운드 URL 세션 디버깅을 사용하는 방법에 대한 자세한 내용은 https://forums.developer.apple.com/message/263807#263807을 참조하십시오.