Невозможно перейти от представления к другому после выполнения некоторых инструкций

86
9

У меня есть эта реализация в части моего приложения:

Почему, когда я нажимаю кнопку "cerca per ISBN", она переходит в таблицуView без выполнения инструкций, которые я написал?

Это код кнопки "cerca per ISBN", которую я нажимаю:

@IBAction func ISBNButtonClick(_ sender: Any) {

let libro = Libro.text! as String

if Libro.text!.isEmpty {

//Alert per segnalare i campi mancanti, oltre a caselle rosse

var myAlert = UIAlertController(title:"Attenzione\n", message:"Inserire il codice ISBN", preferredStyle:UIAlertControllerStyle.alert);

let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.default){ action in }

myAlert.addAction(okAction);
self.present(myAlert, animated:true, completion:nil);

// placeholder rosso se la text è vuota

Libro.attributedPlaceholder = NSAttributedString(string:"Digita qui...", attributes: [NSForegroundColorAttributeName: UIColor.red])

//se tutti i campi obbligatori sono stati inseriti, proseguo ad altri controlli
}else{
if(isNumeric(string: libro)){
if((libro.characters.count) < 13 || (libro.characters.count) > 13){

//Alert per segnalare l'ISBN più corto di 13 numeri

var myAlert = UIAlertController(title:"Attenzione\n", message:"L'ISBN deve essere di 13 cifre", preferredStyle:UIAlertControllerStyle.alert);

let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.default){ action in }

myAlert.addAction(okAction);
self.present(myAlert, animated:true, completion:nil);
}else{
//inviare dati al server
let myUrl = NSURL(string:"http://chuadiv.ddns.net/easytoschool/fetch_book_detailed.php");

let request = NSMutableURLRequest(url:myUrl as! URL);
request.httpMethod = "POST";
let postString = "name=\(libro)&mail=\(UserDefaults.standard.object(forKey: "userEmail") as? String)";
request.httpBody = postString.data(using: String.Encoding.utf8);

let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in

if error != nil{
print("error=\(error)")
return
}

var err: NSError?

do{
var json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray

if let parseJSON: NSArray = json{

for index in 0...parseJSON.count-1 {

print("ciao")
let libro = parseJSON[index] as! [String:Any]
print("\n\n",index,":\n")

let book = resultCell.init(bookId: libro["id"] as! String,bookName: libro["name"] as! String,bookAuthor: libro["author"] as! String,bookSchool: libro["school"] as! String,bookPrice: libro["price"] as! String,bookStatus: libro["status"] as! String,bookISBN: libro["isbn"] as! String,bookType: libro["type"] as! String,bookIdSeller: libro["idSeller"] as! String,bookNameSeller: libro["nameSeller"] as! String,bookSurnameSeller: libro["surnameSeller"] as! String)

book.printBook();

HomeViewController.booksArray.append(book)
}

}
}catch{
print("error=\(error)")
return
}
}
task.resume();

performSegue(withIdentifier: "homeToListBook", sender: self)

}
}else{
var myAlert = UIAlertController(title:"Attenzione\n", message:"Inserire solo numeri per la ricerca attraverso codice ISBN", preferredStyle:UIAlertControllerStyle.alert);

let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.default){ action in }

myAlert.addAction(okAction);
self.present(myAlert, animated:true, completion:nil);
}
}
}

Я хочу, чтобы, когда я нажимаю кнопку, он устанавливает мой массив, и после того, как он переходит к tableView, но я не могу

спросил(а) 2017-05-13T13:00:00+03:00 3 года, 1 месяц назад
1
Решение
67

Проблема заключается в том, что блок завершения dataTask вызовет async, поэтому он будет звонить позже, и вы в настоящее время выполняете segue вне его. Так что вам нужно сделать, это вызвать performSegue внутри завершения блока dataTask также на Main потоке. Также используйте URL и URLRequest вместо NSURL и NS(Mutable)URLRequest

let myUrl = URL(string:"http://chuadiv.ddns.net/easytoschool/fetch_book_detailed.php")

let request = URLRequest(url:myUrl!)
request.httpMethod = "POST";
let postString = "name=\(libro)&mail=\(UserDefaults.standard.string(forKey: "userEmail")!)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in

if error != nil{
print("error=\(error)")
return
}

var err: NSError?

do{
var json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [[String:Any]]

if let parseJSON = json {
for libro in in parseJSON {
let book = resultCell.init(bookId: libro["id"] as! String,bookName: libro["name"] as! String,bookAuthor: libro["author"] as! String,bookSchool: libro["school"] as! String,bookPrice: libro["price"] as! String,bookStatus: libro["status"] as! String,bookISBN: libro["isbn"] as! String,bookType: libro["type"] as! String,bookIdSeller: libro["idSeller"] as! String,bookNameSeller: libro["nameSeller"] as! String,bookSurnameSeller: libro["surnameSeller"] as! String)

book.printBook();

HomeViewController.booksArray.append(book)
}

//Perform segue now
DispatchQueue.main.async {
performSegue(withIdentifier: "homeToListBook", sender: self)
}
}
}catch{
print("error=\(error)")
return
}
}
task.resume()

Примечание. В Swift используйте Swift собственный массив типов и словарь вместо NSArray и NSDictionary.

ответил(а) 2017-05-13T13:14:00+03:00 3 года, 1 месяц назад
39

вы добавляете элементы к массиву другого экземпляра или даже к некоторому статическому var вместо его передачи

вам следует создать класс Book со всеми свойствами

class Book {
let id: String
init(data: [String:Any]) {
self.id = data["id"] as? String ?? "" //or some other error handling
}
}

затем создайте массив книг внутри текущего UIViewController

var books: [Book] = []

затем сделайте что-то вроде


let book = Book(data: libro)
books.append(book)

для передачи данных вы должны создать массив книг внутри целевого контроллера (HomeViewController)

установить его функции DataSource и Delegate для создания UITableViewCells с использованием этого массива

и передавать данные, подобные

override func prepare(for segue: UIStoryboardSegue, sender _: Any?) {
if segue.identifier == "homeToListBook" {
if let destinationVC = segue.destination as? HomeViewController {
destinationVC.books = self.books
}
}
}

EDIT: и, как упоминал Nirav D, segue следует вызывать в основном потоке после анализа данных, не заметил этого

ответил(а) 2017-05-13T13:09:00+03:00 3 года, 1 месяц назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема