2016-01-29 2 views
7

файлы проекта:

https://jumpshare.com/v/Otai3BBXYwfvyz8jb53kДинамически Генерировать UITableView Клетки и Headrs

(Было бы целесообразно, чтобы просмотреть их, чтобы увидеть структуру проекта)

Проблема:

Ok, поэтому я после tutorial, который создает UITableView с заголовками, а затем содержимое ячейки.

Код работал и работает нормально. Теперь я хочу выйти за рамки этого учебника и динамически загружать этот контент с помощью alamofire и SwiftyJSON.

В учебнике, используемый код следующим образом:

func getSectionsFromData() -> [Sections] { 

    var sectionsArray = [Sections]() 

    let animals = Sections(title: "Animals", objects: ["Cats", "Dogs", "Birds", "Lions"]) 


    sectionsArray.append(animals) 

    return sectionsArray 


} 

То, что я пытался сделать, это:

Alamofire.request(.GET, url).validate().responseJSON { response in 
     switch response.result { 
     case .Success: 
      if let value = response.result.value { 
       let json = JSON(value) 

       for (_, subJson) in json { 
        for (year, content) in subJson { 
         let title = year 
         let objects = content 

         sectionsArray.append(Sections(title: title, objects: objects)) 

        } 

       } 
      } 
     case .Failure(let error): 
      print(error) 
     } 
    } 

Если я распечатать результаты, которые они показывают в консоли - так что я узнайте, как работает и работает JSON. Затем я добавил в

let title = year 
let objects = content 

sectionsArray.append(Sections(title: title, objects: objects)) 

Но на этой линии:

sectionsArray.append(Sections(title: title, objects: objects))

Я получаю эту ошибку:

cannot convert value of type 'JSON' to expected argument type '[String]'

Вот является JSON Я использую:

{"posts": [ 
{ 
    "Category1": [ 
     "Post1cat1" 
    ], 
    "Category2": [ 
     "Post1cat2", 
     "Post2cat2" 
    ] 
} 
]} 

Кто-нибудь может мне помочь? Я мог бы пойти не в том направлении Я хочу пропустить JSON и отобразить категории как заголовки и сообщения в ячейке таблицы.

редактировать: 1/29/2016

так, я изменил цикл на:

for (_, subJson) in json { 
       for (index, data) in subJson { 
        for (title, objects) in data { 
         sectionsArray.append(Sections(title: title, objects: objects.self.arrayValue.map { $0.string!})) 


        } 

       } 

      } 

Все еще не повезло. Когда я добавляю в некоторых печатных изданиях (в соответствии с: sectionsArray.append), чтобы проверить, есть ли данные:

print("--") 
print(title) 
print(objects.self.arrayValue.map { $0.string!}) 
print(Sections(title: title, objects: objects.self.arrayValue.map { $0.string!})) 

Я получаю этот результат в консоли:

--

Category1

["Post1cat1"]

Sections(headings: "Category1", items: ["Post1cat1"])

--

Category2

["Post1cat2", "Post2cat2"]

Sections(headings: "Category2", items: ["Post1cat2", "Post2cat2"])

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

ответ

3

Во втором методе синтаксического анализа (после редактирования), вы итерация на массив в последнем цикле, так как вы можете создать массив там и добавить каждый элемент по отдельности, как в примере:

for (title, data) in subJson { 
    var elements: [String] = [] 

    for (_, object) in data { 
     if let stringELement = object.rawString() { 
      elements.append(stringELement) 
     } 
    } 

    sectionsArray.append(Sections(title: title, objects: elements)) 
} 

или если вы предпочитаете вы можете использовать с приведением необработанный массив из объекта JSON, как в этом примере:

for (_, subJson) in json["posts"] { 
    for (title, data) in subJson { 
     let optionalCastedObjects = data.arrayObject as? [String] 
     let unwrappedObjects = optionalCastedObjects ?? [] 
     let section = Sections(title: title, objects: unwrappedObjects) 

     sectionsArray.append(section)       
    } 
} 

Это должно исправить упомянутый компиляция вопрос.

Но в конце помните, что вы используете асинхронный обратный вызов (в вашем GET request) синхронным способом getSectionsFromData. И вы всегда будете возвращать массив до того, как значения из этого обратного вызова (clojure) будут добавлять новые данные. Это приведет к тому, что вы никогда не будете отображать данные, которые вы выбрали именно так.

UPDATE

Чтобы сделать это, вы должны реорганизовать метод getSectionsFromData, как показано ниже.

func getSectionsFromData(completion: ([Sections]) ->()) { 
    var sectionsArray = [Sections]() 

    Alamofire.request(.GET, url).validate().responseJSON { response in 
     switch response.result { 
     case .Success: 
      if let value = response.result.value { 
       let json = JSON(value) 

       for (_, subJson) in json["posts"] { 
        for (title, data) in subJson { 
         let optionalCastedObjects = data.arrayObject as? [String] 
         let unwrappedObjects = optionalCastedObjects ?? [] 
         let section = Sections(title: title, objects: unwrappedObjects) 

         sectionsArray.append(section) 
        } 
       } 

       completion(sectionsArray) 
      } 
     case .Failure(let error): 
      print(error) 
     } 
    } 
} 

И соответствующие части в вашем классе UITableViewController.

var sections: [Sections] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 

    SectionsData().getSectionsFromData { [weak self](sections: [Sections]) ->() in 
     self?.sections = sections 
     self?.tableView.reloadData() 
    } 
} 
+0

Проблема была не в синтаксическом разборе, это работало нормально. проблема заключалась в том, чтобы отобразить их в таблице. это не обновление. – MarkP

+0

Пожалуйста, попробуйте также часть после заголовка UPDATE.'Работает для меня' :) –

-1

Из документации SwiftyJSON:

for (key,subJson):(String, JSON) in json { 
    //Do something you want 
} 

Это указывает на то, что subJson имеет тип JSON.Тем не менее, ваш конструктор разделов в первом примере:

Sections(title: "Animals", objects: ["Cats", "Dogs", "Birds", "Lions"]) 

В вашем втором примере, вы вызываете его как:

Sections(title: title, objects: objects) 

Если вы не изменили конструктор, он ожидает objects быть массив строк, а не JSON. Вот почему вы получаете сообщение об ошибке: Swift не может преобразовать JSON в String. В вашем случае objects JSON на самом деле массив строк, поэтому нужно использовать что-то вроде:

Sections(title: title, objects: objects.arrayValue.map { $0.string!}) 
+0

Су Я пробовал: sectionsArray.append (разделы (название: название, объекты: objects.arrayValue.map {$ 0.string!})) И побежал тренажер - все, что было показано с помощью животных, клетки не какой-либо из новых элементов, ошибок нет – MarkP

+0

Я добавил файлы проекта, если это помогает. – MarkP

+0

Я на работе, и этот сайт заблокирован. Я посмотрю, когда вернусь домой. Использовали ли вы отладчик, чтобы выполнить код и посмотреть, как часто вызывается приложение? – Michael

1

Ваш второй цикл на объект массива, следовательно, в этом цикле year является значение индекса и content является объектом при этом индексе.

Вам необходимо осуществить дополнительный цикл, чтобы решить эту проблему, а именно:

for (_, subJson) in json { 
    for (index, data) in subJson { 
     for (title, objects) in data { 
      sectionsArray.append(Sections(title: title, objects: objects.arrayValue.map { $0.string!})) 

     } 

    } 

} 
+0

Итак, я добавил, что ничего не происходит. Из всех петель, когда я печатаю (разделыArray), я получаю: [разделы. Разделы (рубрики: «Животные», пункты: [«Кошки», «Собаки», «Птицы», «Львы»])] нет новых товаров – MarkP

+0

Вы работали над файлами проекта? не могли бы вы положить файл для скачивания? – MarkP

+0

Кроме того, когда я изменяю ваши section.array (...) на базовый: sectionsArray.append (разделы (название: «test», objects: [«one», «two»])) с жестко закодированными значениями, он также не работает. : S – MarkP

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