Swift URLSession在制作PageView之前不起作用

时间:2018-11-08 06:26:02

标签: ios swift nsurlsession uipageviewcontroller urlsession

我已阅读this post,但无法解决问题。
DispatchQueue.main.async代码无法使用我的代码。
我认为我的问题与此有所不同。所以我发表了我的问题。

我有3个意见。

enter image description here

FirstView是一个表视图,用户可以选择其选择。
SecondView是处理UIPageViewControllerDelegateDataSource的视图。
ThirdView是一个视图,将是Second view的页面视图。
(底部的视图是PageViewController

当用户选择并点击First View上的按钮时,它将转到Second view
然后,Second View给出结果。 (实际上,Third View显示了结果,但似乎只显示在Second View中。)

结果的内容来自服务器上的数据库,具体取决于FirstView中用户的选择。

我认为我需要先从SecondView中的服务器获取结果,然后再在ThirdView上显示结果。

因此,我将获取代码写在viewDidLoad的{​​{1}}的{​​{1}}上。

这是数据模型代码

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尚未编译。

它忽略viewDidLoadtask代码,然后遵循以下代码。

因此,task代码无法使用我的代码。

但是,当我在task.resume()中设置某个初始值时(甚至在DispatchQueue.main.async之后),则pageTitle是在编译与其他task.resume()相关的代码之后编译的。

而且,当我仅用一个task(不像我的PageViewController)在另一个项目中编写此代码时,它也会在ViewController中编译PageViewController代码。 / p>

为什么这个问题中的task代码尚未编译?

而且,如何在编译页面视图控制器代码之前获取数据?

1 个答案:

答案 0 :(得分:0)

我从this post的评论中找到了答案。
这是评论。

  

在self.scenarioArray = ...之后,将行print(scenarioArray)以及之后要执行的所有操作从viewDidLoad移至完成块。

要点是通过在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()
}


但是,请注意CGRect宽度和高度代码中的view

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)

希望获得帮助!