Как преодолеть задержку в навигации к другому viewcontroller iOS swift? - PullRequest
2 голосов
/ 16 мая 2019

Я недавно прекратил использовать Alamofire для выполнения вызовов по сети HTTP, как сейчас в swift 4 Apple представила Codable -протокол, который очень мощный и быстрый по сравнению с Alamofire.Все работает нормально, как и ожидалось, даже мой ответ быстрее, чем раньше.Но есть одна проблема.До использования протокола Codable для анализа данных моя навигация к другим представлениям была очень быстрой.Но теперь у меня небольшая задержка в навигации, особенно при переходе на страницы, где я использую JSONDecoder, чтобы получить ответ.Например: у меня есть VC1 и VC2, VC1 - это статическая страница, где в VC2 я использую JSONDecoder, получаю некоторые данные и отображаю их в collectionView.Теперь я нажимаю на кнопку в VC1, она просто останавливается на секунду, прежде чем перейти к VC2.Я не знаю, почему это происходит.

Код в VC1:

@IBAction func gotoProductCollectionView(_ sender: UIButton) {

    let viewController = self.storyboard?.instantiateViewController(withIdentifier: "productCollection") as! ProductCollectionViewController
    self.navigationController?.pushViewController(viewController, animated: true)
}

Код в VC2:

class ProductCollectionViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {

@IBOutlet weak var productsTableView: UITableView! 

var productsData = [ProductData]()

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

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    getProductData()
}

func getProductData() {
    self.productsData = []
    guard let productDataURL = URL(string: "MyURL") else {return}
   DispatchQueue.global(qos: .background).async {
     do {
         let data = try Data(contentsOf: productDataURL)
         self.productsData = try 
 JSONDecoder().decode([ProductData].self, from: data)
         print(self.productsData)
         print(self.productsData.count)
         for productNames in self.productsData {
             print(productNames.product_name!)
         }
        }catch let error {
           print(error)
       }
      DispatchQueue.main.async {                
            self.productsTableView.reloadData()
        }
     }
   } 
} 

Объект модели продукта:

struct ProductData: Codable {

var product_id: String?
var product_name: String?
var product_price: String?
var product_special_price: String?
var product_sale_of: String?
var product_brand: String?
var product_image: String?

private enum CodingKeys: String, CodingKey {
    case product_id
    case product_name
    case product_price
    case product_special_price
    case product_sale_of
    case product_brand
    case product_image
}

init(product_id: String? = nil, product_name: String? = nil, product_price: String? = nil, product_special_price: String? = nil, product_sale_of: String? = nil, product_brand: String? = nil, product_image: String? = nil) {

    self.product_id = product_id
    self.product_name = product_name
    self.product_price = product_price
    self.product_special_price = product_special_price
    self.product_sale_of = product_sale_of
    self.product_brand = product_brand
    self.product_image = product_image
}

init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    product_id = try container.decode(String.self, forKey: .product_id)
    product_name = try container.decode(String.self, forKey: .product_name)
    product_price = try container.decode(String.self, forKey: .product_price)
    product_special_price = try container.decode(String.self, forKey: .product_special_price)
    product_brand = try container.decode(String.self, forKey: .product_brand)
    product_image = try container.decode(String.self, forKey: .product_image)
    if let value = try? container.decode(Int.self, forKey: .product_sale_of) {
        product_sale_of = String(value)
    } else {
        product_sale_of = try container.decode(String.self, forKey: .product_sale_of)
    }
  }
}

1 Ответ

3 голосов
/ 16 мая 2019

Ответ в этой строке

let data = try Data(contentsOf: productDataURL)

Очевидно, что вы загружаете данные из Интернета в DispatchQueue.main

Вам нужно сделать это в отдельной фоновой очереди, а затем обновить представлениеот main снова.Не забудьте использовать .async звонки.

...