2016-10-02 38 views
1

我需要知道服務器在編輯完成後返回到單元格右側的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 
       } 
      } 

     } 

法在用於服務器請求問題類:

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

你應該永遠不會在主線程上發出遠程請求。對於任何移動平臺而言,這是一條規則,應用程序應始終對用戶操作負責,即使在下載或上傳數據時也是如此。

你想要做的是使該請求異步使用任何一種庫(我建議你看看Alamofire),並通過一個回調應該接收響應。在那裏你可以使用GCD(dispatch_async)來從主線程更新UI(你至少不能在iOS上的任何其他線程中更改UI)。

另請注意,Apple已經棄用了在iOS上發出同步請求的方法(儘管它們仍然可以使用信號量或其他形式的同步完成)。

+0

請檢查我的更新。 – SeRG1k

+0

對我來說看起來很好,你並不需要那裏的編輯變量,我只是稱完成(true)或完成(false),但這是一個偏好問題。而且,像這樣的方法通常需要兩個回調,其中一個在發生錯誤時被調用。因此,如果您想要在editQuestion內發生錯誤後顯示警報,請傳入可打開此警報的回調並適當調用它。 – davidv

+0

我想,我理解你。謝謝。 – SeRG1k

相關問題