[英]Swift URLSession not working before making PageView
I have read this post , but I couldn't solve my problem. 我已经阅读了这篇文章 ,但无法解决我的问题。
DispatchQueue.main.async
code cannot work to my code. DispatchQueue.main.async
代码无法对我的代码起作用。
I think my problem is a little bit different from that. 我认为我的问题与此有所不同。 So I post my question.
所以我发表了我的问题。
I have 3 views. 我有3个意见。
FirstView
is a table view that user can select their choice. FirstView
是一个表视图,用户可以选择自己的选择。
SecondView
is a view that handles UIPageViewControllerDelegate
and DataSource
. SecondView
是处理UIPageViewControllerDelegate
和DataSource
的视图。
ThirdView
is a view which will be page views of Second view
. ThirdView
是一个视图,它将是Second view
页面Second view
。
(The view at the bottom is PageViewController
) (底部的视图是
PageViewController
)
When user selects and tap the button on the First View
, it goes to the Second view
. 当用户选择并点击“
First View
上的按钮时,它将转到Second view
。
Then, Second View
presents the result. 然后,
Second View
呈现结果。 (Actually, Third View
shows the result, but it seems to be just shown in the Second View
.) (实际上,“
Third View
显示了结果,但似乎仅在“ Second View
。)
The contents of the result are from the DB on server based on user's selection in the FirstView
. 结果的内容基于用户在
FirstView
的选择来自服务器上的FirstView
。
I thought that I need to fetched the result from server in the SecondView
before presenting results on the ThirdView
. 我想,我需要从服务器获取的结果
SecondView
上呈现结果之前ThirdView
。
So I write the fetching code on the viewDidLoad
in the SecondView
's View Controller
. 因此,我在
SecondView
的View Controller
的viewDidLoad
上编写了获取代码。
Here's the data model code 这是数据模型代码
struct MyData: Decodable {
let a: String
let b: String
let c: String
}
Here's the Second View
class code 这是
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()
And in viewDidLoad
code, the pageViewController
codes are there. 在
viewDidLoad
代码中,存在pageViewController
代码。
Here's the residual codes in viewDidLoad
. 这是
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)
}
And to make page index, this code is followed. 为了使页面索引,请遵循以下代码。 Here's the code.
这是代码。
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
}
But, when I run the app, it stops vc.titleText = pageTitles[index]
in this code. 但是,当我运行该应用程序时,它将在此代码中停止
vc.titleText = pageTitles[index]
。
Because, pageTitles
are nil. 因为,
pageTitles
为零。
So I set a breakpoint on the viewDidLoad
, and I found that task
had not been compiled. 因此,我在
viewDidLoad
上设置了一个断点,发现该task
尚未编译。
It ignores task
and task.resume()
code, and then complies the following codes. 它忽略
task
和task.resume()
代码,然后遵循以下代码。
So, DispatchQueue.main.async
code cannot work to my code. 因此,
DispatchQueue.main.async
代码无法对我的代码起作用。
But, when I set certain initial value in pageTitle
(even after task.resume()
), then task
had been compiled after compiling codes related to other PageViewController
. 但是,当我在
pageTitle
设置某个初始值时(甚至在task.resume()
),则task
是在编译与其他PageViewController
相关的代码之后编译的。
And, when I made this code in another project with a just single ViewController
(not like my PageViewController
), it also compiles task
code in viewDidLoad
. 而且,当我仅使用一个
ViewController
在另一个项目中创建此代码时(不同于我的PageViewController
),它也会在viewDidLoad
编译task
代码。
Why task
code in this question had not been compiled? 为什么这个问题中的
task
代码尚未编译?
And, how can I fetch data before compiling page view controller code? 而且,如何在编译页面视图控制器代码之前获取数据?
I found the answer from comments from this post . 我从这篇文章的评论中找到了答案。
This is the comment. 这是评论。
Move the line print(scenarioArray) and everything you want to do afterwards from viewDidLoad into the completion block after self.scenarioArray = ....
在self.scenarioArray = ...之后,将行print(scenarioArray)以及以后要执行的所有操作从viewDidLoad移至完成块。
The point is 'put other codes in viewDidLoad
into completion block(in this code, do
block) by making DispatchQueue.main.async { code }
in do
block. 点是“把其它代码在
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
in CGRect width and height code. view
。 self.pageViewController.view.frame = CGRect(x: 0, y: 65, width: view.frame.width, height: view.frame.height)
When you put this code in 'do' block, view
will bring ambiguous error of. 当您将此代码放在“ do”块中时,
view
将带来模棱两可的错误。
Then modify that code to this. 然后修改该代码。
self.pageViewController.view.frame = CGRect(x: 0, y: 65, width: self.pageViewController.view.frame.width, height: self.pageViewController.view.frame.height)
Hope this help! 希望有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.