在 iOS 15 中未分配 Alamofire 4.9.1 sessionManager.delegate.sessionDidReceiveChallenge

Posted

技术标签:

【中文标题】在 iOS 15 中未分配 Alamofire 4.9.1 sessionManager.delegate.sessionDidReceiveChallenge【英文标题】:Alamofire 4.9.1 sessionManager.delegate.sessionDidReceiveChallenge is not getting assigned in iOS 15 【发布时间】:2021-12-02 08:04:25 【问题描述】:

我正在开发的 ios 应用程序使用的是 Alamofire 4.9.1,以下代码在 iOS 14 及更低版本中执行没有任何问题,但在 iOS 15 中没有。

dataProvider.sessionDelegate.sessionDidReceiveChallenge =  _, challenge in
                
                print("CHALLENGE ACCEPTED")
                
                if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate 

                    return (URLSession.AuthChallengeDisposition.useCredential,
                            cert.urlCredential())
                

                if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust 

                    return (URLSession.AuthChallengeDisposition.useCredential,
                            URLCredential(trust: challenge.protectionSpace.serverTrust!));
                

                return (URLSession.AuthChallengeDisposition.performDefaultHandling,
                        Optional.none)
            

,其中 cert 是在此之前初始化的 .pfx 证书。

这会阻止应用访问具有基于 TLS 1.2 证书的身份验证的服务器上的信息。在 iOS 13 和 14(支持的 iOS 版本从 13 开始)中执行打印语句,但由于某种原因在 iOS 15 中不执行。在 iOS 13 和 14 中,在 Alamofire 的 SessionDelegate.swift 中,

open func urlSession(
        _ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)

被调用,但在 iOS 15 中被调用替换为

open func urlSession(
        _ session: URLSession,
        task: URLSessionTask,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)

关于什么可能导致此问题以及如何解决它的任何想法?提前谢谢你。

【问题讨论】:

【参考方案1】:

有趣的是,这可能已经改变,因为记录的行为没有:NSURLAuthenticationMethodServerTrust 挑战应该由会话的代表接收,而不是任务的,除非会话代表根本没有实现该方法。我会将此问题报告给 Apple,以便他们可以修复文档或委托回调本身。

无论如何,Alamofire 4 是不受支持的,这个问题不会得到解决。请更新到 Alamofire 5,它通过仅实现此方法的 URLSessionTaskDelegate 版本并为此逻辑提供单个挂钩来纠正此问题。

【讨论】:

谢谢你的回答,我解决了这个问题,详情如下。【参考方案2】:

我设法通过修改 Alamofire pod 本身的 SessionDelegate.swift 文件解决了这个问题。即,我在 SessionDelegate.swift 文件中初始化了证书,并将其 urlCredential 属性传递给了任务委托的凭据属性

open func urlSession(
    _ session: URLSession,
    task: URLSessionTask,
    didReceive challenge: URLAuthenticationChallenge,
    completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)

,它奏效了。

所以我重新定义了类 (PKCS12),让我可以在 SessionDelegate.swift 文件中初始化证书,上述函数的主体现在如下所示:

if let taskDidReceiveChallenge = taskDidReceiveChallenge 
        let result = taskDidReceiveChallenge(session, task, challenge)
        completionHandler(result.0, result.1)
     else if let delegate = self[task]?.delegate 
        // this gets executed in iOS 15 and we need to get a credential in order for the delegate to successfully set the disposition required for getting data from the server
        let cert = PKCS12.init(mainBundleResource: "\(certNameHere)",
                               resourceType: "pfx",
                               password: "%^&^%*&")
        delegate.credential = cert.urlCredential()
        delegate.urlSession(
            session,
            task: task,
            didReceive: challenge,
            completionHandler: completionHandler
        )
     else 
        urlSession(session, didReceive: challenge, completionHandler: completionHandler)
    

这已经为我们解决了这个问题,我希望它对可能在 iOS 15 和 Alamofire 4.9.1 中遇到类似问题的其他人有所帮助。感谢您的阅读。

【讨论】:

以上是关于在 iOS 15 中未分配 Alamofire 4.9.1 sessionManager.delegate.sessionDidReceiveChallenge的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire 5中未设置授权标头?

Swift 3 / Alamofire 4:在 TableView 上使用 ID 获取数据

在 iOS 中未调用 textFieldShouldReturn

共享偏好 Swift 4- iOS- 唯一 Alamofire 用户 ID

更新到iOS 11.1后,Alamofire 4.5.1失败

类型“any”在alamofire 4 iOS swift中没有下标成员[重复]