【问题标题】:NSURLConnection Delegate Methods Not Called In Generic ClassNSURLConnection 委托方法未在泛型类中调用
【发布时间】:2015-04-27 02:13:39
【问题描述】:

我有一个测试类,它试图通过NSURLConnection 访问谷歌。如果我尝试使其通用,则永远不会调用 NSURLConnectionDataDelegate 方法。

class Remote<T: NSObject>: NSObject, NSURLConnectionDelegate, NSURLConnectionDataDelegate {
//class Remote: NSObject, NSURLConnectionDelegate, NSURLConnectionDataDelegate {

    var data = NSMutableData()

    func connect(query:NSString) {
        var url =  NSURL(string:"http://www.google.com")!
        var request = NSURLRequest(URL: url)
        var conn = NSURLConnection(request: request, delegate: self, startImmediately: true)
    }


    func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
        LF.log("didReceiveResponse")
    }

    func connection(connection: NSURLConnection!, didReceiveData conData: NSData!) {
        LF.log("didReceiveData")
        self.data.appendData(conData)
    }

    func connectionDidFinishLoading(connection: NSURLConnection!) {
        LF.log("didFinished")
        //println(self.data)
    }


    deinit {
        println("deiniting")
    }
}

测试它(注释/取消注释要比较的第一/第二行):

    let remote = Remote<NSObject>()
    //let remote = Remote()
    remote.connect("")

有什么想法吗?

Update1:​​回答评论 1,它是一个 REST 客户端,为您处理网络连接和解析。我稍后会写一篇关于此的博客(因为它仍在开发中),但为了让您了解这里是我项目中的一些演示代码:

        let client = ICRestClient<ICCategoryModel>(api:IC.api.category_list)
        client.func_array = {
            (results: [ICCategoryModel]?, error: NSError?) -> Void in
            block!(results, error)
        }
        client.execute()

而 ICCategoryModel 是这样的:

class ICSubCategoryModel: ICModel {
    var name: String?
    var category_id: Int = 0
}

这个想法是你传入 API URL,你会得到一个包含一些反射对象的数组(或错误)而不是字典。它来自我的 LSwift 库,支持各种身份验证方法(内置参数、cookie、标头、身份验证挑战等)

【问题讨论】:

  • 你创建一个泛型类的目的是什么?你想用这种方法解决什么问题?
  • 我添加了带有演示的 update1。它比 CoreData 更容易使用——主要思想是,在现实世界中,大多数情况下我们只需要 JSON、Parse 等简单的技术,而 XML、AWS 等解决方案过于复杂。然而,为了构建简单的解决方案,有时我们需要编写一些不常见的代码。顺便说一句,swiftobjc 灵活得多,但我只是喜欢swift 的语法。

标签: ios swift generics


【解决方案1】:

其中一个问题是我无法访问NSURLConnection 的委托对象。我通过创建另一个不是泛型类型的 RemoteDelegate 类提出了一个解决方案,并将其设置为“conn”的委托。它现在有效,但这只是一种解决方法,我仍在寻找问题的答案。

我的委托类:

class LRestConnectionDelegate: NSObject {

    var func_done: ((NSURLResponse?, NSData!, NSError!) -> Void)?
    var credential: NSURLCredential?
    var response: NSURLResponse?
    var data: NSMutableData = NSMutableData()

    func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) {
        if challenge.previousFailureCount > 0 {
            challenge.sender.cancelAuthenticationChallenge(challenge)
        } else if let credential = credential {
            challenge.sender.useCredential(credential, forAuthenticationChallenge:challenge)
        } else {
            LF.log("REST connection will challenge", connection)
        }
    }
    func connection(connection: NSURLConnection, didReceiveResponse a_response: NSURLResponse) {
        //LF.log("CONNECTION response", response)
        response = a_response
    }
    func connection(connection: NSURLConnection, didReceiveData data_received: NSData) {
        //LF.log("CONNECTION data", data.length)
        data.appendData(data_received)
    }
    func connectionDidFinishLoading(connection: NSURLConnection) {
        //LF.log("CONNECTION finished", connection)
        if func_done != nil {
            func_done!(response, data, nil)
        }
    }
    func connection(connection: NSURLConnection, didFailWithError error: NSError) {
        //LF.log("CONNECTION failed", error)
        if let func_done = func_done {
            func_done(response, nil, error)
        }
    }
    deinit {
        //LF.log("DELEGATE deinit", self)
    }
}

这适用于class LRestClient&lt;T: LFModel&gt;

        let delegate = LRestConnectionDelegate()
        delegate.credential = credential
        delegate.func_done = func_done
        connection = NSURLConnection(request:request, delegate:delegate, startImmediately:true)

【讨论】:

  • 对于那些和我遇到同样问题的人来说,如果你可以使用 iOS 7+,也许从 NSURLSession 而不是 NSURLConnection 开始会更好。我计划使用NSURLSession 重写我的所有连接代码,以支持使用不是 2xx 的 HTTP 代码的响应正文,这是某些服务器所要求的。
【解决方案2】:

因为您正在同步使用 NSURLConnection,所以您必须在主运行循环中安排操作。将以下代码添加到 connect 函数的末尾:

conn?.scheduleInRunLoop(NSRunLoop.currentRunLoop, forMode: NSDefaultRunLoopMode)

或者,将startImmediately 设置为NO 并调用conn?.start()

【讨论】:

  • 这与这个问题无关,但是如果您遇到类似的问题(NSURLConnectionDataDelegate 未调用),您可以试试这个。您也可以尝试将 conn 移出,使其成为类属性。然而,这个问题只是关于泛型类型。
  • 不,不是。他想知道为什么他的委托方法没有被调用。这很可能是因为连接没有通过在运行循环中调度来启动。
  • 对不起,我是那个提出问题的人,不管有没有 &lt;T: NSObject&gt; 部分都会做出改变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-03
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
相关资源
最近更新 更多