2017-02-10 4 views
0

У меня возникает проблема, когда я пытаюсь сделать запрос к YQL для данных запаса, когда символ (newCompanyStockSymbol) для поиска вводится пользователем , Принести запасы в этой функции:Как вставить значение в URL-адрес, чтобы сделать запрос к YQL

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 в соответствующем месте. Однако я получаю сообщение об ошибке и ошибке в этой строке, потому что он возвращает нуль, я ожидаю, потому что он использует URL-адрес с \(newCompanyStockSymbol) там дословно, вместо фактического ввода значения.

Есть ли другой способ сделать это?

EDIT

enter image description here

И save функция зрения контроллера, который вызывается из handleSave() выше, если это полезно:

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() 
} 
+1

Какая ошибка? – Callam

+0

@Callam неожиданно обнаружил нуль при развертывании необязательного значения – d0xi45

+0

, выделив строку 'let url'. И в моей консоли это показывает, что 'newCompanyStockPrice' по-прежнему является пустой строкой, хотя я пытался установить' ask' этой переменной – d0xi45

ответ

1

Предположив вы вошли AAPL в вашем stockTextField, используя просто:

let newCompanyStockSymbol = stockTextField.text 

приводит к newCompanyStockSymbol существа:

Optional("AAPL") 

, который не то, что вы хотите в строке URL. Критическая секция заканчивается так:

(%22Optional("AAPL")%22) 

Вместо этого используйте охранник, чтобы получить значение из текстового поля:

guard let newCompanyStockSymbol = stockTextField.text else { 
     // handle the error how you see fit 
     print("error getting text from field") 
     return 
    } 

Теперь ваш URL должен быть разобран правильно.

--- Дополнительная информация ---

Я не совсем уверен, что правила на «продолжение разговора» здесь, но мы надеемся, редактируя это будет приемлемо ... все равно ...

Убедитесь, что вы после этого потока:

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() функция может потребоваться принудительно на основной поток (так как это делает Обновления пользовательского интерфейса). Но, может быть, это немного более ясно.

+0

О, это объяснило бы это! Спасибо, сейчас я не получаю крушение. Однако, когда я устанавливаю точку останова на строку, где я сохраняю выбранную цену акций ('viewController? .save (name: newCompanyName !, logo: newCompanyLogo !, stockPrice: newCompanyStockPrice)'), я вижу, что newCompanyStockPrice по-прежнему является пустой строкой, поэтому я не думаю, что данные получаются правильно. Я добавил скриншот консоли на свой пост. – d0xi45

+0

'URLSession.shared.dataTask (with: url)' - задача async - она ​​запускается, когда вы вызываете 'task.resume()', но затем выполнение немедленно переходит к вашей функции сохранения, где вы передаете неизмененную переменную newCompanyStockPrice.Вы хотите вызвать функцию сохранения из вашего обработчика завершения ** после ** обработки HTTPURLResponse и установки newCompanyStockPrice. – DonMag

+0

Перемещение функции сохранения внутри обработчика завершения непосредственно перед 'task.resume()' (внутри закрывающей скобки обработчика завершения, после закрывающей скобки 'else if let ', по-прежнему не работает. Я также попытался разместить его повсюду между ними, и новая компания все еще не установлена ​​/ появляется на моем столе. Я могу задать другой вопрос, если вы чувствуете, что знаете ответ, это довольно неприятно! Я чувствую, что до сих пор так близко. Теперь у новойCompanyStockPrice есть значение, но я думаю, что оно не сохраняется правильно, потому что оно не отображается в моем представлении таблицы. – d0xi45

 Смежные вопросы

  • Нет связанных вопросов^_^