2016-01-29 8 views
7

file di progetto:

https://jumpshare.com/v/Otai3BBXYwfvyz8jb53kdinamicamente generare cellule UITableView e Headrs

(sarebbe saggio per vedere questi per vedere la struttura del progetto)

Problema:

Ok, quindi io sono dopo un tutorial che crea un UITableView con intestazioni e quindi contenuto di celle.

Il codice ha funzionato e funziona bene, ora voglio estendere oltre questo tutorial e caricare dinamicamente quel contenuto usando alamofire e SwiftyJSON.

Nel tutorial, il codice utilizzato è in questo modo:

func getSectionsFromData() -> [Sections] { 

    var sectionsArray = [Sections]() 

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


    sectionsArray.append(animals) 

    return sectionsArray 


} 

Quello che ho cercato di fare è stato:

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

Se stampare i risultati che mostrano nella console - così ho sapere come funziona il looping del JSON. Ho poi aggiunto a

let title = year 
let objects = content 

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

Ma su questa linea:

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

ottengo questo errore:

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

Ecco il JSON che sto usando:

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

Qualcuno può aiutarmi? Qui potrei andare nella direzione sbagliata. Voglio passare in rassegna il JSON e visualizzare le categorie come intestazioni e i post in una cella di un tavolo.

edit: 1/29/2016

così, ho cambiato il loop:

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


        } 

       } 

      } 

Ancora nessuna fortuna. Quando aggiungo in alcune stampe (sotto: sectionsArray.append) per verificare se ci sono dati:

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

ottengo questo risultato nella console:

--

Category1

["Post1cat1"]

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

--

Category2

["Post1cat2", "Post2cat2"]

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

che dimostra che le informazioni sono lì, tuttavia quando eseguo l'app non ci sono ancora risultati, ma JSON ha solo la sezione e le celle originariamente definite sopra.

risposta

3

Nel secondo metodo di analisi (dopo modifica), si sta iterazione su array in ultimo ciclo, quindi o è possibile creare array di là e aggiungere ogni elemento separatamente, come nell'esempio:

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

o se si preferisce si può utilizzare colato matrice grezza dalla oggetto JSON come in questo esempio:

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

Questo dovrebbe risolvere il problema di compilazione menzionato.

Ma alla fine ricorda che stai utilizzando la funzione di richiamo asincrono (nel tuo GET request) nel metodo sincrono getSectionsFromData. E tu restituirai sempre l'array prima che i valori di tale callback (clojure) aggiungano nuovi dati. Ciò causerà che non visualizzi mai i dati che hai recuperato in quel modo.

UPDATE

Per fare che si dovrebbe refactoring il metodo getSectionsFromData come di seguito.

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

E parti pertinenti nella classe UITableViewController.

var sections: [Sections] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 

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

Il problema non era con l'analisi, funzionava bene. il problema era farli visualizzare in lui tableview. non si sta aggiornando. – MarkP

+0

Si prega di provare anche la parte dopo il titolo UPDATE.'Funziona per me' :) –

-1

Dalla documentazione SwiftyJSON:

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

Questo indica che subJson è di tipo JSON.Tuttavia, il vostro Sezioni costruttore nel primo esempio è:

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

Nel vostro secondo esempio, si sta chiamando come:

Sections(title: title, objects: objects) 

A meno che non si è modificato il costruttore, si aspetta objects di essere un array di stringhe, non JSON. Questo è il motivo per cui ricevi un errore che dice che Swift non può convertire JSON in String. Nel tuo caso, il objects JSON è in realtà un array di stringhe, quindi è necessario usare qualcosa come:

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

soo ho provato: sectionsArray.append (Sezioni (titolo: titolo, oggetti: objects.arrayValue.map {$ 0.string!})) E corse il simulatore - tutto quello che ha mostrato era le cellule animali non uno qualsiasi dei i nuovi elementi, non ci sono errori – MarkP

+0

Ho aggiunto i file di progetto se questo aiuta. – MarkP

+0

Sono al lavoro e quel sito è bloccato. Daro un'occhiata quando torno a casa. Hai usato il debugger per scorrere il codice e vedere quante volte viene chiamata l'append? – Michael

1

Il secondo ciclo è sul oggetto array, quindi, in quel ciclo year è il valore dell'indice e content è l'oggetto a quell'indice

è necessario implementare un ciclo aggiuntivo per risolvere il problema e cioè:

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

Quindi, l'ho aggiunto. Non succede nulla. Di tutti i loop quando stampo (sezioniArray) ottengo: [sezioni. Sezioni (titoli: "Animali", voci: ["Gatti", "Cani", "Uccelli", "Leoni"])] non nuovi articoli – MarkP

+0

Hai lavorato sui file di progetto? potresti mettere il file per il download? – MarkP

+0

Inoltre, quando cambio il tuo section.array (...) in uno di base: sectionsArray.append (Sections (titolo: "test", objects: ["one", "two"])) con valori hard coded, anche questo non funziona. : S – MarkP

Problemi correlati