2016-03-04 52 views
3

我想写一个使用Swift扩展的委托方法的默认行为如下,但它永远不会被调用。有谁知道为什么或如何以正确的方式做到这一点?Swift扩展的协议方法的默认实现

extension NSURLSessionDelegate { 

    public func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { 
     //default behaviour here 
    } 
} 

添加override也不起作用。

this, 苹果的默认实现是这样的:

extension NSURLSessionDelegate { 
    func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) { } 
    func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { } 
} 

我DataTask要求通常是这样的:

let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration() 
    sessionConfiguration.HTTPCookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage() 
let session = NSURLSession(configuration: sessionConfiguration) 
let requestURL = NSURL(string:"https:www.google.com/blabla") 

session.dataTaskWithURL(requestURL!, completionHandler: completion).resume() 

completion通常会通过参数收到了斯威夫特关闭。

我需要在整个应用程序中为所有nsurlsessiontask实现实现URLSession(... didReceiveChallenge ...)函数,但无法设置会话的委托,因为我需要使用completionHandler(正如我在下面的评论中提到的那样)。

+1

如果你在委托中实现了你的方法,那么这个方法是否被调用?也许委托方法不会被调用。否则你的实现看起来很好。 –

+0

我用'dataTaskWithURL'和一个completionHandler(我不能通过委托来改变其他原因),所以在创建session时我不能为我的'NSURLSession'设置一个特定的委托 - else completionHandler isn不叫。另见我更新的问题。 – Stephan

回答

2

您可以扩展NSURLSessionDelegate协议以添加默认实现,但您的NSURLSession对象需要委托。

此委托只能通过设置+sessionWithConfiguration:delegate:delegateQueue:(因为委托财产read only),所以你唯一的办法将其设置是继承NSURLSession,覆盖+sessionWithConfiguration:并调用与委托财产的初始化。这里的问题是您必须将所有NSURLSession对象替换为MyCustomSessionClass。对象。

我建议你创建一个SessionCreator类,它将符合NSURLSessionDelegate协议并将创建NSURLSession对象。您仍然需要替换对象的创建,但至少该对象不是其自身的委托。

public class SessionCreator:NSObject,NSURLSessionDelegate { 

    //MARK: - Singleton method  
    class var sharedInstance :SessionCreator { 
     struct Singleton { 
      static let instance = SessionCreator() 
     } 
     return Singleton.instance 
    } 

    //MARK: - Public class method  
    public class func createSessionWithConfiguration (configuration:NSURLSessionConfiguration) -> NSURLSession { 
     return sharedInstance.createSessionWithConfiguration(configuration) 
    } 

    //MARK: - Private methods 
    private func createSessionWithConfiguration (configuration:NSURLSessionConfiguration) -> NSURLSession { 
     return NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil) 
    } 

    //MARK: - NSURLSessionDelegate protocol conformance 
    public func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { 
     // Always called since it's the delegate of all NSURLSession created using createSessionWithConfiguration 
    } 
} 

// Let create a NSURLSession object : 
let session = SessionCreator.createSessionWithConfiguration(NSURLSessionConfiguration()) 
+1

您可以扩展NSURLSessionDelegate协议以添加默认实现,但您的NSURLSession对象需要一个委托。搞定了。 – Stephan