如何向 URL 中插入一个值以向 YQL 发出请求
How to insert a value into a URL to make a request to YQL
当我尝试向 YQL 请求股票数据时,我 运行 遇到了问题,而要查找的代码 (newCompanyStockSymbol
) 是用户输入的。我在这个函数中获取股票:
func handleSave() {
// Fetch stock price from symbol provided by user for new company
guard let newCompanyStockSymbol = stockTextField.text else {
print("error getting text from field")
return
}
var newCompanyStockPrice = ""
let url = URL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20symbol%2C%20Ask%2C%20YearHigh%2C%20YearLow%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22\(newCompanyStockSymbol)%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
} else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
let json = JSON(data: data!)
if let quotes = json["query"]["results"]["quote"].array {
for quote in quotes {
let ask = quote["Ask"].stringValue
newCompanyStockPrice = ask
}
}
print("new company json: \(json)")
}
guard let newCompanyName = self.nameTextField.text else {
print("error getting text from field")
return
}
guard let newCompanyLogo = self.logoTextField.text else {
print("error getting text from field")
return
}
print("2: The new commpany stock price is: \(newCompanyStockPrice)")
// Call save function in view controller to save new company to core data
self.viewController?.save(name: newCompanyName, logo: newCompanyLogo, stockPrice: newCompanyStockPrice)
self.viewController?.tableView.reloadData()
}
task.resume()
// Present reloaded view controller with new company added
let cc = UINavigationController()
let companyController = CompanyController()
viewController = companyController
cc.viewControllers = [companyController]
present(cc, animated: true, completion: nil)
}
并且我使用字符串插值将\(newCompanyStockSymbol)
插入到请求URL中的适当位置。但是我在那条线上遇到了崩溃和错误,因为它返回了 nil,我预计是因为它在其中逐字使用 URL 和 \(newCompanyStockSymbol)
,而不是实际插入值。
还有其他方法吗?
编辑
以及从上面的 handleSave()
调用的视图控制器中的 save
函数(如果有帮助的话):
func save(name: String, logo: String, stockPrice: String) {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
let entity =
NSEntityDescription.entity(forEntityName: "Company",
in: managedContext)!
let company = NSManagedObject(entity: entity,
insertInto: managedContext)
company.setValue(stockPrice, forKey: "stockPrice")
company.setValue(name, forKey: "name")
company.setValue(logo, forKey: "logo")
do {
try managedContext.save()
companies.append(company)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
tableView.reloadData()
}
假设您在 stockTextField 中输入 AAPL,只需使用:
let newCompanyStockSymbol = stockTextField.text
导致 newCompanyStockSymbol 为:
Optional("AAPL")
这不是您想要的 URL 字符串。关键部分最终是这样的:
(%22Optional("AAPL")%22)
而是使用 guard 从文本字段中获取值:
guard let newCompanyStockSymbol = stockTextField.text else {
// handle the error how you see fit
print("error getting text from field")
return
}
现在你的 URL 应该被正确解析了。
--- 附加信息 ---
我不完全确定这里 'continued conversation' 的规则,但希望编辑它是可以接受的...无论如何...
确保您遵循以下流程:
func handleSave() {
let newCompanyName = nameTextField.text
let newCompanyStockSymbol = stockTextField.text
let newCompanyLogo = logoTextField.text
var newCompanyStockPrice = ""
// Fetch stock price from symbol provided by user for new company
let url = URL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20symbol%2C%20Ask%2C%20YearHigh%2C%20YearLow%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22\(newCompanyStockSymbol)%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
} else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
let json = JSON(data: data!)
if let quotes = json["query"]["results"]["quote"].array {
for quote in quotes {
let ask = quote["Ask"].stringValue
newCompanyStockPrice = ask
// task completed, we've parsed the return data,
// so NOW we can finish the save process and
// update the UI
viewController?.save(name: newCompanyName!, logo: newCompanyLogo!, stockPrice: newCompanyStockPrice)
}
}
}
}
task.resume()
}
我没有测试这个,所以它可能需要调整,你的 .save() 函数可能需要强制到主线程(因为它正在做 UI 更新)。但也许这样更清楚一些。
当我尝试向 YQL 请求股票数据时,我 运行 遇到了问题,而要查找的代码 (newCompanyStockSymbol
) 是用户输入的。我在这个函数中获取股票:
func handleSave() {
// Fetch stock price from symbol provided by user for new company
guard let newCompanyStockSymbol = stockTextField.text else {
print("error getting text from field")
return
}
var newCompanyStockPrice = ""
let url = URL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20symbol%2C%20Ask%2C%20YearHigh%2C%20YearLow%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22\(newCompanyStockSymbol)%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
} else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
let json = JSON(data: data!)
if let quotes = json["query"]["results"]["quote"].array {
for quote in quotes {
let ask = quote["Ask"].stringValue
newCompanyStockPrice = ask
}
}
print("new company json: \(json)")
}
guard let newCompanyName = self.nameTextField.text else {
print("error getting text from field")
return
}
guard let newCompanyLogo = self.logoTextField.text else {
print("error getting text from field")
return
}
print("2: The new commpany stock price is: \(newCompanyStockPrice)")
// Call save function in view controller to save new company to core data
self.viewController?.save(name: newCompanyName, logo: newCompanyLogo, stockPrice: newCompanyStockPrice)
self.viewController?.tableView.reloadData()
}
task.resume()
// Present reloaded view controller with new company added
let cc = UINavigationController()
let companyController = CompanyController()
viewController = companyController
cc.viewControllers = [companyController]
present(cc, animated: true, completion: nil)
}
并且我使用字符串插值将\(newCompanyStockSymbol)
插入到请求URL中的适当位置。但是我在那条线上遇到了崩溃和错误,因为它返回了 nil,我预计是因为它在其中逐字使用 URL 和 \(newCompanyStockSymbol)
,而不是实际插入值。
还有其他方法吗?
编辑
以及从上面的 handleSave()
调用的视图控制器中的 save
函数(如果有帮助的话):
func save(name: String, logo: String, stockPrice: String) {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
let entity =
NSEntityDescription.entity(forEntityName: "Company",
in: managedContext)!
let company = NSManagedObject(entity: entity,
insertInto: managedContext)
company.setValue(stockPrice, forKey: "stockPrice")
company.setValue(name, forKey: "name")
company.setValue(logo, forKey: "logo")
do {
try managedContext.save()
companies.append(company)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
tableView.reloadData()
}
假设您在 stockTextField 中输入 AAPL,只需使用:
let newCompanyStockSymbol = stockTextField.text
导致 newCompanyStockSymbol 为:
Optional("AAPL")
这不是您想要的 URL 字符串。关键部分最终是这样的:
(%22Optional("AAPL")%22)
而是使用 guard 从文本字段中获取值:
guard let newCompanyStockSymbol = stockTextField.text else {
// handle the error how you see fit
print("error getting text from field")
return
}
现在你的 URL 应该被正确解析了。
--- 附加信息 ---
我不完全确定这里 'continued conversation' 的规则,但希望编辑它是可以接受的...无论如何...
确保您遵循以下流程:
func handleSave() {
let newCompanyName = nameTextField.text
let newCompanyStockSymbol = stockTextField.text
let newCompanyLogo = logoTextField.text
var newCompanyStockPrice = ""
// Fetch stock price from symbol provided by user for new company
let url = URL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20symbol%2C%20Ask%2C%20YearHigh%2C%20YearLow%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22\(newCompanyStockSymbol)%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
} else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
let json = JSON(data: data!)
if let quotes = json["query"]["results"]["quote"].array {
for quote in quotes {
let ask = quote["Ask"].stringValue
newCompanyStockPrice = ask
// task completed, we've parsed the return data,
// so NOW we can finish the save process and
// update the UI
viewController?.save(name: newCompanyName!, logo: newCompanyLogo!, stockPrice: newCompanyStockPrice)
}
}
}
}
task.resume()
}
我没有测试这个,所以它可能需要调整,你的 .save() 函数可能需要强制到主线程(因为它正在做 UI 更新)。但也许这样更清楚一些。