2016-08-23 2 views
2

대부분의 프로그래밍 경험은 Shell과 Python에 있습니다. 나는 "3 일 전"처럼 새로 워진 Swift를 처음 사용합니다. 왜 내 didFinishDownloadtingTo 내 downloadTask 완료되면 호출되지 않는 알아낼 수 없습니다. 여기 내 AppDelegate.swift 파일입니다 :내 URLDownloadTask 호출이 완료되지 않은 이유는 무엇입니까?

import Cocoa 

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate, URLSessionDelegate, URLSessionDownloadDelegate { 

@IBOutlet weak var window: NSWindow! 
@IBOutlet var progressind: NSProgressIndicator! 
@IBOutlet var outputtext: NSTextField! 



func applicationDidFinishLaunching(_ aNotification: Notification) { 

    // Insert code here to initialize your application 
    let requestURL: URL = URL(string: "https://www.apple.com")! 
    let urlRequest: URLRequest = URLRequest(url: requestURL as URL) 
    let session = URLSession.shared 
    let downloads = session.downloadTask(with: urlRequest) 
    print("starting download...") 
    downloads.resume() 

} 

func applicationWillTerminate(_ aNotification: Notification) { 
    // Insert code here to tear down your application 
} 

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){ 
    print("download finished!") 
} 


} 

내가 스위프트 3을 사용하고, 난 그냥 내 자신이 알아 내기에 충분한 문서를 찾을 수 없습니다.

나는 그것이 제대로 작동하지 않는 이유를 알아 내려고 노력하고있는 클래스를 선언하는 데 미친 듯이 갔다. 그래서 나는 또한 거기에 약간의 오류가 있다는 것을 확신한다.

파일을 성공적으로 다운로드 한 것으로 보입니다. 여러 URL을 사용해 보았습니다. 디버그 메뉴의 "Disk"및 "Network"섹션은 테스트 한 모든 URL에서 크기의 파일을 다운로드하는 것과 일관되게 나타납니다.

+0

무엇을 습득하려고합니까? 그냥 목적을 테스트? 당신이 물건을 다운로드하고 싶다면 당신은 Alamofire를 살펴볼 것을 제안합니다. Cocoapods와 같은 종속성 관리자를 사용하십시오. –

+0

정적 웹 페이지에서 파일을 가져 오려고합니다. 이것은 응용 프로그램이 시작되고 완료 될 때 한 번 나타납니다. 따라서 응용 프로그램의 초기 설치를 위해 하나의 파일을 다운로드하기 위해 전체 네트워킹 라이브러리를 다운로드하고 학습하는 것을 배우는 것은 나에게 너무 복잡해 보입니다. – Matt

답변

5

NSURLSession (Swift 3에서 URLSession)을 사용하면 위임자 또는 완료 핸들러를 사용할지 여부를 선택해야하며, 둘 다 사용하는 경우 완료 핸들러 만 호출됩니다. 귀하의 경우에는 delegate가 설정되어 있지 않으므로 위임 메소드에 대한 호출을 볼 수 없습니다.

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate, URLSessionDelegate, URLSessionDownloadDelegate { 

    func applicationDidFinishLaunching(_ aNotification: Notification) { 
     let requestURL: URL = URL(string: "https://www.apple.com")! 
     let urlRequest: URLRequest = URLRequest(url: requestURL as URL) 

     let config = URLSessionConfiguration.default 
     let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) 

     let downloads = session.downloadTask(with: urlRequest) 

     print("starting download...") 
     downloads.resume() 
    } 

    func applicationWillTerminate(_ aNotification: Notification) { 
     // Insert code here to tear down your application 
    } 

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){ 
     print("download finished!") 
    } 
} 

을 그리고 당신은 제대로라는 대리자 메서드를 볼 대신 다음 코드처럼 NSURLSession의 또 다른 초기화를 사용하여 delegate를 지정해야합니다.

이 도움이 되었기 바랍니다.

+0

완벽하게 작동했습니다! 이것은 두 번째 질문으로 이어집니다. 나는 여전히 대의원들이 어떻게 서로 "링크"하거나 함께 협력하는지 또는 그것이 무엇인지간에 확신하지 못한다. 이 경우 "self"가 내 AppDelegate.swift 파일입니까? 그렇다면 "self"를 "DownloadDelegate"로 대체하면 "didFinishDownloadingTo"메소드에 대해 "DownloadDelegate.swift"를 보도록 내 프로그램에 알릴 수 있습니까? – Matt

+0

@ user6684500 아니요, 위임 패턴을 처리하는 방식이 아니며 신중하게보고 다른 개체에 함수를 위임하면 위임을 매우 쉽게 이해할 수 있습니다. 위임 개체는 다른 개체 (위임 및 적절한 시간에 메시지를 보내면 [여기] (https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html)에 대한 자세한 내용을 볼 수 있습니다. 그리고 당신의 질문을 해결하면 답변을 받아주십시오 :) –

1

키는 "위임자"라는 단어에 있습니다. 그것은 셜록 홈즈 (Sherlock Holmes) 이야기에서 밤 시간의 개와 같습니다. 개는 밤에 아무것도하지 않았다. "delegate"이라는 단어는 코드에 나타나지 않습니다!

하지만 필요합니다. didFinishDownloadingTo대리인 메서드입니다. NSURLSession의 대리인 인 경우에만이 메서드를받을 수 있습니다. selfdelegate으로 설정해야합니다. 런타임은 마술처럼 마음을 읽지 않으며이 객체를 대리자로 사용한다는 것을 알고 있습니다. 당신은 에게라고 말해야합니다.

+0

네, 정말로 @matt입니다.하지만 그 것은'URLSession.shared'를 사용하고 있으며'URLSession'의'delegate'는 읽기 전용이므로 불가능합니다. 적어도 그런 식으로. –

+1

@VictorSigler 완벽하게 사실입니다. 나는 단지 개념을 분명히하려고 노력하고있다. 문제는 "didFinishDownloadtingTo가 호출되지 않은 이유를 파악할 수 없다"였습니다. 그리고 대답은 내가 말한 것입니다 : 그것은 당신이 대의원이 아니기 때문입니다. 나는 당신의 대답이 틀렸다는 것을 말하지 않았다. (실제로 완성 처리자에 대한 당신의 이야기는 완전히 넓다.). 당신의 대답은 OP에게 무엇을 할 지에 대해 OP에게 알릴 수있는 이점이 있습니다. 그러나 제 대답은 OP가 실제로 묻는 질문에 답하는 이점이 있습니다. 세상은 두 가지 모두를 위해 충분히 크다. – matt

+0

@matt 내 appDelegate에 didFinishDownloadingTo를 포함 시켰고 내 세션을 구성 할 때 위임자를 자기에게 설정했지만 여전히 그 메소드에 들어 가지 않습니다. 대리자 메서드가 호출되지 않는 다른 이유는 무엇입니까? 전체 세부 정보 : http://stackoverflow.com/questions/41488989/using-urlsession-and-background-fetch-together-with-remote-notifications-using-f – user2363025

관련 문제