I'm trying to build a engine that will take a few pieces of data and parse them through a wikidata query...there are two url session tasks here is my code, but for some reason I can't get the functions to perform the networking to execute...what am I missing?
struct BDayWikiDataManager {
func fetchBDayDataFromWikipedia(numMonth: String, numDay: String) -> (String, String, String) {
var personLabelCode = "no value"
var occupationLabelCode = "no value"
var dob = "no value"
var personName = "no value"
var occupationName = "no value"
let firstURL = "https://query.wikidata.org/sparql?query=SELECT%20distinct%20%3Fperson%20%3FpersonLabel%20%3Fdob%20%3Foccupation%20%3FoccupationLabel%20%3Fawards%20%3FawardsLabel%0AWHERE%0A{%0A%20%20%3Fperson%20wdt%3AP31%20wd%3AQ5%3B%0A%20%20%20%20%20%20%20%20%20%20wdt%3AP27%20wd%3AQ30%3B%0A%20%20%20%20%20%20%20%20%20%20wdt%3AP569%20%3Fdob%3B%0A%20%20%20%20%20%20%20%20%20%20wdt%3AP166%20%3Fawards%3B%0A%20%20%20%20%20%20%20%20%20%20wdt%3AP106%20%3Foccupation.%0A%20%20OPTIONAL%20{%3Fperson%20wdt%3AP166%20%3Fawards}%0A%20%20FILTER(DAY(%3Fdob)%20%3D%20\(numDay)).%0A%20%20FILTER(MONTH(%3Fdob)%20%3D%20\(numMonth)).%0A%20%20FILTER(YEAR(%3Fdob)%20%3E%3D%201940).%0A%20%20FILTER%20(%3Foccupation%20in%20(%20wd%3AQ33999%2C%20wd%3AQ639669%2C%20wd%3AQ2066131%2C%20wd%3AQ947873%2C%20wd%3AQ15265344%20)%20)%0A%20%20SERVICE%20wikibase%3Alabel%20{%20bd%3AserviceParam%20wikibase%3Alanguage%20%22[AUTO_LANGUAGE]%22.%20}%20%0A}%0ALIMIT%2050&format=json"
performRequestFirstURL(with: firstURL) { (data, error) in
if error != nil {
print(error as Any)
}
personLabelCode = data!.personLabel
print(personLabelCode)
occupationLabelCode = data!.occupationLabel
dob = data!.dob
}
print(personLabelCode)
let secondUrl = "https://www.wikidata.org/w/api.php?action=wbgetentities&ids=\(personLabelCode)|\(occupationLabelCode)&format=json&props=labels&languages=en"
let _ = performRequestSecondURL(with: secondUrl, personLabel: personLabelCode, occupationLabel: occupationLabelCode) { (data, error) in
if error != nil {
fatalError("performRequestSecondURL failed, error = \(String(describing: error))")
}
personName = data!.personName
occupationName = data!.occupationName
}
return (personName, occupationName, dob)
}
func performRequestFirstURL(with urlString: String, userCompletionHandler: @escaping (FirstURLData?, Error?) -> Void) {
if let url = URL(string: urlString) {
URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
if let data = data {
let jsonDecoder = JSONDecoder()
do {
let parsedJSON = try jsonDecoder.decode(FirstURLIncomingData.self, from: data)
print(parsedJSON)
let numberOfBindings = parsedJSON.results.bindings.count
let randomBindingNumber = Int.random(in: 0...(numberOfBindings - 1))
let dob = parsedJSON.results.bindings[randomBindingNumber].dob.value
let personLabel = parsedJSON.results.bindings[randomBindingNumber].personLabel.value
let occupationLabel = parsedJSON.results.bindings[randomBindingNumber].occupationLabel.value
let finalData = FirstURLData(dob: dob, personLabel: personLabel, occupationLabel: occupationLabel)
userCompletionHandler(finalData, nil)
} catch {
print(error)
userCompletionHandler(nil,error)
}
}
})
.resume()
}
}
func performRequestSecondURL(with urlString: String, personLabel: String, occupationLabel: String, userCompletionHandler: @escaping (SecondURLData?, Error?) -> Void) {
if let url = URL(string: urlString) {
URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
if let data = data {
let jsonDecoder = JSONDecoder()
do {
let parsedJSON = try jsonDecoder.decode(SecondURLIncomingData.self, from: data)
print(parsedJSON)
let name = parsedJSON.entities[personLabel]?.labels.en.value
let occupation = parsedJSON.entities[occupationLabel]?.labels.en.value
let finalData = SecondURLData(personName: name!, occupationName: occupation!)
userCompletionHandler(finalData, nil)
} catch {
print(error)
userCompletionHandler(nil,error)
}
}
})
.resume()
}
}
}
//MARK: - incoming data model - first url
struct FirstURLIncomingData: Codable {
let results: Results
}
struct Results: Codable {
let bindings: [Bindings]
}
struct Bindings: Codable {
let dob: DOB
let personLabel: PersonLabel
let occupationLabel: OccupationLabel
}
struct DOB: Codable {
let value: String
}
struct PersonLabel: Codable {
let value: String
}
struct OccupationLabel: Codable {
let value: String
}
//MARK: - incoming data model - second url
struct SecondURLIncomingData: Decodable {
let entities: [String : Locator]
}
struct Locator: Decodable {
let labels: Labels
}
struct Labels: Decodable {
let en: EN
}
struct EN: Decodable {
let value: String
}
//MARK: - model of data for both urls
struct FirstURLData: Decodable {
let dob: String
let personLabel: String
let occupationLabel: String
}
struct SecondURLData {
let personName: String
let occupationName: String
}
let manager = BDayWikiDataManager()
let data = manager.fetchBDayDataFromWikipedia(numMonth: "8", numDay: "13")
print(data) //prints "no data" for everything, which means the values didnt update
Worth noting: when I go to the url's manually, I get json responses in my browser, so I know the url's are correct...