Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 3-为HTTP调用创建可重用类_Swift_Http - Fatal编程技术网

Swift 3-为HTTP调用创建可重用类

Swift 3-为HTTP调用创建可重用类,swift,http,Swift,Http,虽然在.net中有经验,但这里有点快 我正在尝试创建我的第一个应用程序,并使代码尽可能模块化和可重用。因此,我试图创建一个类,它允许我发出简单的HTTPGET请求并返回结果文本,如果需要,还可以选择返回JSON。我已将代码粘贴到下面。我遇到的问题是,我的函数在HTTP调用完成之前返回,因此返回一个空对象。我想我知道为什么会发生这种情况,因为我正在对任务调用resume,然后该任务正在执行并等待回调函数被调用——但与此同时,代码执行仍在继续,因此我返回一个空对象。那么…这里推荐的方法是什么?我是否

虽然在.net中有经验,但这里有点快

我正在尝试创建我的第一个应用程序,并使代码尽可能模块化和可重用。因此,我试图创建一个类,它允许我发出简单的HTTPGET请求并返回结果文本,如果需要,还可以选择返回JSON。我已将代码粘贴到下面。我遇到的问题是,我的函数在HTTP调用完成之前返回,因此返回一个空对象。我想我知道为什么会发生这种情况,因为我正在对任务调用resume,然后该任务正在执行并等待回调函数被调用——但与此同时,代码执行仍在继续,因此我返回一个空对象。那么…这里推荐的方法是什么?我是否应该将回调放回原始视图控制器上的函数,而不是尝试以这种方式创建一个可重用的类,或者其他方式!我张开双臂等待任何建议;)

p、 这些代码中的一些可能看起来很熟悉,因为很多都是从我在网上读到的其他文章/帖子中获得的,然后根据我的需要进行定制

class WebController {

    func makeGetCall(strURL:String, returnJSON:Bool) -> WebControllerResponse {

        //declare a var to store our return
        let wcr:WebControllerResponse = WebControllerResponse()

        // Set up the URL request
        guard let url = URL(string: strURL) else {
            wcr.successful = false
            wcr.returnData = "Error: cannot create URL"
            return wcr
        }

        let urlRequest = URLRequest(url: url)

        // set up the session
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)

        // make the request

        session.dataTask(with: urlRequest, completionHandler: {
            (data, response, error) in
            // check for any errors
            guard error == nil else {
                wcr.successful = false
                wcr.returnData = "error calling GET - " + String(describing: error)
                return
            }
            // make sure we got data
            guard let responseData = data else {
                wcr.successful = false
                wcr.returnData = "Error: did not receive data"
                return
            }

            if (returnJSON == true) {
            // parse the result as JSON, since that's what the API provides
            do {
                guard let retObj = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: AnyObject] else {
                        wcr.successful = false
                        wcr.returnData = "error trying to convert data to JSON"
                        return
                    }
                wcr.returnJSON = retObj
                wcr.returnData = String(describing: responseData)
                wcr.successful = true
                }
            catch  {
                wcr.successful = false
                wcr.returnData = "error trying to convert data to JSON"
                return
                }
            }
            else {
                // just return raw data
                wcr.returnData = String(describing: responseData)
                wcr.successful = true
                return
            }
        }).resume()

            return wcr
    }
}
我的响应对象非常简单:

class WebControllerResponse {

    var successful:Bool = false
    var returnData:String = ""
    var returnJSON:[String:AnyObject]?

    init() {

    }

}
以下是根据@dirtydanee的反馈更新的代码,该代码出错:

类CalTest:UIViewController、WebController和Delegate{

@IBOutlet weak var bigText: UITextView!
@IBOutlet var urlIn: UITextField!
@IBOutlet weak var testLabel: UILabel!

@IBAction func getButton(_ sender: Any) {

    let wc:WebController = WebController()
    wc.delegate = self
    wc.makeGetCall(strURL: urlIn.text!, returnJSON:false)

}


func webController(webController: WebController, didReceiveResponse: WebControllerResponse) {
    bigText.text = didReceiveResponse.returnData
}

}

URLSession
dataTask
是一个异步API,因此您需要从完成块返回结果,而不是在完成块之后

当调用dataTask completion处理程序时,您需要从
WebController
创建一个委托来通知观察类

// Create the protocol
protocol WebControllerDelegate: class {
    func webController(webController: WebController, didReceiveResponse: WebControllerResponse)
}

class WebController {

    // Add delegate variable to class
    weak var delegate: WebControllerDelegate?

    // Initaite the call, but do not return anything from the function directly
    func makeGetCall(strURL:String, returnJSON:Bool) {

        //declare a var to store our return
        let wcr:WebControllerResponse = WebControllerResponse()

        // Set up the URL request
        guard let url = URL(string: strURL) else {
            wcr.successful = false
            wcr.returnData = "Error: cannot create URL"
            self.delegate?.webController(webController: self, didReceiveResponse: wcr)
            return 
        }

        let urlRequest = URLRequest(url: url)

        // set up the session
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)

        // make the request

        session.dataTask(with: urlRequest, completionHandler: {
            (data, response, error) in
            // check for any errors
            guard error == nil else {
                wcr.successful = false
                wcr.returnData = "error calling GET - " + String(describing: error)
                // Add the delegate call to the right places
                self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                return
            }
            // make sure we got data
            guard let responseData = data else {
                wcr.successful = false
                wcr.returnData = "Error: did not receive data"
                return
            }

            if (returnJSON == true) {
                // parse the result as JSON, since that's what the API provides
                do {
                    guard let retObj = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: AnyObject] else {
                        wcr.successful = false
                        wcr.returnData = "error trying to convert data to JSON"
                        self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                        return
                    }
                    wcr.returnJSON = retObj
                    wcr.returnData = String(describing: responseData)
                    wcr.successful = true
                    self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                }
                catch  {
                    wcr.successful = false
                    wcr.returnData = "error trying to convert data to JSON"
                    self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                    return
                }
            }
            else {
                // just return raw data
                wcr.returnData = String(describing: responseData)
                wcr.successful = true
                self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                return
            }
        }).resume()
    }
}
用法:

class Foo: WebControllerDelegate {
   let webController = WebController() 

    func testWebController() {
        // Assign delegate to self
        webController.delegate = self
        webController.makeGetCall(strURL: "whatever your URL should be", returnJSON: true)
    }

    // Declare the delegate
    func webController(webController: WebController, didReceiveResponse: WebControllerResponse) {
//转到主UI线程 DispatchQueue.main.sync{ 将文本指定给UITextView bigText.text=didReceiverResponse.returnData } }
}

URLSession
dataTask
是一个异步API,因此您需要从完成块返回结果,而不是在完成块之后

当调用dataTask completion处理程序时,您需要从
WebController
创建一个委托来通知观察类

// Create the protocol
protocol WebControllerDelegate: class {
    func webController(webController: WebController, didReceiveResponse: WebControllerResponse)
}

class WebController {

    // Add delegate variable to class
    weak var delegate: WebControllerDelegate?

    // Initaite the call, but do not return anything from the function directly
    func makeGetCall(strURL:String, returnJSON:Bool) {

        //declare a var to store our return
        let wcr:WebControllerResponse = WebControllerResponse()

        // Set up the URL request
        guard let url = URL(string: strURL) else {
            wcr.successful = false
            wcr.returnData = "Error: cannot create URL"
            self.delegate?.webController(webController: self, didReceiveResponse: wcr)
            return 
        }

        let urlRequest = URLRequest(url: url)

        // set up the session
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)

        // make the request

        session.dataTask(with: urlRequest, completionHandler: {
            (data, response, error) in
            // check for any errors
            guard error == nil else {
                wcr.successful = false
                wcr.returnData = "error calling GET - " + String(describing: error)
                // Add the delegate call to the right places
                self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                return
            }
            // make sure we got data
            guard let responseData = data else {
                wcr.successful = false
                wcr.returnData = "Error: did not receive data"
                return
            }

            if (returnJSON == true) {
                // parse the result as JSON, since that's what the API provides
                do {
                    guard let retObj = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: AnyObject] else {
                        wcr.successful = false
                        wcr.returnData = "error trying to convert data to JSON"
                        self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                        return
                    }
                    wcr.returnJSON = retObj
                    wcr.returnData = String(describing: responseData)
                    wcr.successful = true
                    self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                }
                catch  {
                    wcr.successful = false
                    wcr.returnData = "error trying to convert data to JSON"
                    self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                    return
                }
            }
            else {
                // just return raw data
                wcr.returnData = String(describing: responseData)
                wcr.successful = true
                self.delegate?.webController(webController: self, didReceiveResponse: wcr)
                return
            }
        }).resume()
    }
}
用法:

class Foo: WebControllerDelegate {
   let webController = WebController() 

    func testWebController() {
        // Assign delegate to self
        webController.delegate = self
        webController.makeGetCall(strURL: "whatever your URL should be", returnJSON: true)
    }

    // Declare the delegate
    func webController(webController: WebController, didReceiveResponse: WebControllerResponse) {
//转到主UI线程 DispatchQueue.main.sync{ 将文本指定给UITextView bigText.text=didReceiverResponse.returnData } }
}

由于HTTP请求是异步进行的,因此函数将在完成之前返回

解决此问题的最简单方法是在函数上使用完成块:

func makeGetCall(strURL:String, returnJSON:Bool completion: @escaping (WebControllerResponse?) -> Void) {
    // ...
}
然后,当HTTP请求完成时,您可以调用完成处理程序

completion(webControllerResponse)

由于HTTP请求是异步发生的,因此函数将在完成之前返回

解决此问题的最简单方法是在函数上使用完成块:

func makeGetCall(strURL:String, returnJSON:Bool completion: @escaping (WebControllerResponse?) -> Void) {
    // ...
}
然后,当HTTP请求完成时,您可以调用完成处理程序

completion(webControllerResponse)

这是辉煌的@dirtydanee-然而,我现在有一个问题。已成功调用我的委托,我正在尝试使用数据结果设置UITextView内容(仅用于此阶段的测试目的)。但是,我遇到了一个例外:NSBLOCKOPERATION\u正在调用\u OUT\u到\u A\u blocku您能显示遇到此问题的代码吗?我在想,无论你做什么,都应该在主线程上完成谢谢@dirtydanee:class CalTest:UIViewController,WebControllerDelegate{IBOutlet弱var bigText:UITextView!IBOutlet var urlIn:UITextField!IBOutlet弱var testLabel:UILabel!IBAction func getButton(u发送者:任意){let wc:WebController=WebController()wc.delegate=self-wc.makeGetCall(strURL:urlIn.text!,returnJSON:false)}func-WebController(WebController:WebController,didReceiverResponse:WebControllerResponse){bigText.text=didReceiverResponse.returnData}我从我的网站上删除了@符号,并采取措施来缩小帖子的大小,避免被用户捡起。请回答您的问题,不要将代码作为注释发布。这是brilliant@dirtydanee-但是,我现在有一个问题。我的代表被成功调用,我正在尝试使用d的结果设置UITextView内容ata(仅用于此阶段的测试目的)。但是,我遇到了一个异常:NSBLOCKOPERATION\u正在调用\u OUT\u到\u A\u Block您可以显示遇到此问题的代码吗?我想无论您做什么,都应该在主线程上完成谢谢@dirtydanee:class CalTest:UIViewController,WebControllerDelegate{IBOutlet弱变量bigText:UITextView!IBOutlet弱变量urlIn:UITextField!IBOutlet弱变量testLabel:UILabel!iAction func getButton(uSender:Any){let wc:WebController=WebController()wc.delegate=self wc.makeGetCall(strURL:urlIn.text!,returnJSON:false)}func webController(webController:webController,didReceiveResponse:WebControllerResponse){bigText.text=didReceiveResponse.returnData}我从我的出口中删除了@符号,并采取措施来修剪帖子的大小,避免它们被用户拾取。请回答您的问题,不要将代码作为注释发布。