2016-10-02 8 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)を呼び出すだけですが、それは好みの問題です。また、このようなメソッドは2つのコールバックをとることが多く、そのうちの1つはエラーが発生したときに呼び出されます。たとえば、editQuestion内でエラーが発生した後で警告を表示する場合は、その警告を開き、適切にコールバックするコールバックを渡します。 – davidv

+0

私はあなたを理解していると思います。ありがとう。 – SeRG1k

関連する問題