Ios 同一视图控制器上显示多个API的问题-多个调度队列
我正在开发一个应用程序,它从几个不同的来源提取数据,并将其显示在视图控制器上。我试图显示来自ChartsData和AirportData的数据,而不是获取“N/A”或空白值。我有其他使用其中一个来源的数据的工作VCs,但无法让它们都渲染Ios 同一视图控制器上显示多个API的问题-多个调度队列,ios,swift,xcode,api,viewcontroller,Ios,Swift,Xcode,Api,Viewcontroller,我正在开发一个应用程序,它从几个不同的来源提取数据,并将其显示在视图控制器上。我试图显示来自ChartsData和AirportData的数据,而不是获取“N/A”或空白值。我有其他使用其中一个来源的数据的工作VCs,但无法让它们都渲染 // // ChartsViewController.swift // AvWx Pro // // Created by Grayson Bertaina on 9/25/20. // import UIKit class ChartsViewCon
//
// ChartsViewController.swift
// AvWx Pro
//
// Created by Grayson Bertaina on 9/25/20.
//
import UIKit
class ChartsViewController: UIViewController, AirportManagerDelegate, ChartManagerDelegate {
func didUpdateAirport(_ airportManager: AirportManager, airports: AirportModel) {
DispatchQueue.main.async {
self.icaoLabel.text = airports.airportICAO
self.managerLabel.text = airports.airportManager
self.managerPhone.text = airports.airportManagerPhone
self.tpaLabel.text = airports.trafficPatternAltitude
print(airports.trafficPatternAltitude ?? "N/A")
}
}
func didFailWithErrorAirport(error: Error) {
print("error! Airport Error")
}
func didUpdateChart(_ dataManager: ChartManager, charts: ChartModel) {
DispatchQueue.main.async {
self.cityLabel.text = charts.cityString
self.stateLabel.text = charts.stateString
self.titleAirportLabel.text = charts.airportNameString
print(charts.cityString ?? "N/A")
}
}
func didFailWithErrorChart(error: Error) {
print("error! Chart Error")
}
var airportPassed: String = ""
@IBOutlet weak var titleAirportLabel: UILabel!
@IBOutlet weak var icaoLabel: UILabel!
@IBOutlet weak var ctafLabel: UILabel!
@IBOutlet weak var ctafTitleLabel: UILabel!
@IBOutlet weak var unicomTitleLabel: UILabel!
@IBOutlet weak var unicomLabel: UILabel!
@IBOutlet weak var managerLabel: UILabel!
@IBOutlet weak var managerPhone: UILabel!
@IBOutlet weak var isToweredLabel: UILabel!
@IBOutlet weak var cityLabel: UILabel!
@IBOutlet weak var stateLabel: UILabel!
@IBOutlet weak var magVarLabel: UILabel!
@IBOutlet weak var tpaLabel: UILabel!
var chartmanager = ChartManager()
var airportmanager = AirportManager()
override func viewDidLoad() {
super.viewDidLoad()
airportmanager.delegate = self
chartmanager.delegate = self
airportmanager.fetchAirport(stationICAO: airportPassed)
chartmanager.fetchCharts(stationICAO: airportPassed)
print(airportPassed + " was the airport given")
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
我已经尝试解决这个问题一段时间了,包括尝试各种类型的显示方法。我感谢任何指导
我在使用不同视图控制器上的两个按钮时也遇到问题-它们都应该转到不同的VC并传递一段数据,但我不能将它们都放在func prepare()中而不出错。提前谢谢你的帮助
//
// WeatherModel.swift
// AvWx Pro
//
// Created by Grayson Bertaina on 9/22/20.
//
import Foundation
struct ChartModel {
let airportNameString: String?
let stateString: String?
let cityString: String?
let chartCodeString: String?
let chartNameString: String?
let pdfPathString: String?
}
struct AirportModel {
let airportICAO: String?
let airportManager: String?
let airportManagerPhone: String?
let airportElevation: String?
let magneticDeviation: String?
let trafficPatternAltitude: String?
let towered: String?
let unicomFreq: String?
let ctafFreq: String?
}
// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse the JSON, add this file to your project and do:
//
// let chartData = try? newJSONDecoder().decode(ChartData.self, from: jsonData)
import Foundation
// MARK: - ChartData
struct ChartData: Codable {
let dataPoints: [DataPoints?]
}
// MARK: - Kdab
struct DataPoints: Codable {
let state: String?
let stateFull: String?
let city: String?
let volume: String?
let airportName: String?
let military: String?
let faaIdent: String?
let icaoIdent: String?
let chartSeq, chartCode, chartName, pdfName: String
let pdfPath: String
enum CodingKeys: String, CodingKey {
case state
case stateFull = "state_full"
case city, volume
case airportName = "airport_name"
case military
case faaIdent = "faa_ident"
case icaoIdent = "icao_ident"
case chartSeq = "chart_seq"
case chartCode = "chart_code"
case chartName = "chart_name"
case pdfName = "pdf_name"
case pdfPath = "pdf_path"
}
}
// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse the JSON, add this file to your project and do:
//
// let airportData = try? newJSONDecoder().decode(AirportData.self, from: jsonData)
struct AirportData: Codable {
let siteNumber, type, facilityName, faaIdent: String
let icaoIdent, region, districtOffice, state: String
let stateFull, county, city, ownership: String
let use, manager, managerPhone, latitude: String
let latitudeSEC, longitude, longitudeSEC, elevation: String
let magneticVariation, tpa, vfrSectional, boundaryArtcc: String
let boundaryArtccName, responsibleArtcc, responsibleArtccName, fssPhoneNumber: String
let fssPhoneNumerTollfree, notamFacilityIdent, status, certificationTypedate: String
let customsAirportOfEntry, militaryJointUse, militaryLanding, lightingSchedule: String
let beaconSchedule, controlTower, unicom, ctaf: String
let effectiveDate: String
enum CodingKeys: String, CodingKey {
case siteNumber = "site_number"
case type
case facilityName = "facility_name"
case faaIdent = "faa_ident"
case icaoIdent = "icao_ident"
case region
case districtOffice = "district_office"
case state
case stateFull = "state_full"
case county, city, ownership, use, manager
case managerPhone = "manager_phone"
case latitude
case latitudeSEC = "latitude_sec"
case longitude
case longitudeSEC = "longitude_sec"
case elevation
case magneticVariation = "magnetic_variation"
case tpa
case vfrSectional = "vfr_sectional"
case boundaryArtcc = "boundary_artcc"
case boundaryArtccName = "boundary_artcc_name"
case responsibleArtcc = "responsible_artcc"
case responsibleArtccName = "responsible_artcc_name"
case fssPhoneNumber = "fss_phone_number"
case fssPhoneNumerTollfree = "fss_phone_numer_tollfree"
case notamFacilityIdent = "notam_facility_ident"
case status
case certificationTypedate = "certification_typedate"
case customsAirportOfEntry = "customs_airport_of_entry"
case militaryJointUse = "military_joint_use"
case militaryLanding = "military_landing"
case lightingSchedule = "lighting_schedule"
case beaconSchedule = "beacon_schedule"
case controlTower = "control_tower"
case unicom, ctaf
case effectiveDate = "effective_date"
}
}
//
// ChartManager.swift
// AvWx Pro
//
// Created by Grayson Bertaina on 9/21/20.
//
import Foundation
protocol ChartManagerDelegate : class {
func didUpdateChart(_ dataManager: ChartManager, charts: ChartModel)
func didFailWithErrorChart(error: Error)
}
protocol AirportManagerDelegate : class {
func didUpdateAirport(_ airportManager: AirportManager, airports: AirportModel)
func didFailWithErrorAirport(error: Error)
}
struct ChartManager {
let chartsURL = "https://api.aviationapi.com/v1/charts?apt="
weak var delegate : ChartManagerDelegate?
func fetchCharts (stationICAO: String) {
let chartString = "\(chartsURL)\(stationICAO)"
performRequest(with: chartString)
}
func performRequest (with chartString: String) {
if let charturl = URL(string: chartString) {
let session = URLSession(configuration: .default)
let charttask = session.dataTask(with: charturl) { (data, response, error) in
if error != nil {
self.delegate?.didFailWithErrorChart(error: error!)
return
}
if let chartSafeData = data {
if let charts = self.parseJSONChart(chartSafeData) {
self.delegate?.didUpdateChart(self, charts: charts)
}
}
}
charttask.resume()
print(chartString)
}
}
func parseJSONChart(_ chartData: Data) -> ChartModel? {
do {
let chartData = try? JSONDecoder().decode(ChartData.self, from: chartData)
let importedChart = chartData?.dataPoints[0]
let airportName = importedChart?.airportName
let airportState = importedChart?.state
let airportCity = importedChart?.city
let chartName = importedChart?.chartName
let chartCode = importedChart?.chartCode
let chartLink = importedChart?.pdfPath
let charts = ChartModel(airportNameString: airportName, stateString: airportState, cityString: airportCity, chartCodeString: chartCode, chartNameString: chartName, pdfPathString: chartLink)
delegate?.didUpdateChart(self, charts: charts)
return charts
} catch {
delegate?.didFailWithErrorChart(error: error)
return nil
}
}
}
struct AirportManager {
weak var delegate: AirportManagerDelegate?
let airportURL = "https://api.aviationapi.com/v1/airports?apt="
func fetchAirport (stationICAO: String) {
let airportString = "\(airportURL)\(stationICAO)"
performRequestAirport(with: airportString)
}
func performRequestAirport (with airportString: String) {
if let airporturl = URL(string: airportString) {
let session = URLSession(configuration: .default)
let airporttask = session.dataTask(with: airporturl) { (data, response, error) in
if error != nil {
self.delegate?.didFailWithErrorAirport(error: error!)
return
}
if let airportSafeData = data {
if let airports = self.parseJSONAirport(airportSafeData) {
self.delegate?.didUpdateAirport(self, airports: airports)
}
}
}
print(airportString)
airporttask.resume()
}
}
func parseJSONAirport(_ airportData: Data) -> AirportModel? {
do {
let airportData = try? JSONDecoder().decode(AirportData.self, from: airportData)
let ctaf = airportData?.ctaf
let unicom = airportData?.unicom
let manager = airportData?.manager
let managerPhone = airportData?.managerPhone
let trafficpatternaltitude = airportData?.tpa
let isTowered = airportData?.controlTower
let magVar = airportData?.magneticVariation
let airportElev = airportData?.elevation
let airportICAO = airportData?.icaoIdent
let airports = AirportModel(airportICAO: airportICAO, airportManager: manager, airportManagerPhone: managerPhone, airportElevation: airportElev, magneticDeviation: magVar, trafficPatternAltitude: trafficpatternaltitude, towered: isTowered, unicomFreq: unicom, ctafFreq: ctaf)
delegate?.didUpdateAirport(self, airports: airports)
return airports
} catch {
delegate?.didFailWithErrorAirport(error: error)
return nil
}
}
}