UiPickerView не всегда показывает значения в 3g

Привет у меня действительно странная ошибка, приложение в этом приложении использует pattern-view-controller, в представлении я использую UIPickerView отображать имена. Значения должны быть указаны в RisorseUmaneUIPicker! Странно то, что все работает, а когда вы отправляете текстовое сообщение на мобильные устройства в 3g иногда, UIPickerView остается пустым. Как я могу решить это?

Я проверил запрос JSON с почтальоном, и это всегда правильно

Посмотреть:

class RisorseUmaneViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITableViewDelegate, UITableViewDataSource {

    //Dichiarazione Oggetti
    //L'array User contiene le informazione su tutti gli utenti presenti nel database
    private var UserLoad: [UserStruct] = []
    private var RisorseUmaneUIPicker: UIPickerView = UIPickerView()
    private let datePicker: UIDatePicker = UIDatePicker()
    private let StartPicker: UIDatePicker = UIDatePicker()
    private let EndPicker: UIDatePicker = UIDatePicker()
    private let PausaPicker: UIDatePicker = UIDatePicker()
    private var textView: UITextView = UITextView()
    private var RisoseUmaneTableView: UITableView!
    private var RisorseUmaneLoad: [RisorsaUmanaStruct] = []
    private var SwitchRapportino: UISwitch = UISwitch()
    //L'oggetto RisorsaUmana Rappresenta la risorsa che verrà inserita
    public var Cantiere: Cantiere
    private var RisorsaSelezionata: RisorsaUmana?
    private var Extensioni: Extend = Extend()
    public var Stato: String = "Inserimento"
    private var RisorsaRapportino: Bool = false;


    init(CantiereInterno: Cantiere) {
        self.Cantiere = CantiereInterno
        super.init(nibName: nil, bundle: nil)
    }


    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        hideKeyboardWhenTappedAround()
        self.view.backgroundColor = UIColor.white
        self.navigationController?.setNavigationBarHidden(false, animated: true)
        self.navigationItem.title = "Risorse Umane"
        InitRisorseUmaneViewController();
        //Modifica UiPickerView delle Risorse con l'utente che ha effettuato il login
        print("Login di : \(UserLoginDefault.Username)")
        selectPicker(withText: UserLoginDefault.Username)

    }

    //Funzione di Configurazione Iniziale della View
    private func InitRisorseUmaneViewController() {

        //inizializzo il Cantiere
        let displayWidth: CGFloat = self.view.frame.width
        //Carico le Risorse
        CaricaRisorse()
        //Configurazione Label Risorsa
        let label = UILabel(frame: CGRect(x: (self.view.frame.width / 2) - 150, y: 65, width: 90, height: 24))
        label.font = UIFont(name: "HelveticaNeue-Bold", size: 16.0)
        label.textAlignment = .center
        label.text = "Risorsa: "
        self.view.addSubview(label)
        //Configurazione :impostazioni picker view
        self.RisorseUmaneUIPicker = UIPickerView(frame: CGRect(x: (self.view.frame.width / 2) - 70, y: 50, width: 200, height: 50))
        self.RisorseUmaneUIPicker.delegate = self
        self.RisorseUmaneUIPicker.dataSource = self
        self.RisorseUmaneUIPicker.backgroundColor = UIColor.white
        self.view.addSubview(RisorseUmaneUIPicker)
        //Configuro il DataTime Picker per la data
        self.datePicker.frame = CGRect(x: 10, y: 100, width: self.view.frame.width, height: 80)
        self.datePicker.timeZone = NSTimeZone.local
        self.datePicker.backgroundColor = UIColor.white
        self.datePicker.datePickerMode = UIDatePickerMode.date;
        //Aggiunto un evento quando viene modificato il valore del datePicker
        self.datePicker.addTarget(self, action: #selector(RisorseUmaneViewController.datePickerValueChanged(_:)), for: .valueChanged)
        self.view.addSubview(datePicker)
        //Congiurazione Ore di Inizio e Fine
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "HH:mm"
        let dateStart = dateFormatter.date(from: "08:00")
        let dateEnd = dateFormatter.date(from: "17:30")
        let datePausa = dateFormatter.date(from: "01:30")
        //Configuro il DataPicker di Start
        self.StartPicker.frame = CGRect(x: (self.view.frame.width / 2) - 90, y: 190, width: 100, height: 40)
        self.StartPicker.timeZone = NSTimeZone.local
        self.StartPicker.backgroundColor = UIColor.white
        self.StartPicker.datePickerMode = UIDatePickerMode.time
        self.StartPicker.date = dateStart!
        self.StartPicker.addTarget(self, action: #selector(RisorseUmaneViewController.SetDataInizio(sender:)), for: .valueChanged)
        self.StartPicker.minuteInterval = 30
        self.view.addSubview(StartPicker)
        //Configuro il DataPicker di End
        self.EndPicker.frame = CGRect(x: (self.view.frame.width / 2) + 60, y: 190, width: 100, height: 40)
        self.EndPicker.timeZone = NSTimeZone.local
        self.EndPicker.backgroundColor = UIColor.white
        self.EndPicker.datePickerMode = UIDatePickerMode.time
        self.EndPicker.date = dateEnd!
        self.EndPicker.addTarget(self, action: #selector(RisorseUmaneViewController.SetDataFine(sender:)), for: .valueChanged)
        self.EndPicker.minuteInterval = 30
        self.view.addSubview(EndPicker)
        //Configuro il DataPicker di Pausa
        self.PausaPicker.frame = CGRect(x: (self.view.frame.width / 2) - 30, y: 250, width: 100, height: 40)
        self.PausaPicker.timeZone = NSTimeZone.local
        self.PausaPicker.backgroundColor = UIColor.white
        self.PausaPicker.datePickerMode = UIDatePickerMode.time
        self.PausaPicker.date = datePausa!
        self.PausaPicker.addTarget(self, action: #selector(RisorseUmaneViewController.SetPausa(sender:)), for: .valueChanged)
        self.PausaPicker.minuteInterval = 30
        self.view.addSubview(PausaPicker)
        //Configurazione Testo TextView
        self.textView = UITextView(frame: CGRect(x: 0, y: 300, width: displayWidth, height: 85))
        self.automaticallyAdjustsScrollViewInsets = false
        textView.font = UIFont(name: "HelveticaNeue-Bold", size: 18.0)
        textView.textAlignment = NSTextAlignment.justified
        textView.textColor = UIColor.blue
        textView.backgroundColor = UIColor.lightGray
        self.view.addSubview(textView)
        //Bottone per inserimento:
        let ImageInserisci = UIImage(named: "inserisci.png") as UIImage?
        let ButtonInserisciRisorsaUmana = UIButton()
        ButtonInserisciRisorsaUmana.frame = CGRect(x: (self.view.frame.width / 2) - 180, y: 395, width: 80, height: 80)
        ButtonInserisciRisorsaUmana.setImage(ImageInserisci, for: .normal)
        ButtonInserisciRisorsaUmana.setTitleColor(UIColor.black, for: .normal)
        ButtonInserisciRisorsaUmana.set(image: ImageInserisci, attributedTitle: NSAttributedString(string: "Inserisci"), at: UIButton.Position(rawValue: 1)!, width: 30, state: UIControlState.normal)
        ButtonInserisciRisorsaUmana.addTarget(self, action: #selector(InserisciRisorsaButtonAction), for: .touchUpInside)
        self.view.addSubview(ButtonInserisciRisorsaUmana)
        //Bottone per tornare a schermata principale
        let ImageReturn = UIImage(named: "return.png") as UIImage?
        let buttonReturn = UIButton()
        buttonReturn.frame = CGRect(x: (self.view.frame.width / 2) - 30, y: 395, width: 80, height: 80)
        buttonReturn.backgroundColor = UIColor.white
        buttonReturn.setImage(ImageReturn, for: .normal)
        buttonReturn.setTitle("Go Home", for: .normal)
        buttonReturn.addTarget(self, action: #selector(Return), for: .touchUpInside)
        self.view.addSubview(buttonReturn)
        //Configuro lo UISwitch per l'inserimento delle risorse nel cantiere
        let labelRapportino = UILabel(frame: CGRect(x: (self.view.frame.width / 2) + 80, y: 395, width: 130, height: 21))
        labelRapportino.text = "Rapportino?"
        labelRapportino.font = UIFont(name: "HelveticaNeue-Bold", size: 16.0)
        self.view.addSubview(labelRapportino)
        SwitchRapportino = UISwitch(frame: CGRect(x: (self.view.frame.width / 2) + 100, y: 430, width: 0, height: 0))
        SwitchRapportino.setOn(false, animated: true)
        SwitchRapportino.addTarget(self, action: #selector(RisorseUmaneViewController.switchValueDidChange(sender:)), for: .valueChanged)
        self.view.addSubview(SwitchRapportino)


        //Stato Inserimento: l'utente sta inserendo delle risorse dentro una cantier
        if(Stato == "Inserimento") {
            RisorsaSelezionata = RisorsaUmana(CantiereInterno: Cantiere)
            //Configurazione table view
            RisoseUmaneTableView = UITableView(frame: CGRect(x: 0, y: 500, width: displayWidth, height: self.view.frame.height - 500))
            RisoseUmaneTableView.register(CustomTableViewCellArticolo.self, forCellReuseIdentifier: "MyCell")
            RisoseUmaneTableView.dataSource = self
            RisoseUmaneTableView.delegate = self
            RisoseUmaneTableView.tableFooterView = UIView()
            RisoseUmaneTableView.rowHeight = 60
            RisoseUmaneTableView.layer.borderWidth = 2.0
            self.view.addSubview(RisoseUmaneTableView)
            //Carica Le risorse Umane e chiamo i Metodi di configurazione
            CaricaRisorseCantiere()
        }
        SetPausa(sender: PausaPicker)
        SetDataInizio(sender: StartPicker)
        SetDataFine(sender: EndPicker)
        datePickerValueChanged(datePicker)
        SwitchRapportino.isHidden = false
        labelRapportino.isHidden = false
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func selectPicker(withText text: String) {
        print("Testo: \(text)")
        if let index = self.UserLoad.index(where: { $0.Username == text }) {
            print("Indice di riga: \(index)")
            RisorseUmaneUIPicker.selectRow(index, inComponent: 0, animated: true)
            self.RisorseUmaneUIPicker.reloadAllComponents()
        }
        else {
            print("text not found")
        }
    }

    //Funzione per il caricamento delle risorse Umane
    func CaricaRisorse() {
        DispatchQueue.global(qos: .userInteractive).async {
            let rtemp = User()
            rtemp.CaricaUtenti(completion: { result in
                self.UserLoad = result
                self.RisorseUmaneUIPicker.reloadAllComponents()
            });
        }
    }

    @objc func SetPausa(sender: UIDatePicker) {
        RisorsaSelezionata?.SetOrePausa(Pausa: Extensioni.CastFromDateToString_SqlServer_Pausa(mydate: PausaPicker.date))
    }

    @objc func SetDataFine(sender: UIDatePicker) {
        RisorsaSelezionata?.SetOreFine(OreFine: Extensioni.CastFromDateToString_SqlServer_DateTime(mydate: EndPicker.date))
    }

    @objc func SetDataInizio(sender: UIDatePicker) {
        RisorsaSelezionata?.SetOreInizio(OreInizio: Extensioni.CastFromDateToString_SqlServer_DateTime(mydate: StartPicker.date))
    }

    @objc func InserisciRisorsaButtonAction(sender: UIButton!) {
        print("\n Id Risorsa: \(String(describing: RisorsaSelezionata?.GetIdUtente()))")
        if(textView.text.isEmpty || RisorsaSelezionata?.GetIdUtente() == 0) {
            let alertController = UIAlertController(title: title, message: "Attenzione non hai compilato tutti i campi", preferredStyle: .alert)
            let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
            alertController.addAction(OKAction)
            self.present(alertController, animated: true, completion: nil)
        }
        else { 
            RisorsaSelezionata?.SetDescrizione(Descrizione: textView.text)
                RisorsaSelezionata?.SetRisorsaRapporto(RisorsaRapportino: RisorsaRapportino)
            if(Stato == "Inserimento") {
                RisorsaSelezionata?.InserisciRisorsa(completion: { result in

                if(result == true) {
                    self.CaricaRisorseCantiere()
                }
                else {
                    let alertController = UIAlertController(title: "Errore", message: "Non sono riuscito ad inserire la risorsa!", preferredStyle: .alert)
                    let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
                    alertController.addAction(OKAction)
                    self.present(alertController, animated: true, completion: nil)
                }
            })
        }
    }

}

    @objc func Return(sender: UIButton!) {
        //self.performSegueToReturnBack()
        let CantiereSelezionato = GestioneCantieriViewController(CantiereSet: self.Cantiere)
        self.present(CantiereSelezionato, animated: true, completion: nil)
    }

    //Metodo delegato che ritorna il numero di righe
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return UserLoad.count
    }

    // Metodo delegato che ritorna il valore mostrato nella riga
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        RisorsaSelezionata?.SetIdUtente(IdUtente: UserLoad[row].IdUtente)
        return UserLoad[row].Username
    }

    // Metodo Delato Chiamao quando viene selezionata unarigha
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        print("\n UserLoad[row].IdUtente \(UserLoad[row].IdUtente!)")
        RisorsaSelezionata?.SetIdUtente(IdUtente: UserLoad[row].IdUtente!)
        print("\n ID Risorsa \(String(describing: RisorsaSelezionata?.GetIdUtente()))")
    }

    //Number of Columns into UIPickerView
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    //this func get select Date from UIDatePicker
    @objc func datePickerValueChanged(_ sender: UIDatePicker) {
        RisorsaSelezionata?.SetData(Data: Extensioni.CastFromDateToString_SqlServer_DateTime(mydate: sender.date))
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return RisorseUmaneLoad.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        RisoseUmaneTableView.beginUpdates()
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! CustomTableViewCellArticolo
        cell.layer.cornerRadius = 10
        cell.layer.borderWidth = 1.0
        cell.layer.borderColor = UIColor.gray.cgColor
        cell.layer.masksToBounds = true
        cell.labCodArt.text = RisorseUmaneLoad[indexPath.row].Risorsa
        cell.labDescrizione.text = RisorseUmaneLoad[indexPath.row].Descrizione
        cell.labPrezzo.text = ""
        RisoseUmaneTableView.endUpdates()
        return cell
    }

    func CaricaRisorseCantiere() {
        if(Stato == "Inserimento") {
            let rtemp = RisorsaUmana(CantiereInterno: Cantiere)
            rtemp.CaricaRisorseUmaneCantiere(completion: { result in

            self.RisorseUmaneLoad.removeAll()
            self.RisorseUmaneLoad = result
            DispatchQueue.main.async {
                self.RisoseUmaneTableView.reloadData()
            }
        });
    }
}
......

контроллер:

func CaricaUtenti(completion: @escaping ([UserStruct]) -> Void) {
    DispatchQueue.global(qos: .userInteractive).async {
        let rtemp = UserModel()
        rtemp.CaricaRisorse(completion: { result in
            completion(result)
        })
    }
}

Модель:

func CaricaRisorse(completion: @escaping ([UserStruct]) -> ()) {
    DispatchQueue.global(qos: .userInteractive).async {
        let jsonrequest = JSON()
        let jsonarray: [String: Any] = ["Default": "0"]
        jsonrequest.GetArray(Tipo: "User", Router: "/RisorseUmane/CaricaRisorse", ValueArray: jsonarray, completion: { result in
            completion(result as! [UserStruct])
        })
    }
}

func GetArray(Tipo: String, Router: String, ValueArray: [String: Any], completion: @escaping (_ ret: Codable) -> ()) {
    let semaphore = DispatchSemaphore(value: 1)
    semaphore.wait()
    let db = Database()
    let json: [String: Any] = ValueArray
    let jsonData = try? JSONSerialization.data(withJSONObject: json)
    var request = URLRequest(url: URL(string: db.GetServerURL() + Router)!)
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
    request.httpMethod = "POST"
    request.httpBody = jsonData
    URLSession.shared.dataTask(with: request) { (data, response, error) in
        if error != nil {
            print(error!.localizedDescription)
        }
    guard let data = data else { return }
    do {
        if(Tipo == "User") {
            let value = try JSONDecoder().decode([UserStruct].self, from: data)
            completion(value)
        }
    } catch let error {
         print("Error JSON: ", error)
     }
    }.resume()
    semaphore.signal()
}

1 ответ

Вы можете установить "Network Link Conditioner" из меню XCode: Open Developers Tools > More Developers Tools, Этот инструмент позволяет тестировать в разных условиях сети.

Обработчик передан URLSesssion.dataTask Вероятно, следует передать информацию об успехе или неудаче обратно вызывающей стороне. Теперь он просто возвращает, если произошла ошибка, если данные nil, Попробуйте добавить дополнительное значение помимо данных в обработчик. Например, _ success: Bool может быть передано false в случае ошибки, если данные отсутствуют.

... completion: @escaping (_ success: Bool, _ ret: Codable) -> ()
Другие вопросы по тегам