ios - 带有 Swift 扩展的协议(protocol)方法的默认实现

标签 ios nsurlsession swift-extensions protocol-extension

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

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 ...) 函数,但无法将我的 session 委托(delegate)设置为我需要使用 completionHandler(如我在下面的评论中所述)。

最佳答案

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

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

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

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

关于ios - 带有 Swift 扩展的协议(protocol)方法的默认实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35790901/

相关文章:

iOS IAP-需要有关高级版应用程序的建议

iPhone SDK :NSScanner crashing randomly

ios - 使默认 session 无效 - NSURLSession

objective-c - NSMutableURLRequest setTimeoutInterval 在 ios 11.0 中不起作用

ios - NSURLSession 错误域=NSPOSIXErrorDomain 代码=2 "No such file or directory"

ios - 在 Swift 中使用可编码扩展更新对象属性

swift - 从字节数组到结构的转换。 swift

iOS 创建具有动态内容的 PDF

swift - 使用协议(protocol)切换通用数值函数

ios - 将 iOS 应用程序组迁移到另一个开发者帐户