【问题标题】:Default implementation of protocol method with Swift extension带有 Swift 扩展的协议方法的默认实现
【发布时间】:2016-03-04 21:09:19
【问题描述】:

我正在尝试使用如下的 Swift 扩展为委托方法编写默认行为,但它从未被调用。有谁知道为什么或如何以正确的方式做到这一点?

extension NSURLSessionDelegate {

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

添加override 也不起作用。

根据this, Apple 的默认实现如下所示:

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 通常是通过参数接收的 Swift 闭包。

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

【问题讨论】:

  • 如果你在你的委托中实现你的方法,这个方法是否被调用过?也许委托方法不会被调用。否则你的实现看起来不错。
  • 我将dataTaskWithURL 与completionHandler 一起使用(由于其他原因,我无法将其更改为通过委托进行管理),因此在创建时我无法为NSURLSession 设置特定委托session - 否则 completionHandler 不会被调用。另请参阅我更新的问题。

标签: ios nsurlsession swift-extensions protocol-extension


【解决方案1】:

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

这个delegate只能使用+sessionWithConfiguration:delegate:delegateQueue:设置(因为delegate属性是read only),所以设置它的唯一方法是继承NSURLSession,覆盖+sessionWithConfiguration:并使用delegate属性调用初始化器.这里的问题是您必须将所有NSURLSession 对象替换为MyCustomSessionClass。对象。

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

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())

【讨论】:

  • 你可以扩展 NSURLSessionDelegate 协议来添加默认实现,但是你的 NSURLSession 对象需要一个委托。搞定了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多