2014-08-15 12 views
7

Mentre le stringhe sembrano andare bene, sto avendo qualche problema a memorizzare i numeri interi nei dati principali. Seguire i tutorial e leggere le informazioni disponibili là fuori non sembra aiutarmi chi non ha background di Objective-C. (Swift sembrava un linguaggio semplice come le lingue che conosco bene con PHP/OOPHP/JavaScript/VBScript/... quindi ho iniziato a giocare con esso e finora sono stato in grado di fare tutto ciò che volevo, quasi)Memorizza numeri interi nei dati principali usando Swift e XCode

Quello che voglio fare ora è, per ricevere i dati JSON e conservarla in core Data

Ecco il mio dati Nucleo

Entity name: Category 

suoi attributi:

id Int16 
title String 
description String 

mio Modello Swift? file: Category.swift

import CoreData 

class Category: NSManagedObject { 
    @NSManaged var id: Int //should I declare this as Int16? 
    @NSManaged var title: String 
    @NSManaged var description: String 
} 

Sto usando l'estensione SwiftyJASON? e il protocollo NSURLSession? per ottenere i dati e per analizzare come segue:

import UIKit 
import CoreData 

class ViewController: UIViewController { 

    let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     fetchData() 
    } 
     func fetchData() { 
      var url = NSURL.URLWithString("http://domain.com/index.php?r=appsync/read&id=category") 
      var session = NSURLSession.sharedSession() 
      session.dataTaskWithURL(url, completionHandler: {(data, response, error) in 
       // parse data into json 
       let json = JSONValue(data) 
       let entityDescription = NSEntityDescription.entityForName("Category", inManagedObjectContext: self.managedObjectContext) 
       let category = Category(entity: entityDescription, insertIntoManagedObjectContext: self.managedObjectContext) 
       for item in json.array! { 
        category.id = item["id"].string!.toInt()! //goes KABOOM! 
        category.title = item["title"].string! 
        category.description = item["description"].string! 
        managedObjectContext?.save(nil) 
       } 
       dispatch_async(dispatch_get_main_queue()) { 
        // do something 
       } 
      }).resume() 
     } 
} 

Supponiamo i dati JASON è:

[{"id":"1","title":"cat1","description":"blabala one"},{"id":"2","title":"cat2","description":"blabala two"}] 

In linea di cui si dice category.id = item["id"].string!.toInt()! xCode va Kaboom, che cosa sto facendo male qui?

Note/Altre domande:

  • Ho provato a cambiare tipo id all'interno di Core Data di Int32 e poi dichiarando come proprio Int nel modello (e non Int16 o Int32) che ha ridotto alcuni errori ma xCode blocca ancora

  • Probabilmente il modo in cui sto loop roba non è il modo migliore per farlo, qual è il modo migliore di memorizzare array di dati in dati di base a volta?

  • La maggior parte delle esercitazioni che ho visto non ci sono ID per Entità (tabelle), mi manca qualcosa qui?

Riferimenti:

EDIT> Lavorare codice:

Category.s file di modello wift che può essere generato automaticamente utilizzando File> Nuovo> File> iOS> Core Data> NSManagedObject sottoclasse [rapida, senza bisogno di colmare colpo di testa, ma è necessario aggiungere manualmente la linea @objc come qui di seguito]

import CoreData 

@objc(Category) //Wouldn't work without this 
class Category: NSManagedObject { 
    @NSManaged var id: NSNumber //has to be NSNumber 
    @NSManaged var title: String 
    @NSManaged var mydescription: String //"description" is reserved so is "class" 
} 

ViewController .swift

import UIKit 
import CoreData 

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     fetchData() 
    } 
    func fetchData() { 
     var url = NSURL.URLWithString("http://domain.com/index.php?r=appsync/read&id=category") 
     var session = NSURLSession.sharedSession() 
     session.dataTaskWithURL(url, completionHandler: {(data, response, error) in 
      let json = JSONValue(data) 
      let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext //this line had to be moved here 
      let entityDescription = NSEntityDescription.entityForName("Category", inManagedObjectContext: managedObjectContext) 
      for item in json.array! { 
       let category = Category(entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext) //this line has to be in inside for loop 
       category.id = item["id"].string!.toInt()! 
       category.title = item["title"].string! 
       category.mydescription = item["description"].string! 
       managedObjectContext?.save(nil) 
      } 
      dispatch_async(dispatch_get_main_queue()) { 
       // do something 
      } 
     }).resume() 
    } 
} 

Esempio recupero codice dei dati:

func requestData() { 
    let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate 
    let context:NSManagedObjectContext = appDel.managedObjectContext! 
    var request = NSFetchRequest(entityName: "Category") 
    request.returnsObjectsAsFaults = false 
    var results:NSArray = context.executeFetchRequest(request, error: nil) 
    //println(results) 
    for category in results { 
     var cat = category as Category 
     println("\(cat.id),\(cat.title),\(cat.mydescription)") 
    } 
} 

P.S. Assicurarsi di pulire il vostro progetto ed eliminare l'applicazione dal simulatore dopo aver cambiato modello

+1

Dovrebbe essere NSNumber? O possibile lasciarlo come var id? AS rapido lo dedurrà dal valore che hai inserito? – CW0007007

+0

Ottengo errore 'EXC_BAD_ACCESS' quando lo faccio alla stessa riga, ho provato a cambiare' Int' nel modello in 'NSNumber' e anche' category.id = item ["id"]. Stringa! .toInt() ! come NSNumber! 'e altre combinazioni, stesso risultato. E non ho capito cosa intendi con _leave it var id_ –

+0

Non dichiarare esplicitamente un tipo? Non ho fatto molto in fretta. Quindi non so se un EntityModel funzionerà senza un tipo esplicito. Quindi passare a: @NSManaged var id – CW0007007

risposta

6

I tipi scalari (interi, float, booleani) nei dati di base sono interrotti nella versione corrente di Swift beta (5). Usa NSNumber per le proprietà e invia un radar.

object.intProperty = NSNumber(int:Int(item["id"] as String)) 

(digitato al telefono, mi dispiace se questo è sbagliato, e so che è il codice disgustoso - di conseguenza, un file di radar)

Oppure, nel caso specifico, guardando il JSON, uso Stringa. Quegli ID stanno arrivando come stringhe comunque.

+0

Ho aggiornato la mia domanda con codice funzionante, credo che xCode stia giocando e dato che stavo cambiando il mio file di modello (che ho creato manualmente) senza pulire il mio progetto stavo diventando Errori BAD_ACCESS –

+1

@ (objc) non è la soluzione consigliata, consultare http://stackoverflow.com/questions/24926418/swift-array-cannot-be-downcast-to-array-of-derived/24926845#24926845 – jrturton

1

Aggiornato per Swift 2

Se i dati JSON è in realtà di tipo [[String:String]], è possibile utilizzare il seguente codice al fine di impostare category.id :

if let unwrappedString = item["id"], unwrappedInt = Int(unwrappedString) { 
    category.id = unwrappedInt 
} 
+0

La tua risposta è corretta Ho dovuto usare NSNumber nel file di modello –

Problemi correlati