【问题标题】:Swift URLSession not working before making PageViewSwift URLSession 在制​​作 PageView 之前不起作用
【发布时间】:2019-04-11 15:38:17
【问题描述】:

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

我有 3 个视图。

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

当用户选择并点击First View 上的按钮时,它会转到Second view
然后,Second View 显示结果。 (其实Third View显示了结果,但好像只是在Second View中显示了。)

结果的内容来自服务器上的数据库,基于用户在FirstView中的选择。

我认为在ThirdView 上显示结果之前,我需要从SecondView 中的服务器获取结果。

所以我在SecondViewView Controller中的viewDidLoad上写了获取代码。

这是数据模型代码

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没有被编译。

它忽略tasktask.resume()代码,然后遵守以下代码。

所以,DispatchQueue.main.async 代码不能用于我的代码。

但是,当我在pageTitle中设置了某个初始值(即使在task.resume()之后),那么task在编译了其他PageViewController相关的代码之后就已经编译好了。

而且,当我在另一个项目中使用一个 ViewController(不像我的 PageViewController)编写此代码时,它还会在 viewDidLoad 中编译 task 代码。

为什么这个问题中的task代码没有被编译?

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

【问题讨论】:

  • 您的问题与URLSession无关。我想您的代码因index our of range 错误异常而崩溃。尝试谷歌它

标签: ios swift nsurlsession uipageviewcontroller urlsession


【解决方案1】:

我从this post的cmets那里找到了答案。
这是评论。

将行 print(scenarioArray) 和之后你想做的所有事情从 viewDidLoad 移到 self.scenarioArray = ....之后的完成块中。

重点是通过将DispatchQueue.main.async { code } 放入do 块中,将viewDidLoad 中的其他代码放入完成块(在此代码中为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)

希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-04
    • 2017-09-06
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    相关资源
    最近更新 更多