2017-10-27 1 views
0

私のアプリケーションでは、ビューJson関数とテーブルビューのデリゲートとデータソースメソッドをロードしましたが、ここではテーブルビューメソッドを呼び出すWebサービスからデータをロードせずに、モデルのデータがないためにクラッシュしていますこれを解決する方法を教えてください。これはときどき起こっていて、時にはうまく機能していますか?ここテーブルビューのデータソースとデリゲートメソッドは、Webサービスからデータをロードせずに呼び出しますか?

は、私の見解では、ここで負荷

let guestAddressURL = "http://magento.selldesk.io/index.php/rest/V1/guest-carts/\(guestkey!)/billing-address" 
self.guestShippingaddressURL(guestAddressApi: guestAddressURL) 
self.tableDetails.delegate = self 
self.tableDetails.dataSource = self 
self.tableDetails.tableFooterView?.isHidden = true 
self.tableDetails.separatorInset = UIEdgeInsets.zero 
self.tableDetails.rowHeight = UITableViewAutomaticDimension 
self.tableDetails.estimatedRowHeight = 50 
self.title = "Checkout" 

をやっている私のJSON関数を使用すると、いくつかのデフォルト値を使用してテーブルビューのメソッドの内部で使用されているすべてのあなたの変数を初期化する必要があり

func guestShippingaddressURL(guestAddressApi: String) { 
     print(guestAddressApi) 
     let url = URL(string: guestAddressApi) 
     var request = URLRequest(url: url! as URL) 
     request.httpMethod = "GET" 
     request.addValue("application/json", forHTTPHeaderField: "Content-Type") 
     let task = URLSession.shared.dataTask(with: request) { (data, response, error) in 
      if error != nil { print(error!); return } 
      do { 
       if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [String:Any] { 
        let obj = jsonObj["street"] as! [String] 
        for item in obj { 
         self.street = item 
        } 
        print(obj) 
        print(self.street) 
        self.guestShippingAddressModel = GuestAddress.init(dict: jsonObj) 
        if self.street?.isEmpty == false { 
         self.addressSelected = true 
         self.selected = false 
        } 
        DispatchQueue.main.async { 
         self.tableDetails.reloadData() 
        } 
       } 
      } catch { 
       print(error) 
      } 
     } 
     task.resume() 
    } 
func numberOfSections(in tableView: UITableView) -> Int { 
     if self.street?.isEmpty == false{ 
      return 3 
     } 
     else { 
      if ((addressSelected == true || checkIsPaymentRadioSelect == true) && selected == false) { 
       return 3 
      }else { 
       return 2 
      } 
     } 
    } 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ 
     if ((addressSelected == true || checkIsPaymentRadioSelect == true) && selected == false) { 
      if (section == 0) 
      { 

       return 1 
      } 
      else if (section == 1) 
      { 
       return 1 
      } 
      else 
      { 
       return 1 
      } 
     } 
     else 
     { 
      if (section == 0) 
      { 
       return 1 
      } 
      else 
      { 
       return 1 
      } 
     } 
    } 
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     if ((addressSelected == true || checkIsPaymentRadioSelect == true) && selected == false){ 
      if (indexPath.section == 0) { 
       return UITableViewAutomaticDimension 
      } 
      else if (indexPath.section == 1) { 
       return 62 
      } 
      else { 
       if height == 0 { 
        return CGFloat(heightStart) 
       } 
       else{ 
        return CGFloat(self.height) 
       } 
      } 
     } 
     else{ 
      if (indexPath.section == 0){ 
       if self.street?.isEmpty == true{ 
        return 50 
       }else { 
        return UITableViewAutomaticDimension 
       } 
      } 
      else if (indexPath.section == 1){ 
       return 62 
      } 
      else { 
       return 0 
      } 
     } 
    } 
    func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){ 
     let header = view as! UITableViewHeaderFooterView 
     header.textLabel?.textColor = UIColor.gray 
     header.textLabel?.textAlignment = NSTextAlignment.center 
     header.textLabel?.font = UIFont(name: "Futura", size: 17) 
    } 
+0

あなたはおそらく、私は私のコードは – koropok

+0

の一部を表示する必要があります。 – user0246

+0

ショー 'numberOfRowsInSection'方法 –

答えて

0

です。

同様:var street: String! = ""var addressSelected: Bool! = falseなど

APIが呼び出される前であっても、これらの値の一部がnilかどうかが設定されているため。

cell.nameLabel.text = "\((dict?.firstName)!) \の場合は、return 0numberOfRowsにすることができます。

guard let _ = dict { 
    return 0 
} 
+0

しかし、私は – user0246

+0

を実行すると、モデルクラスからデータを返しています。この最初の行' cell.nameLabel.text = "\( " cell.addressLabel.text =" \(self.street!)\((dict?.city)!)\((dict?.FirstName)!)\((dict?.lastName) )!)\((dict?.postCode)!) " cell.mobileNumberLabel.text =" \((dict?。テレフォン)!) "' – user0246

+0

更新された回答。 –

1

JSON呼び出しが終了したかどうかにかかわらず、テーブルビューの読み込みが開始されます。これは、viewDidLoadが終了した後に自動的に発生します。完了ハンドラのreloadData()呼び出しを待機しません。

したがって、データがロードされるまで0を返すようにnumberOfSectionsを設定する必要があります。この方法では、補完ハンドラがデータを格納してreloadData()を呼び出すまで、テーブルは空になります(cellForRowは呼び出されません)。このとき、numberOfSectionsはゼロ以外の値を返し、データが表示されます。

+0

しかし、ときどき予想通りに起きることもありますが、時にはそれがクラッシュしていて、何らかの特別な理由があります。 – user0246

+0

urの理由によると、アプリケーションを実行するたびにクラッシュするはずですが、時にはうまく動作する場合があります。 – user0246

+0

ビューがロードされた状態になる前にリンクが呼び出され、APIコールが終了しないことがあります。おそらく..とにかく@ozzieは正しいと言った –

0

Webサービスコールバックで代理人とデータソースを設定することでそれを行うことができます。

DispatchQueue.main.async { 
        self.tableDetails.delegate = self 
        self.tableDetails.dataSource = self 
        self.tableDetails.reloadData() 
       } 

希望します。

関連する問題