Swift URLSession не работает до создания PageView - PullRequest
0 голосов
/ 08 ноября 2018

Я прочитал это сообщение , но не смог решить свою проблему.
DispatchQueue.main.async код не может работать с моим кодом.
Я думаю, что моя проблема немного отличается от этого. Поэтому я отправляю свой вопрос.

У меня 3 просмотра.

enter image description here

FirstView - это табличное представление, которое пользователь может выбрать по своему выбору.
SecondView - это представление, которое обрабатывает UIPageViewControllerDelegate и DataSource.
ThirdView - это представление, которое будет просмотром страницы Second view.
(Вид внизу PageViewController)

Когда пользователь выбирает и нажимает кнопку на First View, он переходит к Second view.
Затем Second View представляет результат. (На самом деле, Third View показывает результат, но, кажется, он просто показан в Second View.)

Содержимое результата берется из БД на сервере в зависимости от выбора пользователя в FirstView.

Я подумал, что мне нужно получить результат с сервера в SecondView, прежде чем представлять результаты на ThirdView.

Поэтому я пишу код извлечения на viewDidLoad в SecondView View Controller.

Вот код модели данных

struct MyData: Decodable {
let a: String
let b: String
let c: String
}

Вот код класса Second View

class SecondView: UIViewController, UIPageViewControllerDelegate, 
UIPageViewControllerDataSource {

var pageViewController: UIPageViewController!
let pageControl: UIPageControl = UIPageControl()
let pageControlHeight: CGFloat = 20

var passedFromFirstVC: [String] = []
var pageTitle: [String] = []

override func viewDidLoad() {
    super.viewDidLoad()

    var request = URLRequest(url: NSURL(string: "http://xxxxx.xxx/" )! as URL)
    request.httpMethod = "POST"
    var postString = "xxxxxx"
    request.httpBody = postString.data(using: String.Encoding.utf8)

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

        if error != nil {
            return
        }

        guard let data = data else { return }

        do {
            let fetchedData = try JSONDecoder().decode([MyData].self, from: data)
            print(fetchedData)
            self.pageTitle.append(fetchedData[x].xx)

         } catch let jsonErr {
                print("Error serializing json:", jsonErr)
         }
    }
    task.resume()

А в коде viewDidLoad есть коды pageViewController.
Вот остаточные коды в viewDidLoad.

    self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "pageviewcontroller") as! UIPageViewController
    self.pageViewController.delegate = self
    self.pageViewController.dataSource = self
    self.pageViewController.view.frame = CGRect(x: 0, y: 65, width: view.frame.width, height: view.frame.height)
    let startVC = self.viewControllerAtIndex(index: 0) as! ContentViewController
    let viewControllers = NSArray(object: startVC)
    self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil)
    self.addChildViewController(self.pageViewController)
    self.view.addSubview(self.pageViewController.view)
    self.pageViewController.didMove(toParentViewController: self)
}

И чтобы сделать индекс страницы, следует этот код. Вот код.

func viewControllerAtIndex(index: Int) -> ContentViewController {

    let vc: ContentViewController = self.storyboard?.instantiateViewController(withIdentifier: "ContentViewController") as! ContentViewController

    vc.pageIndex = index
    print("page just has been moved...")
    print(pageTitles)

    vc.titleText = pageTitles[index]
    return vc
}

Но, когда я запускаю приложение, оно останавливается vc.titleText = pageTitles[index] в этом коде.
Потому что pageTitles равны нулю.

Поэтому я установил точку останова на viewDidLoad и обнаружил, что task не скомпилировано.

Он игнорирует коды task и task.resume(), а затем соответствует следующим кодам.

Итак, код DispatchQueue.main.async не может работать с моим кодом.

Но когда я установил определенное начальное значение в pageTitle (даже после task.resume()), тогда task было скомпилировано после компиляции кодов, связанных с другими PageViewController.

И, когда я сделал этот код в другом проекте с одним ViewController (не похожим на мой PageViewController), он также компилирует код task в viewDidLoad.

Почему task код в этом вопросе не был скомпилирован?

И как мне получить данные перед компиляцией кода контроллера просмотра страниц?

1 Ответ

0 голосов
/ 08 ноября 2018

Я нашел ответ из комментариев от к этой записи .
Это комментарий.

Переместите строку print (sceneArray) и все, что вы хотите сделать потомиз viewDidLoad в блок завершения после self.scenarioArray = ....

Точка «помещает другие коды в viewDidLoad в блок завершения (в этом коде, блок do) путемDispatchQueue.main.async { code } в do блок.

Вот ответ.

override func viewDidLoad() {

    super.viewDidLoad()
    var request = URLRequest(url: NSURL(string: "http://xxxxx.xxx/" )! as URL)
    request.httpMethod = "POST"
    var postString = "xxxxxx"
    request.httpBody = postString.data(using: String.Encoding.utf8)

    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
            if error != nil {
            return
            }
            guard let data = data else { return }

            do {
                let fetchedData = try JSONDecoder().decode([MyData].self, from: data)
                self.pageTitle.append(fetchedData[x].xx)

                DispatchQueue.main.async {
                    self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "pageviewcontroller") as! UIPageViewController
                    self.pageViewController.delegate = self
                    self.pageViewController.dataSource = self
                    self.pageViewController.view.frame = CGRect(x: 0, y: 65, width: view.frame.width, height: view.frame.height)
                    let startVC = self.viewControllerAtIndex(index: 0) as! ContentViewController
                    let viewControllers = NSArray(object: startVC)
                    self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil)
                    self.addChildViewController(self.pageViewController)
                    self.view.addSubview(self.pageViewController.view)
                    self.pageViewController.didMove(toParentViewController: self)
                 }
            } catch let jsonErr {
                    print("Error serializing json:", jsonErr)
            }
        }
    task.resume()
}


Но, имейте в виду view в CGRect ширина и высотакод.

self.pageViewController.view.frame = CGRect(x: 0, y: 65, width: view.frame.width, height: view.frame.height)

Когда вы поместите этот код в блок 'do', view приведет к неоднозначной ошибке.

Затем измените этот код на это.

self.pageViewController.view.frame = CGRect(x: 0, y: 65, width: self.pageViewController.view.frame.width, height: self.pageViewController.view.frame.height)

Надеюсь, эта помощь!

...