After completing the foundations course, I am attempting to build a small app that allows user to perform various functions associated with a website api.
One of those functions is to allow inputting of gift codes and having them be redeemed for each user (from JSON file).
Upon app start, the ContentModel gets the remote data (JSON) and puts it in a model. ==> This works GREAT!! No issues.
When the user goes to the correct tab and inputs a “gift code” and submits it, the code is sent into a ContentModel method (submitBoxCode).
This method should cycle through each person and call another method (submitToWebsite) to:
- provide that person’s data,
- decode JSON response (data) and provide appropriate feedback (success, fail, etc…)
Then it should return to the initial method (submitBoxCode) and go to the next person.
The following appears to be the sequence of events when I run through DEBUG mode:
- submitBoxCode calls first person and submits it to submitToWebsite.
- submitToWebiste creates URL and URLRequest, but DOES NOT enter the URLSession… it resumes and goes back to submitBoxCode.
This continues until all the names from the JSON have been run through, then it returns to submitToWebsite and proceeds to conduct all the URLSessions.
This is not what I expected. Why does this happen?
What am I not understanding about URLSession??
Thank you!
Code below: some specific items (like website) is scrubbed out.
ADDITIONALLY, the successfulPosting and failedtoPost dictionaries never update with the relevant information either (from the switch / case in the submitToWebsite method).
import Foundation
class ContentModel: ObservableObject {
@Published var people = [Model]()
var successfulPosting: [String:String] = [:]
var failedtoPost: [String:String] = [:]
init () {
getRemoteData()
}
// MARK: Get json data from remote site
func getRemoteData () {
// String path
// let urlString = Constants.jsonUrlLocation
let urlString = Constants.jsonUrlLocationTesting
guard let url = URL(string: urlString) else { return }
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
do {
let decodedJSON = try JSONDecoder().decode([Model].self, from: data)
DispatchQueue.main.async {
self.people += decodedJSON
}
} catch {
print("error: \(error)")
return
}
}
}.resume()
}
// MARK: Submit new box code for all names in the json
func submitBoxCode(_ boxcode: String) {
for person in people {
let state = String(person.state)
for currentName in person.members {
let name = currentName.name
self.submitToWebsite(state, name, boxcode)
}
}
print(successfulPosting)
print(failedtoPost)
return
}
func submitToWebsite(_ state: String, _ name: String, _ boxcode: String) {
let urlString = // https website with queries allowing for name, state, and boxcode to be presented as variables
guard let url = URL(string: urlString) else { return }
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
print(String(data: data, encoding: .utf8)!)
if let decodedJSON = try? JSONDecoder().decode(responseData.self, from: data) {
print(decodedJSON.code!)
switch decodedJSON.code {
case -20001:
let invalidName = "Name (\(name)) does not exist"
print(invalidName)
self.failedtoPost[name]?.append(invalidName)
case -20003:
let invalidCode = "Redemption code \(boxcode) is invalid for \(name)"
print(invalidCode)
self.failedtoPost[name]?.append(invalidCode)
case -20002:
print("Fail")
case 1:
let successful = "\(name) successfully redeemed \(boxcode)"
self.successfulPosting[name]?.append(successful)
print(self.successfulPosting)
default:
print("Failed for unknown reason")
}
}
return
}
else {
print(error!)
return
}
}.resume()
}
}