[Résolu] CoreData : Save et Load un Array

busterTheobusterTheo Membre
mars 2015 modifié dans Dev. iOS, watchOS, tvOS #1

Bonjour, suite aux réponses reçues sur ce post


http://forum.cocoacafe.fr/topic/13588-manipuler-les-courbes-de-bezier/


 


je suis amené à  essayer d'enregistrer un tableau (de string pour l'instant, mais plus tard ce sera des CGFloat), dans coreData.


 


J'ai bien lu


http://forum.cocoacafe.fr/topic/9174-comment-installer-un-nsmutablearray-comme-attribut-dune-entite-core-data/?hl=unarchiver#entry88431


et


https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html


et


http://geekyviney.blogspot.fr/2015/02/transformable-binary-data-properties-in.html


 


et j'ai donc fait des essais, mais j'avoue que je ne comprend pas tout, et je suis sur de faire n'importe quoi. En plus, tout ce que je lis est en objC, et je travaille en swift. Pas facile.


 


Je teste donc sur un projet bidon, dans lequel je rempli un tableau, puis tente de l'enregistrer et lire de coreData, avec (NSKeyedUnarchiver), et ça marche pas.


 


En même temps je ne dis pas que j'enregistre le tableau (leTablo) dans le champ "tablo" du model, mais je ne sais pas comment faire.


 


Petite vidéo de démo ici


http://www.magnitude-6.net/ge/y.mov


 


Et mon code :


La base



import Foundation
import CoreData

@objc(Tableau)
class Tableau: NSManagedObject {
@NSManaged var nom: String
@NSManaged var tablo: NSArray
}

Le ViewController



import UIKit
import CoreData

class ViewController: UIViewController, NSFetchedResultsControllerDelegate {

// MARK: - Properties

@IBOutlet weak var nom: UITextField!
@IBOutlet weak var element: UITextField!

// MARK: - Variables

var leTablo = [String]()

var managedObjectContext: NSManagedObjectContext? = nil

// MARK: - Actions

@IBAction func ajouter(sender: AnyObject) {
println("à‰léments du tableau")
leTablo.append(element.text)
for item in leTablo {
println(item)
}
}

@IBAction func enregistrer(sender: AnyObject) {
var appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
let entity = NSEntityDescription.entityForName("Tableau", inManagedObjectContext: context)

var newTablo = Tableau(entity: entity!, insertIntoManagedObjectContext: context)
newTablo.nom = nom.text
NSKeyedArchiver.archivedDataWithRootObject(leTablo)
context.save(nil)

println("Enregistrement dans cordeData")
}

@IBAction func afficher(sender: AnyObject) {
println("Affichage du cordeData")

var error: NSError? = nil
let fetchRequest = NSFetchRequest(entityName: "Tableau")
if let returnedObject = managedObjectContext?.executeFetchRequest(fetchRequest, error: &error) as? [Tableau] {
println(returnedObject.count)
}
}

// Mark: - View Life Cycle

override func viewDidLoad() {
super.viewDidLoad()
}
}

Je ne met pas le AppDelegate, car c'est celui d'Apple (nouveau projet coreData)


 


Merci d'avance aux courageux qui pourraient m'aider


 


Mots clés:

Réponses

  • colas_colas_ Membre
    mars 2015 modifié #2

    A priori tu t'y prends mal.


     


    Avec Core Data, tous tes objets sont "automatiquement" sauvegardés. Donc, tu n'as pas besoin de NSKeyedUnarchiver. 


  • Merci de ta réponse.


    Je sais que je m'y prend mal, mais comment je fais pour enregistrer un array, je sais enregistrer un string (newUser.nom = nomTextField.text)


     


    ...


  • Veux-tu enregistrer un array et un seul ? Ou bien de multiples array ?


     


    Ton array, c'est tous tes users ?


    Si c'est le cas, à  chaque que tu crées un user, il sera AUTOMATIQUEMENT sauvegardé et donc, quand plus tard tu voudras récupérer tes users, tu demanderas à  core data : "donne-moi tous les objets de type user".

  • Non mon array c'est pas tous les users.


     


    Je sais enregistrer le coreData avec les champs - genre : nom, prénom, âge, etc.


     


    Mais je dois enregistrer un champ spécifique, qui sera de type "transformable" et non pas "string" ou "int", en plus des autres champs évidemment.


     


    Ce champ transformable doit contenir un Array, pour éviter d'enregistrer toutes les valeurs de mon array dans des centaines de champs.


     


    Merci encore


  • Joanna CarterJoanna Carter Membre, Modérateur

    Pourquoi pas créer une autre entité pour stocker les coordonnées et une relation pour lier les deux ?


  • parce que je vais avoir des centaines de coordonnées, c'est pourquoi il me faut un tableau


     


    et aussi sur les conseils de fleurantin en fin de ce post


    http://forum.cocoacafe.fr/topic/13588-manipuler-les-courbes-de-bezier/


     


    Merci pour vos réponses

  • De mémoire, il faut que tu choisisses un attribut Transformable, que tu donnes en paramètre de cet attribut des classes pour archiver et désactiver. Tu dois aussi donner la classe de ton attribut (ici NSArray)


     


    Ensuite, coredata gère tout seul ! Si par exemple ton attribut s'appelle array, ton code sera :



    myManagedObject.array = @[;@Nom1, @Nom2, @Nom3] ;

    De mémoire, si les objets que tu veux archiver sont des array de strings, tu n'as pas besoin de préciser les classes pour désarchiver et archiver.


     


    J'avais trouvé ces infos sur le net. Bon courage, reviens demander si tu n'y arrives toujours pas.


     


    PS : moi pas parler Swift

  • Merci pour tes encouragements, ça fait du bien  :p


    J'ai déjà  l'attribut "Transformable", et la classe NSArray (voir code plus haut), mais je ne trouve pas ce qu'il faut faire


     


    Pour enregistrer un champ string il suffit de faire user.nom = user.text, mais pour un transformable, on fait quoi.


    Pour un tableau je fais quoi user.tablo = leTablo (voir les variables plus haut) ? Ben non, je sais que c'est pas si simple, mais je n'arrive pas à  trouver le truc...


    Et je peux pas faire 



     


     


    myManagedObject.array = @[@Nom1, @Nom2, @Nom3] ;

    Car je n'ai pas le contenu du tableau. Cela se stock dans le tableau (voir la vidéo plus haut)


  • une idée ?


  • Si je crois que c'est aussi simple que cela pour enregistrer le tableau : 



    myManagedObject.array = monTableau ;

  • Joanna CarterJoanna Carter Membre, Modérateur
    mars 2015 modifié #12

    OK, je viens de expérimenter avec le stockage d'un UIBezierPath dans CoreData.


     


    Tout d'abord, dans le modèle, il faut marquer l'attribut comme dans le capture d'écran ci-joint.


     


    Et, dans la classe :



    import UIKit
    import CoreData

    class Forme: NSManagedObject
    {
    @NSManaged var path: UIBezierPath

    override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?)
    {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
    }
    }

    Puis, on peut enregistrer un objet comme ci :



    {
    let path = UIBezierPath()

    path.moveToPoint(CGPoint(x:100, y:50))

    path.addCurveToPoint(CGPoint(x:300, y:50), controlPoint1:CGPoint(x:100, y:250), controlPoint2:CGPoint(x:300, y:250))

    path.addCurveToPoint(CGPoint(x:100, y:50), controlPoint1:CGPoint(x:300, y:0), controlPoint2:CGPoint(x:100, y:0))

    path.closePath()

    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
    {
    if let moc = appDelegate.managedObjectContext
    {
    let entity = NSEntityDescription.entityForName("Forme", inManagedObjectContext:moc)!

    let forme = Forme(entity: entity, insertIntoManagedObjectContext:moc)

    forme.path = path

    var error : NSError? = nil

    moc.save(&error)
    }
    }
    }

    Et, pour le récupérer :



    {
    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
    {
    let moc: NSManagedObjectContext? = appDelegate.managedObjectContext

    if moc != nil
    {
    let fetchRequest = NSFetchRequest(entityName: "Forme")

    var error : NSError? = nil

    if let formes = moc!.executeFetchRequest(fetchRequest, error: &error) as? [Forme]
    {
    let forme = formes[0]

    let path = forme.path

    path.lineWidth = 2.0

    // utiliser path qui est un UIBezierPath
    }
    }
    }
    }

  • Ah, ben c'est des bonnes nouvelles tout ça - super.


     


    En attendant, pour mettre en pratique tout çà  (coreData, sauv et load), faut déjà  que je puisse dessiné sur un nouveau projet avec la technique des loyers - Voir discussion


  • busterTheobusterTheo Membre
    mars 2015 modifié #14

    Bon, ben ça-yest, ça marche - save and load du path de coreData.


    Je met une vidéo ici, et j'hésite à  mettre le code, car il est long, mais je peux le mettre si nécessaire.


     


    Merci encore pour votre aide. Je met résolu.


  • Salut,


     


    Bravo pour ta participation constructive au site. Le sujet ne m'intéresse pas plus que cela pour le moment mais je l'ai suivi d'un oe“il car j'hésite à  me plonger dans core data pour le moment.


     


    - C'est génial d'indiquer quand un problème est résolu.


    - L'idée de la vidéo est pas mal.


     


    Pour le code partageable j'utilise github qui permet à  chacun de suivre ton code et de proposer des améliorations.

  • busterTheobusterTheo Membre
    mars 2015 modifié #16

    Hey iLandes,


    merci pour les compliments.


     


    Utilises-tu une autre technologie que coreData pour stoker les infos ?


     


    J'ai essayé de m'inscrire chez Github, je suis inscris, mais impossible d'uploader mon projet. J'ai lu l'aide, et installer Github for mac, l'ai lancé, créer un New Repository, en gros, j'y comprend rien. Y'a pas un endroit où uploader un zip du projet ?


     


     


    J'ai créé un nouveau post pour Github


  • Joanna CarterJoanna Carter Membre, Modérateur

    Utilises-tu une autre technologie que coreData pour stoker les infos ?




    ça dépend sur la quantité de données que tu prévoies stocker. Pour les petites quantités tu pourrais utiliser les plists, mais le plus efficaces et le plus facile à  utiliser, surtout pour les UITableViews, c'est CoreData
  • Ouais je vais avoir pas mal de données. Les plists, je connais, le coreData semble mieux pour mes besoins. Merci.


Connectez-vous ou Inscrivez-vous pour répondre.