2015-04-19 2 views
1

У меня есть makeRequest() метод внутри UITableViewController со следующим кодом:Как использовать swiftyJSON dictionaryValue как полезную строку для UILabel?

func makeRequest() { 

    Alamofire.request(.GET, self.foursquareEndpointURL, parameters: [ 
     //"VENUE_ID" : self.foursquareVenueID, 
      "client_id" : self.foursquareClientID, 
      "client_secret" : self.foursquareClientSecret, 
      "v" : "20140806" 
      ]) 
     .responseJSON(options: nil) { (_, _, data, error) -> Void in 
     if error != nil { 
      println(error?.localizedDescription) 
     } else if let data: AnyObject = data { 
      let jObj = JSON(data) 
      if let venue = jObj["response"]["venue"].dictionaryValue as [String: JSON]? { 
       self.responseitems = jObj 
       println("venue is: \(venue)") 
      } 
      dispatch_async(dispatch_get_main_queue()) { 
       self.tableView.reloadData() // Update UI 
      } 
     } 
    } 
} 

также иметь в виду, что у меня есть свойство var responseitems:JSON = []

println("venue is: \(venue)") печатает хорошо выглядящий ответа на консоль, так что я знаю, что это работает правильно ...

у меня также есть собственный UITableViewCell класс с bindData() методом со следующим кодом:

func bindData() { 
    println("VenueDetailHeaderCell data did set") 
    self.venueDetailTitleLabel.text = self.headerInfo?["name"].stringValue 
    let labelData = self.headerInfo?["name"].stringValue 
    println("labelData is: \(labelData)") 
} 

Как вы можете видеть, я пытаюсь установить текст UILabel в ["name"]. StringValue в ответе JSON. Однако, когда я println("labelData is: \(labelData)"), я получаю консольный вывод labelData: Необязательный (""), который, очевидно, пуст.

Вот скриншот того, что я пытаюсь захватить

enter image description here

Что я здесь делаю неправильно и как я могу захватить название места и назначить мой UILabel к нему?

UPDATE:

Я попытался следующий код

let labelData = self.headerInfo?["name"].error 
    println("labelData is: \(labelData)") 

И получить выход консольной: «Error Domain = SwiftyJSONErrorDomain Code = 901 "Array [0] провал, это не является массивом" UserInfo = 0x7fd6d9f7dc10 {NSLocalizedDescription = Ошибка массива [0], это не массив} «Если это кому-то полезно. Я действительно запутался здесь ... Любые идеи?

+0

Где вы устанавливаете значение 'self.headerInfo' в пользовательском' UITableViewCell'? Я предполагаю, что вы хотите, чтобы этот объект JMSON был «местом». Однако не кажется, что вы когда-либо делали это в любом из предоставленных образцов кода. – cnoon

+0

@cnoon Я делаю 'var headerInfo: JSON? { didSet { self.bindData() } } ' –

ответ

4

Проблема заключается в том, что значение headerInfo ошибка JSON объект, потому что вы пытаетесь получить доступ словарь с целочисленным индексом.

Обратите внимание, что var responseitems:JSON = [] не создает объект массива. SwiftyJSON имеет автоматические назначения-конструктор (я новичок в быстр, так что не уверен, что правильно скора терминологии) ... посмотреть Инициализатор в исходном коде SwiftyJSON.swift:

extension JSON: ArrayLiteralConvertible { 
    public init(arrayLiteral elements: AnyObject...) { 
     self.init(elements) 
    } 
} 

Что это означает что когда вы делаете var responseitems:JSON = [], вы не создаете массив, вы создаете объект JSON, который построен с пустым массивом, используя метод выше init. Затем, когда вы делаете self.responseitems = jObj, вы переписываете переменную responseitems в объект JSON со словарем в нем. Поэтому self.responseitems[0] недействителен.

Также обратите внимание, что с SwiftyJSON нет такой вещи, как необязательный объект JSON. Я замечаю в вашем комментарии, что вы говорите, что вы делаете var headerInfo:JSON? ... - не возможно иметь опционный JSON.

var headerInfo: JSON = nil 

выше возможно - это использует другой автоматический Инициализатор, что инициализирует действующий JSON объект, представляющий нулевое значение в формате JSON.

Итак, как исправить это?

При назначении headerInfo сделать это следующим образом:

let headerInfo = self.responseitems["response"]["venue"] 

И теперь bindData вы можете сделать:

self.venueDetailTitleLabel.text = self.headerInfo["name"].stringValue 

Обратите внимание, что все вышеперечисленное предполагает Swift 1.2 и SwiftyJSON> = 2,2 - также после того, как вы поняли вышеизложенное и исправили проблему, вам, вероятно, захочется немного обработать код, чтобы отразить исправленное понимание модели данных.

+0

Это сработало! Спасибо. Тем не менее, я не получаю ошибок для 'var headerInfo: JSON?'. Означает ли это, что на самом деле возможно, что это необязательно? Я положил? там как проверка, чтобы предотвратить ее сбой, если она вернула нуль. Кроме того, что бы вы порекомендовали в отношении рефакторинга кода, чтобы отразить исправленное понимание модели данных? Еще раз спасибо –

+0

Это не ошибка или проблема, чтобы сделать 'headerInfo: JSON?', Но я хочу сказать, что даже если это необязательно, вы никогда не получите значение nil, всегда действующее JSON-объект. Тем не менее, вы все равно можете проверить, есть ли 'headerInfo == nil', но обратите внимание, что это не делает то, что вы думаете, что оно делает. Он создает действительный объект JSON, инициализированный с помощью nil (внутренне сохраненный как NSNull) в правой части, и затем сравнивает его с вашим 'headerInfo' с левой стороны. Установите контрольную точку и перейдите в код, чтобы узнать, что произойдет. Число рейнольдса рефакторинг - не беспокойтесь об этом, это будет просто быть придирчивым. – jhabbott

+0

А я вижу! В этом есть смысл. Огромное спасибо –

0

Путь разобрать это следующий

element: JSONValue //Something with JSONValue 
if let title = element["name"]?.string { 
    cell.title.text = title 
} 
+0

Извините, я должен был указать, что' var responseitems: JSON = [] 'Итак, я уже делаю то, что вы предлагаете, не повезло. –

+0

Я также делаю 'var headerInfo: JSON? { didSet { self.bindData() } } 'в VenueDetailHeaderCell, который является классом UITableView –