I'm currently making an app in swift that essentially functions as a virtual stock trading game. I was able to get most of the data I need using Yahoo's YQL service. A particular feature that I am working on now is a search function so that users can search for a stock ticker. I am making the app for IOS using Swift. The problem is I call JSON using this url:
http://d.yimg.com/autoc.finance.yahoo.com/autoc?query=f&callback=YAHOO.Finance.SymbolSuggest.ssCallback
Which includes the extra text "YAHOO.Finance.SymbolSuggest.ssCallback(" and ")" around the JSON data which causes the code to be unable to parse the JSON data. How can I remove this? Thank you in advance.
Here is my code:
let callURL = NSURL(string: "http://d.yimg.com/autoc.finance.yahoo.com/autoc?query=f&callback=YAHOO.Finance.SymbolSuggest.ssCallback")
var errorEncountered: Bool = false
var downloadFinished: Bool = false
var arrayOfStockResults: [[String]] = []
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask =
sharedSession.downloadTaskWithURL(callURL!, completionHandler: {
(location: NSURL!, response: NSURLResponse!, error: NSError!)
-> Void in
if (error != nil) {
errorEncountered = true
}
if (errorEncountered == false) {
let dataObject = NSData(contentsOfURL: location)
let stocksDictionary =
NSJSONSerialization.JSONObjectWithData(dataObject!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println(stocksDictionary)
if (error != nil) {
errorEncountered = true
}
downloadFinished = true
I don't know why you're using downloadTaskWithURL and then using NSData's dataWithContentsOfURL to get the data. It's simpler to use dataTaskWithURL. The following code worked for me to download the data, convert it to a string, trim that string to remove unwanted text, convert that string back to an NSData object, and finally to get the dictionary.
var sharedSession: NSURLSession!
override func viewDidLoad() {
super.viewDidLoad()
let callURL = NSURL(string: "http://d.yimg.com/autoc.finance.yahoo.com/autoc?query=f&callback=YAHOO.Finance.SymbolSuggest.ssCallback")
var arrayOfStockResults: [[String]] = []
sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDataTask = sharedSession.dataTaskWithURL(callURL!, completionHandler: { (data, response, error) -> Void in
if error != nil {
println(error)
}else{
var jsonError: NSError?
var text: NSString = NSString(data: data, encoding: 4)!
var range = text.rangeOfString("ssCallback")
var subtext: NSString = text.substringFromIndex(range.location + range.length)
var finalText = subtext.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "()")) // trim off the parentheses at both ends
var trimmedData = finalText.dataUsingEncoding(4, allowLossyConversion: false)
if let stocksDictionary = NSJSONSerialization.JSONObjectWithData(trimmedData!, options: .AllowFragments, error: &jsonError) as? NSDictionary {
println(stocksDictionary)
}else{
println(jsonError)
}
}
})
downloadTask.resume()
}
You could substring the request body
let startIndex = //enough to cut out yahoo prepend
let endIndex = //enough to cut off that ending paren
//assuming some data variable for request body
data.substringWithRange(Range<String.Index>(start: startIndex, end: endIndex))
then json-ify it!
Related
I'm trying to do something very simple; get the same video results displayed in my app as are displayed when you search Youtube.com and sort by Upload count.
Almost everything else works fine, I can:
fetch the thumbnail, title, and channel name
play the video
*Working on getting each video's view count too (I've heard you need
to create two requests?)
What really confuses me is how this code:
var urlString = "https://www.googleapis.com/youtube/v3/search?
part=snippet
&fields=items(id,snippet(title,channelTitle,thumbnails))
&order=viewCount
&q=\(searchBar.text)
&type=video
&maxResults=25&key=\(apiKey)"
produces this result:
instead of something like this:
*Excluding the playlist
What is wrong with my code?
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchBar.resignFirstResponder()
// Form the request URL string.
var urlString = "https://www.googleapis.com/youtube/v3/search?part=snippet&fields=items(id,snippet(title,channelTitle,thumbnails))&order=viewCount&q=\(searchBar.text)&type=video&maxResults=25&key=\(apiKey)"
urlString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
// Create a NSURL object based on the above string.
let targetURL = NSURL(string: urlString)
// Get the results.
performGetRequest(targetURL, completion: { (data, HTTPStatusCode, error) -> Void in
if HTTPStatusCode == 200 && error == nil {
// Convert the JSON data to a dictionary object.
let resultsDict = (try! NSJSONSerialization.JSONObjectWithData(data!, options: [])) as! Dictionary<NSObject, AnyObject>
// Get all search result items ("items" array).
let items: Array<Dictionary<NSObject, AnyObject>> = resultsDict["items"] as! Array<Dictionary<NSObject, AnyObject>>
// Loop through all search results and keep just the necessary data.
for var i=0; i<items.count; ++i {
let snippetDict = items[i]["snippet"] as! Dictionary<NSObject, AnyObject>
// let statisticsDict = items[i]["statistics"] as! Dictionary<NSObject, AnyObject>
// Create a new dictionary to store the video details.
var videoDetailsDict = Dictionary<NSObject, AnyObject>()
videoDetailsDict["title"] = snippetDict["title"]
videoDetailsDict["channelTitle"] = snippetDict["channelTitle"]
videoDetailsDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<NSObject, AnyObject>)["default"] as! Dictionary<NSObject, AnyObject>)["url"]
videoDetailsDict["videoID"] = (items[i]["id"] as! Dictionary<NSObject, AnyObject>)["videoId"]
// videoDetailsDict["viewCount"] = statisticsDict["viewCount"]
self.videosArray.append(videoDetailsDict)
// Reload the tableview.
self.tableView.reloadData()
}
}
else {
print("HTTP Status Code = \(HTTPStatusCode)")
print("Error while loading channel videos: \(error)")
}
})
}
// MARK: Custom method implementation
func performGetRequest(targetURL: NSURL!, completion: (data: NSData?, HTTPStatusCode: Int, error: NSError?) -> Void) {
let request = NSMutableURLRequest(URL: targetURL)
request.HTTPMethod = "GET"
let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfiguration)
let task = session.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
completion(data: data, HTTPStatusCode: (response as! NSHTTPURLResponse).statusCode, error: error)
})
})
task.resume()
}
The issue was quite simple actually, much to my relief/frustration.
In the url, this was the issue:
\(searchBar.text)
searchBar.text is an optional and that's why the results were coming back different from the youtube.com search. Simple fix:
\(searchBar.text!)
I'm using a bar code scanner to get data on a scanned book using the google books api. I successfully call the API and get a JSON object back.
I'm trying to get the book title which follows the path items.volumeInfo.title.
When I call valueForPath on the JSON object returned by the API and attempt to print it (the title), I end up printing:
Optional((
"A Dance with Dragons"
))
I can't seem to figure out how to actually get the string out of the printed optional. I tried as! String and jsonResult.valueForKeyPath("items.volumeInfo.title")!, but the first simply complained to me and the second only removed the optional and outside set of parentheses.
func getBookInfo(isbn: String) {
var url: String = "https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn;
var request: NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if (jsonResult != nil) {
println(jsonResult.valueForKeyPath("items.volumeInfo.title"))
//self.json.setValue(jsonResult.valueForKeyPath("items.volumeInfo.title")!, forKey: "title")
} else {
GlobalConstants.AlertMessage.displayAlertMessage("Error fetching data from barcode, please try again.", view: self)
}
})
}
The response you get from the API is an array of titles.
I suggest using if let to unwrap the Optional value you get from KVC, and typecasting the result as a Swift array of Strings.
Swift 1
func getBookInfo(isbn: String) {
var url: String = "https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn
var request: NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: error) as? NSDictionary {
if let arrayOfTitles = jsonResult.valueForKeyPath("items.volumeInfo.title") as? [String] {
let titles = ", ".join(arrayOfTitles)
println(titles)
} else {
// error: no title found
}
} else {
GlobalConstants.AlertMessage.displayAlertMessage("Error fetching data from barcode, please try again.", view: self)
}
})
}
getBookInfo("0553283685") // prints "Hyperion"
Swift 2
For this version we're using NSURLSession because NSURLConnection is now deprecated.
func getBookInfo(isbn: String) {
let urlString = "https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn
if let url = NSURL(string: urlString) {
NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: {data, _, error -> Void in
if let error = error {
print(error.localizedDescription)
} else {
if let data = data,
jsonResult = try? NSJSONSerialization.JSONObjectWithData(data, options: []),
arrayOfTitles = jsonResult.valueForKeyPath("items.volumeInfo.title") as? [String] {
let titles = arrayOfTitles.joinWithSeparator(", ")
print(titles)
} else {
GlobalConstants.AlertMessage.displayAlertMessage("Error fetching data from barcode, please try again.", view: self)
}
}
}).resume()
}
}
getBookInfo("0553283685") // prints "Hyperion"
Swift 3
Same as Swift 2 with some syntax changes. I've also added the "authors" example, and I'm now using guard. Just for the sake of showing something different from the previous example.
func getBookInfo(isbn: String) {
guard let url = URL(string: "https://www.googleapis.com/books/v1/volumes?q=isbn:\(isbn)") else {
print("the url is not valid")
return
}
URLSession.shared().dataTask(with: url, completionHandler: {data, response, error -> Void in
guard error == nil else {
print(response)
print(error!.localizedDescription)
return
}
guard let data = data else {
print("no error but no data")
print(response)
return
}
guard let jsonResult = try? JSONSerialization.jsonObject(with: data, options: []) else {
print("the JSON is not valid")
return
}
if let arrayOfTitles = jsonResult.value(forKeyPath: "items.volumeInfo.title") as? [String] {
print(arrayOfTitles)
}
if let arrayOfAuthors = jsonResult.value(forKeyPath: "items.volumeInfo.authors") as? [[String]] {
print(arrayOfAuthors)
}
}).resume()
}
getBookInfo(isbn: "0553283685")
I'm attempting to test a server response using an API key taken from a .plist file. When I print out the key from the from the request header, it has an optional wrapper: Optional([App-Token: apikey1234567])). I'm not getting a response, which I think is because the key is being passed in this form. A little new to Swift. How can I pass this so it isn't optional? Relevant code below:
var key: String!
let baseURL: String = ("https://apiurl.com/").stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
override init() {
path = NSBundle.mainBundle().pathForResource("APIkey", ofType: "plist")
dict = NSDictionary(contentsOfFile: path!)
key = dict!.objectForKey("APIkey") as! String
super.init()
}
func updateJSON() {
var session = NSURLSession.sharedSession()
var request = NSMutableURLRequest(URL: NSURL(string: baseURL)!)
request.HTTPMethod = "GET"
request.setValue(key, forHTTPHeaderField:"App-Token")
// This prints out the 'Optional([App-Token: apikey1234567]))'
println("\(request.allHTTPHeaderFields))")
var dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
var error: NSError?
if (error != nil) {
println("\(error)")
} else {
self.jsonObject = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) as? NSDictionary
println("\(self.jsonObject)")
}
})
dataTask.resume()
}
UPDATE: I was getting nil because jsonObject was being cast as an NSDictionary. When I changed its type to AnyObject the response came back.
The functions valueForHTTPHeaderField and allHTTPHeaderFields - return optionals, it doesn't mean the key you put in is optional. from Swift NSURLRequest file:
func valueForHTTPHeaderField(field: String) -> String?
var allHTTPHeaderFields: [String : String]?
Check value of key by adding print after setting it in init:
var key: String!
let baseURL: String = ("https://apiurl.com/").stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
override init() {
path = NSBundle.mainBundle().pathForResource("APIkey", ofType: "plist")
dict = NSDictionary(contentsOfFile: path!)
key = dict!.objectForKey("APIkey") as! String
println("On init Key = \(key)") // Check key value here is it optional?
super.init()
}
Also: dataTaskWithRequest returns optional so at least optional chain:
dataTask?.resume()
You also have an new error:NSError created in completion of task when it already returns an error, it appears you mean to create this error for JSON parse? best to name it different to avoid any ambiguity. Some var can be let because never mutated -session, request, dataTask.
func updateJSON() {
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: baseURL)!)
request.HTTPMethod = "GET"
request.setValue(key, forHTTPHeaderField:"App-Token")
// This prints out the 'Optional([App-Token: apikey1234567]))'
println("\(request.allHTTPHeaderFields))")
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
println("\(error)")
} else {
var jsonError: NSError?
self.jsonObject = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: & jsonError) as? NSDictionary
println("\(self.jsonObject)")
}
})
dataTask?.resume()
}
(NB: I only have machine with xcode 7 and swift 2 installed at this moment, but i don't think any of these things have changed since Swift 1.2)
I am trying to return data from JSON object as a string but whenever I try it returns nil if someone could help please find the below code. I need to return currentWeather as a String with its value currently I am not able to return the data as a string only as an optional.
let urlPath = "http://api.openweathermap.org/data/2.5/weather?q=London,uk&units=metric"
let url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
println("Task completed")
if((error) != nil) {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
let jsonDictionary = jsonResult as NSDictionary
let mainDictionary = jsonResult.valueForKey("main") as NSDictionary
let currentWeather = mainDictionary.valueForKey("humidity") as? NSString
println(currentWeather)
})
task.resume()
I tried the code. The 'humidity' is an Int, not String. So you should use
let currentWeather = mainDictionary.valueForKey("humidity") as Int
I'm trying hard to learn IOS development.
I have followed this guide and successfully managed to create a working quiz game. The last couple of days I have been trying to connect the game to an external database. Finally after many hours I'm able to read from MYSQL using JSON parsing.
Right now Im struggling with a way to convert the json array into a normal array.
My current hardcoded questions look like this:
let questionOne = questionTemplate("the first question?", answerOne: "a answer", answerTwo: "a second answer", answerThree: "a third aswer", answerFour: "tast possible answer", correctAnswer: 2)
Then they are added to an array
spormslaArray = [questionOne, questionTwo, questionThree, questionFour, questionFive, questionSix,questionSeven]
Then im doing some more loading of answers and questions before i add them to the GUI based on an array counter from the first to the last question.
func questionTemplate(question:String, answerOne:String, answerTwo:String, answerThree:String, answerFour:String, correctAnswer:Int) -> NSArray {
//Set the question
var quizQuestion = question
//set the answers and the right answer
var firstAnswer = answerOne
var secondAnswer = answerTwo
var thirdAnswer = answerThree
var fourthAnswer = answerFour
var rightAnswer = correctAnswer
var gjennverendeSporsmal = 1
//Add all the questions and answers to an array
let questionAnswerArray = [question, firstAnswer, secondAnswer, thirdAnswer, fourthAnswer, rightAnswer]
return questionAnswerArray
}
I now want to add questions from my database into spormslaArray.I got questions loaded into xcode using this code:
func lasteJson(){
let urlPath = "http://universellutvikling.no/utvikling/json.php"
let url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
if error != nil {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if err != nil {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
let json = JSON(jsonResult)
let count: Int? = json["data"].array?.count
// println("found \(count!) challenges")
//Im just setting a hardcoded number, it will be based on the array when I have figured that out
var tall = 7
let ct = count
for index in 0...tall-1 {
println(json["data"][index] )
//DEtte printer ut induviduelt
/*
if let questionId = json["data"][index]["id"].string {
println(questionId)
}
if let spm1 = json["data"][index]["answerOne"].string {
println(spm1)
}
if let spm2 = json["data"][index]["answerTwo"].string {
println(spm2)
}
if let spm3 = json["data"][index]["answerThree"].string {
println(spm3)
}
if let spm4 = json["data"][index]["answerFour"].string {
println(spm4)
}
if let correctAnswer = json["data"][index]["correctAnswer"].string {
println(correctAnswer)
}
*/
}
//}
})
task.resume()
This is mostly based on this code.
If Im ignoring the fact that Im getting some breakpoints when im running the app, and that nordic characters in my database makes the ios simulator crash; This is the parsing result in the command line:
{
"correctAnswer" : "1",
"id" : "0",
"answerThree" : "aa3",
"answerFour" : "aa4",
"questionTemplate" : "sporsmal",
"answerOne" : "as1",
"answerTwo" : "aa2"
}
//////Finally here is the problem///////
I have tried for hours to make a variable from the json array, into the guestion array.
I want to do something like this:
let questionOne = json["data"][index]["answerOne"].string
and then add them to an array
let questionArray[questionOne, QuestionTwo.. etc]
I have tried for hours without any progress, so my last hope is you guys! :-)
Use this...
To post JSON or to receive JSON (Leave dictionary nil to GET)
///Use completion handler to handle recieved data
func sendJSON(params:Dictionary<String, String>?, toAdressOnServer:String, customCompletionHandler:((parsedData:AnyObject?, statusCode: Int) -> Void)?){
var request = NSMutableURLRequest(URL: NSURL(string: SERVER_NAME + toAdressOnServer)!)
var session = NSURLSession.sharedSession()
var err: NSError?
if (params == nil){
request.HTTPMethod = "GET"
}else{
request.HTTPMethod = "POST"
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params!, options: nil, error: &err)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
var err: NSError?
var json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments , error: &err)
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(err != nil) {
println(err!.localizedDescription)
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: '\(jsonStr)'")
customCompletionHandler?(parsedData: json, statusCode: -1)
}
else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON: AnyObject = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
// Use keyword "success" in JSON from server to register successful transmission
let success = parseJSON["success"] as? Int
if (success == nil){
customCompletionHandler?(parsedData: json, statusCode: -2)
}else{
customCompletionHandler?(parsedData: json, statusCode: success!)
}
}
else {
// The json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: \(jsonStr)")
customCompletionHandler?(parsedData: json, statusCode: -1)
}
}
})
task.resume()
}
And To decode the JSON in your case the array, but it can have any form.
self.sendJSON(nil, toAdressOnServer: "ADRESS", customCompletionHandler: { (parsedData, statusCode) -> Void in
//check for valid data
if (parsedData != nil){
//Loop through results
for (var x = 0; x < parsedData!.count; x++){
///primary key of the item from the internet
let pk:Int = (parsedData![x] as NSDictionary).objectForKey("pk") as Int
let month = ((parsedData![x] as NSDictionary).objectForKey("fields") as NSDictionary).objectForKey("month")! as String
let quote = ((parsedData![x] as NSDictionary).objectForKey("fields") as NSDictionary).objectForKey("quote")! as String
let quotee = ((parsedData![x] as NSDictionary).objectForKey("fields") as NSDictionary).objectForKey("quotee")! as String
})
This is an example, use parsed data as "json" and use it with the appropriate structure. In this case the JSON was An array of some dictionary with a fields dictionary that has another dictionary with more fields. So you can have any JSON structure.
I Hope this helps!
It seems that you almost have the answer there. I think what you are missing is questionArray.append(... in your loop to build your array. You could also make things easier for yourself if you modified your JSON so that the questions were in an array rather than discrete keys and change your questionTemplate to take an array rather than discrete answers.
Working with what you have however -
func lasteJson(){
let urlPath = "http://universellutvikling.no/utvikling/json.php"
let url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
questionsArray=[Question]()
let task = session.dataTaskWithURL(url, completionHandler: { (data, response, error) -> Void in
if error != nil {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
else {
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if err != nil {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
else {
let questions=jsonResult["data"] as? [[String:String]]
if (questions != nil) {
for question in questions! {
let answer1=question["answerOne"]!
let answer2=question["answerTwo"]!
let answer3=question["answerThree"]!
let answer4=question["answerFour"]!
let id=question["id"]!
let questionTemplate=question["questionTemplate"]!
let correctAnswer=question["correctAnswer"]!
let newQuestion=Question(questionTemplate, answerOne: answer1, answerTwo:answer2, answerThree: answer3, answerFour: answer4, correctAnswer: correctAnswer)
questionsArray.append(newQuestion)
}
}
}
}
})
task.resume()
}
You don't show your questionTemplate, but I am not sure why/how it returns an array. My code above assumes that there is a class Question and fills in a property questionsArray