2016-01-29 23 views
7

pliki projektu:

https://jumpshare.com/v/Otai3BBXYwfvyz8jb53kdynamicznego generowania Komórki UITableView i Headrs

(byłoby mądre, aby zobaczyć je zobaczyć strukturę projektu)

Problem:

Ok, więc jestem po tutorial, który tworzy UITableView z nagłówkami, a następnie zawartość komórki.

Kod zadziałał i działa poprawnie, Teraz chcę wykroczyć poza samouczek i dynamicznie wczytać tę zawartość za pomocą alamofire i SwiftyJSON.

W samouczku kod używany jest tak:

func getSectionsFromData() -> [Sections] { 

    var sectionsArray = [Sections]() 

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


    sectionsArray.append(animals) 

    return sectionsArray 


} 

Co próbowałem zrobić to:

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) 
     } 
    } 

Gdybym wydrukować wyniki pokazują one w konsoli - tak ja znać otrzymywanie i zapętlanie prac JSON. Następnie dodaje się

let title = year 
let objects = content 

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

Ale na tej linii:

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

otrzymuję ten błąd:

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

Oto JSON Używam:

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

Czy ktoś może mi pomóc? Być może podążę w niewłaściwym kierunku. Chcę przejść przez JSON i wyświetlić kategorie jako nagłówki i posty w komórce tabeli.

edit: 1/29/2016

więc zmieniłem pętlę do:

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!})) 


        } 

       } 

      } 

nadal nie ma szczęścia. Kiedy dodać w niektórych odbitek (under: sectionsArray.append), aby sprawdzić, czy istnieją dane:

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

uzyskać ten wynik w konsoli:

--

Category1

["Post1cat1"]

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

--

Category2

["Post1cat2", "Post2cat2"]

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

który pokazuje, że informacja jest tam, Jednak gdy uruchomię aplikację, nadal nie ma wyników z JSON tylko pierwotnie zdefiniowana sekcja i komórki powyżej.

Odpowiedz

3

W drugiej metodzie analizy składniowej (po edycji), jesteś iteracji na tablicy w ostatniej pętli, więc albo można utworzyć tam tablicę i dodać każdy element osobno, tak jak w przykładzie:

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)) 
} 

lub jeśli wolisz, możesz użyć lanego surowego tablicę z obiektu JSON jak w poniższym przykładzie:

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)       
    } 
} 

To powinno naprawić wspomniany problem z kompilacją.

Ale na koniec pamiętaj, że używasz asynchronicznego wywołania zwrotnego (w swoim GET request) w metodzie synchronicznej getSectionsFromData. A ty zawsze zwróci tablicę, zanim wartości z tego wywołania zwrotnego (clojure) dodadzą nowe dane. To spowoduje, że nigdy nie wyświetlisz danych, które pobrałeś w ten sposób.

UPDATE

Aby to zrobić należy byłaby metodę getSectionsFromData jak poniżej.

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) 
     } 
    } 
} 

i istotne części w swojej klasie UITableViewController.

var sections: [Sections] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 

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

Problem z parsowaniem nie zadziałał. problem polegał na tym, że musieli je wyświetlić w tabeli. to nie jest aktualizacja. – MarkP

+0

Spróbuj również część po nagłówku UPDATE.'Pracuje dla mnie' :) –

-1

Z dokumentacji SwiftyJSON:

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

Oznacza to, że subJson jest typu JSON.Jednak twój konstruktor sekcje w pierwszym przykładzie jest:

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

W drugim przykładzie, jesteś nazywając ją jako:

Sections(title: title, objects: objects) 

Jeśli nie zmieniły konstruktora, to spodziewa objects być tablica łańcuchów, a nie JSON. Właśnie dlatego pojawia się błąd informujący, że Swift nie może przekonwertować JSON na ciąg. W twoim przypadku, objects JSON jest faktycznie tablicę ciągów, więc trzeba użyć czegoś takiego:

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

soo Próbowałem: sectionsArray.append (sekcje (tytuł: tytuł, obiekty: objects.arrayValue.map {$ 0.string!})) I prowadził symulator - wszystko, co pokazał nie było komórki zwierzęta dowolnego nowe elementy, nie ma błędów – MarkP

+0

Dodałem pliki projektu, jeśli to pomaga. – MarkP

+0

Jestem w pracy i ta strona jest zablokowana. Przyjrzę się, kiedy wrócę do domu. Czy użyłeś debuggera, aby przejrzeć kod i zobaczyć, jak często jest wywoływany plik append? – Michael

1

Twoja druga pętla jest na obiekt array stąd w tej pętli year jest wartość indeksu i content jest przedmiotem w tym indeksie.

Trzeba wdrożyć dodatkową pętlę naprawić IE problem:

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

Więc dodałem to. Nic się nie dzieje. Spośród wszystkich pętli podczas drukowania (sectionsArray) otrzymuję: [sections.Sections (nagłówki: "Animals", items: ["Cats", "Dogs", "Birds", "Lions"])] brak nowych przedmiotów – MarkP

+0

Czy pracujesz nad plikami projektu? czy możesz umieścić plik do pobrania? – MarkP

+0

Ponadto, gdy zmienię twoją sekcje.array (...) na podstawową: sectionsArray.append (sekcje (tytuł: "test", obiekty: ["jeden", "dwa"])) z zakodowanymi wartościami, to również nie działa. : S – MarkP