如何减慢程序向服务器发出请求?

How can I slow down a program to make the request to the server?

我需要知道如果发生错误,服务器 return 编辑后或 return 前一行显示在单元格右侧的 inoformatsiya 中。或者我可以异步获取数据,稍后更新一个单元格的结果?

第一次按下按钮允许编辑,第二次在服务器和对象问题上存储信息

var tempText:String!
        @IBAction func editButtonTapped(_ sender:UIButton) {
            print("editButtonTapped")
            textIsEditable = !textIsEditable


            if textIsEditable == true {
                tempText = questionTextView.text
                questionTextView.isEditable=true
                questionTextView.backgroundColor = UIColor.white
            } else {
                questionTextView.isEditable=false
                questionTextView.backgroundColor = UIColor.clear

                question.questionText=questionTextView.text

                //Edit question on the server
                if question.editQuestion() == true {
                    print("return true")
                    if delegate != nil {
                        //delegate.editQuestionAction(question: question)
                        delegate.editQuestionAction(cell: self)

                    }
                } else {
                    questionTextView.text = tempText
                    question.questionText = tempText
                }
            }

        }

服务器请求的问题class中的方法:

func editQuestion() -> Bool {
        var edited=false

        //Prepare image for put
        let stringImage:String
        if questionImage == nil {
            stringImage=""
        } else {
            stringImage=imageName
        }

        let editDict:[String:String] = ["category" : category,
                       "text" : questionText,
                       "image": stringImage,
                       "id" : questionId]

        Connection.fetchData(feed: "quests", token: nil, parameters: editDict as [String : AnyObject]?, method: "PUT") { (result, responseDict) in
            if let success = responseDict?["success"] as? String {
                if success == "1" {
                    edited = true
                } else {
                    edited = false
                }
            }
        }
        return edited
    }

向服务器请求的方法:

static func fetchData(feed:String,token:String? = nil,parameters:[String:AnyObject]? = nil,method:String? = nil, onCompletion:@escaping (_ success:Bool,_ data:NSDictionary?)->Void){

        DispatchQueue.main.async() {
            UIApplication.shared.isNetworkActivityIndicatorVisible = true

            //let url = NSURL(string: feed)
            if let unwrapped_url = NSURL(string: serverString+feed){

                let request = NSMutableURLRequest(url: unwrapped_url as URL)

                if let tk = token {
                    let authValue = "Token \(tk)"
                    request.setValue(authValue, forHTTPHeaderField: "Authorization")
                }

                if let parm = parameters{
                    do {
                        if let data = try JSONSerialization.data(withJSONObject: parm, options:[]) as NSData? {

                            //println(NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: nil))
                            request.httpBody = data as Data
                            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
                            request.setValue("\(data.length)", forHTTPHeaderField: "Content-Length")
                        }
                    } catch let error as NSError {
                        print(error)
                    }
                }

                if let unwrapped_method = method {
                    request.httpMethod = unwrapped_method
                }

                let sessionConfiguration = URLSessionConfiguration.default
                sessionConfiguration.timeoutIntervalForRequest = 15.0
                let session = URLSession(configuration: sessionConfiguration)
                let taskGetCategories = session.dataTask(with: request as URLRequest){ (responseData, response, error) -> Void in

                    let statusCode = (response as! HTTPURLResponse?)?.statusCode
                    print("Status Code: \(statusCode), error: \(error)")
                    if error != nil || (statusCode != 200 && statusCode != 201 && statusCode != 202){
                        onCompletion(false, nil)

                    }
                    else {
                        do {
                            if let dictionary = try JSONSerialization.jsonObject(with: responseData!, options: [.mutableContainers, .allowFragments]) as? NSDictionary{
                                onCompletion(true,dictionary)

                            } else{
                                onCompletion(false, nil)
                            }
                        } catch let error as NSError {
                            print(error)
                        }
                    }
                }

                UIApplication.shared.isNetworkActivityIndicatorVisible = false
                taskGetCategories.resume()
            }
        }
    }

更新(导入 SwiftHTTP,需要 ios8):

func editQuestion(completion:@escaping (Bool)->()) {
        var edited=false

        //Prepare image for put
        let stringImage:String
        if questionImage == nil {
            stringImage=""
        } else {
            stringImage=imageName
        }

        let editDict:[String:String] = ["category" : category,
                       "text" : questionText,
                       "image": stringImage,
                       "id" : questionId]

        do {
            let opt = try HTTP.PUT(serverString+"quests", parameters: editDict)
            opt.start { response in
                //do things...
                if let err = response.error {
                    print("error: \(err.localizedDescription)")
                    DispatchQueue.main.async {
                        completion(edited)
                    }
                    return //also notify app of failure as needed
                }
                let responseDict=convertStringToDictionary(text: response.text!)
                if let success = responseDict?["success"] as? String {
                    if success == "1" {
                        edited = true
                        completion(edited)
                    } else {
                        edited = false
                        completion(edited)
                    }
                }
            }
        } catch let error {
            print("got an error creating the request: \(error)")
        }
    }

现在好了吗?

你应该永远不要在主线程上发出远程请求。这是任何移动平台的规则,应用程序应始终对用户操作负责,即使在下载或上传数据时也是如此。

你想要做的是使用你使用的任何库异步发出请求(我建议你看看 Alamofire),并传递一个应该接收响应的回调 .在那里你可以使用 GCD (dispatch_async) 从主线程 更新 UI (你不能从任何其他线程更改 UI , 至少 iOS).

另请注意,Apple 已弃用在 iOS 上发出同步请求的方法(尽管它们仍然可以使用信号量或其他形式的同步来完成)。