I have read this post, but I couldn't solve my problem.
DispatchQueue.main.async
code cannot work to my code.
I think my problem is a little bit different from that. So I post my question.
I have 3 views.
FirstView
is a table view that user can select their choice.
SecondView
is a view that handles UIPageViewControllerDelegate
and DataSource
.
ThirdView
is a view which will be page views of Second view
.
(The view at the bottom is PageViewController
)
When user selects and tap the button on the First View
, it goes to the Second view
.
Then, Second View
presents the result. (Actually, Third View
shows the result, but it seems to be just shown in the Second View
.)
The contents of the result are from the DB on server based on user's selection in the FirstView
.
I thought that I need to fetched the result from server in the SecondView
before presenting results on the ThirdView
.
So I write the fetching code on the viewDidLoad
in the SecondView
's View Controller
.
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
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.
Here's the residual codes in 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.
Because, pageTitles
are nil.
So I set a breakpoint on the viewDidLoad
, and I found that task
had not been compiled.
It ignores task
and task.resume()
code, and then complies the following codes.
So, DispatchQueue.main.async
code cannot work to my code.
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
.
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
.
Why task
code in this question had not been compiled?
And, how can I fetch data before compiling page view controller code?