为什么不显示新视图控制器的表视图?迅速
这是以下问题的后续措辞:如何调用可以呼叫API调用的类的实例,以及在该类中的函数,并将其分配给变量?迅速。
我正在尝试将新的视图控制器推向堆栈,并从初始视图控制器中呈现此视图控制器,但是当我运行程序时,应该在新视图控制器中显示的表视图不加载在模拟器上。在运行程序之前,之中或之后,我根本没有任何错误通知。另外,似乎并没有在此新视图控制器中执行代码,因为新View Controller类的顶部/非常开头的打印语句(和View Controller .swift File)未打印。
当应该显示新的视图控制器的新表视图时所显示的是空白屏幕,但是导航栏仍在顶部,而导航栏的左上方则显示了后面的按钮(就像通常是一样当正确显示表视图之前,在更改Yelpapi类作为API请求并使用异步/等待时)。发生这种情况时,我也不会在终端中收到任何错误消息。
我认为与问题相关的是新的Yelpapi类,该类用于在此处和使用异步/等待API端点请求。直到我使用此新类和异步/等待代码重构后,这个问题才发生。
我认为可能会更具体地引起问题,是在“ func viewDidload()async {” newviewController.swift之前取出“覆盖”。我之所以这样做,是因为我将其放在那里时会遇到错误,并发现该解决方案建议将其取出,但是,这样做的问题如接受答案所述(问题是没有问题编译时间检查确保您的签名正确): SWIFT协议:方法不会从其超类中覆盖任何方法。
我已经在网上看到了这个问题(表视图未显示),包括此处,并且找不到工作解决方案。一篇类似的文章是:视图控制器不正确显示我的代码已经设置了类似地,以与公认答案相同的形式。我也让程序运行20分钟,然后再辞职,以防该请求仅出于任何原因而花费很长时间,但是,仍未介绍所需的表观视图。
代码:
drimationViewController.swift
:
//*Code for creating a table view that shows options to the user, for the user to select.*
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//*Code for assigning values to variables related to what row in the table view the user selected.*
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let newVC = storyboard.instantiateViewController(identifier: "NewViewController") as! NewViewController
newVC.modalPresentationStyle = .fullScreen
newVC.modalTransitionStyle = .crossDissolve
//Print Check.
//Prints.
print("Print Check: Right before code for presenting the new view controller.")
navigationController?.pushViewController(newVC, animated: true)
}
newViewController.swift
import UIKit
import CoreLocation
class NewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//Print Check.
//Doesn't print.
func printCheckBeforeIBOutletTableViewCode() {
print("Print Check: Right before tableView IBOutlet code at top of NewViewController.swift file.")
}
@IBOutlet var tableView: UITableView!
var venues: [Venue] = []
//Print Check.
//Doesn't print.
func printCheckAfterIBOutletTableViewCode() {
print("Print Check: Right after tableView IBOutlet code at top of NewViewController.swift file.")
}
func viewDidLoad() async {
super.viewDidLoad()
//Function calls for print checks.
//Doesn't print.
self.printCheckBeforeIBOutletTableViewCode()
self.printCheckAfterIBOutletTableViewCode()
tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomTableViewCell")
tableView.delegate = self
tableView.dataSource = self
//Print Check.
//Doesn't print.
print("Print Check: Right before creating an instance of YelpApi class, then creating a task to make the API request.")
let yelpApi = YelpApi(apiKey: "Api key")
Task {
do {
self.venues = try await yelpApi.searchBusiness(latitude: selectedLatitude, longitude: selectedLongitude, category: "category query goes here", sortBy: "sort by query goes here")
self.tableView.reloadData()
} catch {
//Handle error here.
print("Error")
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return venues.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as! CustomTableViewCell
//Details for custom table view cell go here.
}
//Rest of table view protocol functions.
}
venue.swift
:
import Foundation
// MARK: - BusinessSearchResult
struct BusinessSearchResult: Codable {
let total: Int
let businesses: [Venue]
let region: Region
}
// MARK: - Business
struct Venue: Codable {
let rating: Double
let price, phone, alias: String?
let id: String
let isClosed: Bool?
let categories: [Category]
let reviewCount: Int?
let name: String
let url: String?
let coordinates: Center
let imageURL: String?
let location: Location
let distance: Double
let transactions: [String]
enum CodingKeys: String, CodingKey {
case rating, price, phone, id, alias
case isClosed
case categories
case reviewCount
case name, url, coordinates
case imageURL
case location, distance, transactions
}
}
// MARK: - Category
struct Category: Codable {
let alias, title: String
}
// MARK: - Center
struct Center: Codable {
let latitude, longitude: Double
}
// MARK: - Location
struct Location: Codable {
let city, country, address2, address3: String?
let state, address1, zipCode: String?
enum CodingKeys: String, CodingKey {
case city, country, address2, address3, state, address1
case zipCode
}
}
// MARK: - Region
struct Region: Codable {
let center: Center
}
fetchdata.swift
:
import Foundation
import CoreLocation
class YelpApi {
private var apiKey: String
init(apiKey: String) {
self.apiKey = apiKey
}
func searchBusiness(latitude: Double,
longitude: Double,
category: String,
sortBy: String) async throws -> [Venue] {
var queryItems = [URLQueryItem]()
queryItems.append(URLQueryItem(name:"latitude",value:"\(latitude)"))
queryItems.append(URLQueryItem(name:"longitude",value:"\(longitude)"))
queryItems.append(URLQueryItem(name:"categories", value:category))
queryItems.append(URLQueryItem(name:"sort_by",value:sortBy))
var results = [Venue]()
var expectedCount = 0
let countLimit = 50
var offset = 0
queryItems.append(URLQueryItem(name:"limit", value:"\(countLimit)"))
repeat {
var offsetQueryItems = queryItems
offsetQueryItems.append(URLQueryItem(name:"offset",value: "\(offset)"))
var urlComponents = URLComponents(string: "https://api.yelp.com/v3/businesses/search")
urlComponents?.queryItems = offsetQueryItems
guard let url = urlComponents?.url else {
throw URLError(.badURL)
}
var request = URLRequest(url: url)
request.setValue("Bearer \(self.apiKey)", forHTTPHeaderField: "Authorization")
let (data, _) = try await URLSession.shared.data(for: request)
let businessResults = try JSONDecoder().decode(BusinessSearchResult.self, from:data)
expectedCount = min(businessResults.total,1000)
results.append(contentsOf: businessResults.businesses)
offset += businessResults.businesses.count
} while (results.count < expectedCount)
return results
}
}
谢谢!
更新:
从Andreas和Paulw11的建议进行更改之后,该程序运行时仍未加载表视图,我在终端中从 catch> catch
block中获得了最后的打印语句是“错误”在任务
创建Yelpapi类的实例之后,在 newViewController.swift
中创建了初始API请求。从那以后,我将文件中的“错误”语句更改为“在制作初始API端点请求时发生错误”。为了清楚。
以下是 newViewController.swift
的更新版本,其中包括Andreas和paulw11建议的更改,以及 fetchdata.swift
,并带有新的打印语句,以帮助识别新问题。在这些更新的版本下方是对Andreas和Paulw11的建议更改后的终端的返回语句,该更改还包含FetchData.Swift更新版本中的新打印语句(以帮助识别新问题)。
newViewController.swift
的更新版本替代插入和 async
删除:
import UIKit
import CoreLocation
class NewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//Print Check.
//Prints.
func printCheckBeforeIBOutletTableViewCode() {
print("Print Check: Right before tableView IBOutlet code at top of NewViewController.swift file.")
}
@IBOutlet var tableView: UITableView!
var venues: [Venue] = []
//Print Check.
//Prints.
func printCheckAfterIBOutletTableViewCode() {
print("Print Check: Right after tableView IBOutlet code at top of NewViewController.swift file.")
}
override func viewDidLoad() {
super.viewDidLoad()
//Function calls for print checks.
//Prints.
self.printCheckBeforeIBOutletTableViewCode()
self.printCheckAfterIBOutletTableViewCode()
tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomTableViewCell")
tableView.delegate = self
tableView.dataSource = self
//Print Check.
//Prints.
print("Print Check: Right before creating an instance of YelpApi class, then creating a task to make the API request.")
let yelpApi = YelpApi(apiKey: "Api key")
Task {
do {
self.venues = try await yelpApi.searchBusiness(latitude: selectedLatitude, longitude: selectedLongitude, category: "category query goes here", sortBy: "sort by query goes here")
self.tableView.reloadData()
} catch {
//Handle error here.
//Prints.
print("Error")
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return venues.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as! CustomTableViewCell
//Details for custom table view cell go here.
}
//Rest of table view protocol functions.
}
fetchdata.swift.swift
更新版本新的打印语句以帮助识别新问题:
import Foundation
import CoreLocation
class YelpApi {
private var apiKey: String
init(apiKey: String) {
self.apiKey = apiKey
}
func searchBusiness(latitude: Double,
longitude: Double,
category: String,
sortBy: String) async throws -> [Venue] {
var queryItems = [URLQueryItem]()
queryItems.append(URLQueryItem(name:"latitude",value:"\(latitude)"))
queryItems.append(URLQueryItem(name:"longitude",value:"\(longitude)"))
queryItems.append(URLQueryItem(name:"categories", value:category))
queryItems.append(URLQueryItem(name:"sort_by",value:sortBy))
var results = [Venue]()
var expectedCount = 0
let countLimit = 50
var offset = 0
queryItems.append(URLQueryItem(name:"limit", value:"\(countLimit)"))
//Print Check.
//Prints.
print("Print Check: Line before repeat-while loop.")
repeat {
//Print Check.
//Prints.
print("Print Check: Within repeat-while loop and before first line of code within it.")
var offsetQueryItems = queryItems
offsetQueryItems.append(URLQueryItem(name:"offset",value: "\(offset)"))
var urlComponents = URLComponents(string: "https://api.yelp.com/v3/businesses/search")
urlComponents?.queryItems = offsetQueryItems
guard let url = urlComponents?.url else {
throw URLError(.badURL)
}
var request = URLRequest(url: url)
request.setValue("Bearer \(self.apiKey)", forHTTPHeaderField: "Authorization")
//Print Check.
//Prints.
print("Print Check: Within repeat-while loop and before 'let (data, _) = try await' line of code.")
let (data, _) = try await URLSession.shared.data(for: request)
//Print Check.
//Prints.
print("Print Check: Within repeat-while loop and before 'let businessResults = try JSONDecoder()' line of code.")
let businessResults = try JSONDecoder().decode(BusinessSearchResult.self, from:data)
//Print Check.
//Doesn't print.
print("Print Check: Within repeat-while loop and right after 'let businessResults = try JSONDecoder()' line of code.")
expectedCount = min(businessResults.total,1000)
results.append(contentsOf: businessResults.businesses)
offset += businessResults.businesses.count
} while (results.count < expectedCount)
//Print Check.
//Doesn't print.
print("Print Check: After repeat-while loop and before 'return results' code.")
return results
}
}
在制作Andreas和Paulw11的建议更改和运行程序
中返回的终端返回的打印语句:
Print Check: Right before code for presenting the new view controller.
Print Check: Right before tableView IBOutlet code at top of NewViewController.swift file.
Print Check: Right after tableView IBOutlet code at top of NewViewController.swift file.
Print Check: Right before creating an instance of YelpApi class, then creating a task to make the API request.
Print Check: Line before repeat-while loop.
Print Check: Within repeat-while loop and before first line of code within it.
Print Check: Within repeat-while loop and before 'let (data, _) = try await' line of code.
Date and Time, Project Name, and some other info [boringssl] boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics
Print Check: Within repeat-while loop and before 'let businessResults = try JSONDecoder()' line of code.
Error occurred when making initial API endpoint request.
必须退出程序,因为它“停滞不前”/在进行最后一次之后什么也没做终端上的打印语句。
另外,“日期和时间,项目名称以及其他一些信息[boringssl] boringssl_metrics_metrics_log_metric_block_invoke(153)未能登录指标”,每当我提出API请求时,就会出现打印语句,并且在研究时,不会对任何问题造成任何问题。项目。
在“发出初始API端点请求时发生错误”之前打印的最后一个打印语句。是“打印检查:在重复循环中,然后在'Let businessResults = try jsondecoder()'代码行之前。”表明代码的行中出现了问题,让businessResults = try jsondecoder()。decode(butinessSearchResult.self,from:data)
,这使我认为问题可能正在发生并成为与类别
和 sort_by
在 searchbusinesses
yelpapi fetchdata.swift
中的类定义。我正在努力解决此问题,如果我弄清楚,将更新。
感谢您的帮助!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您已经确定了其中一个问题。您的代码在
func viewDidload()async
永远不会执行,因为没有人调用它。通过添加async
您不再覆盖原始uiviewController
方法。 (请参阅)您可以删除
async
并再次覆盖它吗?我认为这至少应该执行代码,您应该看到打印语句。I think you identified one of the issues already. Your code in
func viewDidLoad() async
will never be executed, because no-one calls it. By addingasync
you are not overriding the originalUIViewController
method anymore. (see https://developer.apple.com/documentation/uikit/uiviewcontroller/1621495-viewdidload)Can you remove
async
and override it again? I think that should at least execute the code and you should see your print statements.