在通用类中调用NSURLConnection委托方法 [英] NSURLConnection Delegate Methods Not Called In Generic Class

查看:85
本文介绍了在通用类中调用NSURLConnection委托方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

var data = NSMutableData()

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


func连接(didReceiveResponse:NSURLConnection !, didReceiveResponse响应:NSURLResponse!){
LF.log(didReceiveResponse)
}

func连接(连接:NSURLConnection !, didReceiveData ){
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?) - >无效
block!(结果,错误)
}
client.execute()

和ICCategoryModel类似:

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

这个想法是你通过API URL中,您会得到一个数组(或错误),而其中包含一些反映的对象而不是Dictionary。它来自我的LSwift库,并支持各种身份验证方法(buildin参数,cookie,头文件,身份验证挑战等)。 问题是我无法访问 NSURLConnection 的委托对象。我通过创建另一个RemoteDelegate类来创建解决方案,该类不是泛型类型,并将其设置为conn的委托。它现在可以工作,但它只是一个解决方法,我仍然在寻找问题的答案。



我的委托类:

  class LRestConnectionDelegate:NSObject {

var func_done :((NSURLResponse ?, NSData !, NSError!) - > Void) ?
var凭证:NSURLCredential?
无功响应:NSURLResponse?
var data:NSMutableData = NSMutableData()

func连接(连接:NSURLConnection,willSendRequestForAuthenticationChallenge挑战:NSURLAuthenticationChallenge){
如果challenge.previousFailureCount> 0 {
challenge.sender.cancelAuthenticationChallenge(挑战)
}否则,如果让凭证=凭证{
challenge.sender.useCredential(凭证,forAuthenticationChallenge:挑战)
} else {
LF.log(REST连接将挑战连接)


func连接(连接:NSURLConnection,didReceiveResponse a_response:NSURLResponse){
// LF .log(CONNECTION response,response)
response = a_response
}
func connection(连接:NSURLConnection,didReceiveData data_received:NSData){
//LF.log( CONNECTION data,data.length)
data.appendData(data_received)
}
func connectionDidFinishLoading(connection:NSURLConnection){
//LF.log(\"CONNECTION finished),连接)
if func_done!= nil {
func_done!(response,data,nil)
}
}
func_done {
func_done(response,nil,错误)
}
}
deinit {
//LF.log(\"DELEGATE deinit,self)
}
}

这可以在类中使用LRestClient< T:LFModel>

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


I have a test class that tries to reach to google with a NSURLConnection. If I try to make it generic, the NSURLConnectionDataDelegate methods are never called.

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")
    }
}

To test it (comment/uncomment the first/second line to compare):

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

Any idea please?

Update1: to answer comment 1, it's a REST client that handles network connection and parsing for you. I'd write a blog about this later (since it's still under development), but to give you the idea here's some demo code from my project:

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

And ICCategoryModel is like:

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

The idea is that you pass the API URL in, you get an array (or error) with some reflected objects instead of Dictionary. It's from my LSwift library and supports various authentications methods (buildin-parameters, cookie, header, authentication challenge etc.)

解决方案

One of the problem is that I can't access the delegate object of NSURLConnection. I came up with a solution by creating another RemoteDelegate class, which is not generic type, and set it as the delegate of "conn". It works for now but it's just a work-around, and I'm still looking for the answer to the question.

My delegate class:

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

And this works in class LRestClient<T: LFModel>:

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

这篇关于在通用类中调用NSURLConnection委托方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆