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

时间:2016-10-02 08:24:05

标签: ios objective-c iphone swift dispatch

我需要知道,如果发生错误,服务器将在编辑后返回显示在右侧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
                }
            }

        }

服务器请求的Question类中的方法:

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

UPDATE(导入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)")
        }
    }

现在好吗?

1 个答案:

答案 0 :(得分:1)

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

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

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