【问题标题】:Call view controller function from delegate class从委托类调用视图控制器函数
【发布时间】:2019-11-23 09:51:24
【问题描述】:

我对 swift 比较陌生,尝试从我定义的委托调用视图控制器中的函数时遇到问题。如何从这个委托调用我的视图控制器中的函数?这是一个混合项目,主要由 Objective-C 代码组成,只有一个 Swift 控制器。该函数位于 Swift 控制器内部。下面是委托类:

class DelegateToHandle302:NSObject, URLSessionTaskDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {

    //convert to https
    let http = request.url!
    var comps = URLComponents(url: http, resolvingAgainstBaseURL: false)!
    comps.scheme = "https"
    let httpsUrl = comps.url!

    ViewControllerFunction(url: httpsUrl)

}

我收到错误使用未解析的标识符“ViewControllerFunction”。我尝试创建视图控制器的一个实例,但不认为这是正确的方法,因为这个视图控制器也有一个音频播放器(它也没有工作)。

这里是我从视图控制器中的函数调用委托的地方:

    let urlString = "https://urlthatredirects.com"
    let config = URLSessionConfiguration.default
    let url = URL(string: urlString)

    //set delegate value equal to SessionDelegate to handle 302 redirect
    let delegate = DelegateToHandle302()

    //establish url session
    let session = URLSession(configuration: config, delegate: delegate, delegateQueue: nil)

    //set task with url
    let dataTask = session.dataTask(with: url!)

    //init call
    dataTask.resume()

我正在关注有关如何从重定向 (https://gist.github.com/mgersty/b565ba4c9e9422637f15f52a5317f07e) 获取最终 URL 的示例的一部分。我的视图控制器“标题”是:

@objc class AudioPlayerController: UIViewController{........}

我希望我已经提供了足够的信息,以便任何人都可以帮助我找出我做错了什么。我唯一需要做的就是调用该函数并将重定向 URL 传递给它。

【问题讨论】:

    标签: swift delegates


    【解决方案1】:

    我对您要做什么以及为什么要尝试将委托方法调用回 VC 而不是使用完成处理程序感到有些困惑;但我认为你的委托模式是从后到前的。我假设这个想法是:

    1. 视图控制器发起 URL 会话
    2. url会话将URLSession的结果传递给DelegateToHandle302处理
    3. DelegateToHandle302 然后尝试在启动它的视图控制器中运行一个方法。

    如果是这种情况,您实际上需要 VC 作为 DelegateToHandle302 类的委托,而不是相反。

    所以在你的视图控制器中

    let handlerFor302 = DelegateToHandle302()
    handlerFor302.delegate = self. 
    
    let session = URLSession(configuration: config, delegate: handlerFor302, delegateQueue: nil
       //etc... as before
    

    创建一个协议供委托采用,它定义了所需的功能

    protocol URLProcessor {
       func  ViewControllerFunction(url: URL)
    }
    

    在你的视图控制器中采用协议并实现方法

    extension MyViewController: URLProcessor {
       func  ViewControllerFunction(url: URL) { .... do whatever ...}
    

    然后将委托与您的 DelegateToHandle302 中的协议方法一起使用

    class DelegateToHandle302:NSObject, URLSessionTaskDelegate {
       weak var delegate: URLProcessor? 
    
       func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
    
        //Process the output
    
        delegate?.ViewControllerFunction(url: httpsUrl)
    }
    
    
    
    

    【讨论】:

    • 这很有效,感谢您的详细解释。为了使那个弱 var 委托: URLProcessor?工作,我还必须使协议继承自类(协议 URLProcessor:类 {...}。您是否建议我不要使用从后到前的模式进行委派?
    • 我的音频不再播放有什么原因吗?在 ViewControllerFunction 内部,我有以下内容: let playerItem:AVPlayerItem = AVPlayerItem(url: httpsUrl);播放器 = AVPlayer(playerItem: playerItem);播放器?.play();
    • 我想我也说得太早了,似乎weak var delegate: URLProcessor? 总是为零,所以这不起作用。我不知道为什么。
    • 不确定为什么 URLProcessorprotocol 需要继承其他协议 - 它应该是符合这两种协议的 VC。
    • 在 VC 中,您专门在 handlerFor302.delegate = self 中设置了委托,所以我看不出它可以为 nil 的任何方式,除非您在某些时候重新初始化“handlerFor302”,然后用委托覆盖实例属性集。使用 viewController 中的相关代码更新问题可能会有所帮助。
    猜你喜欢
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 2023-03-05
    • 2013-10-26
    • 1970-01-01
    相关资源
    最近更新 更多