Charger une entité Core Data dans un Array

Bonsoir à  tous,


 


Comment puis-je charger les données contenues dans une entité Core Data vers un Array ?


 


Admettons que mon entité se nomme Produit, j'avais commencé à  faire une boucle :



var arrayOfProduct = NSArray

for produit in Produit {

...


Mais je n'ai pas la syntaxe, merci.


 


Réponses

  • Joanna CarterJoanna Carter Membre, Modérateur
    Pourquoi les mettre dans un array ?


    Quand tu fais un NSFetchRequest, le résultat est déjà  un array - fetchedObjects.


    Qu'est-ce que tu veux faire avec les données ?
  • En fait dans une de mes applications déjà  publiée sur le store, j'ai créé le modèle Core Data avec un attribut date en String (erreur) !


    je voulais recréer un Array avec tous les attributs du modèle Core Data mais avec une date qui a bien le type date pour pouvoir faire des tris. Je pourrais changer le type dans Core data mais je ne voulais pas avoir à  faire une migration du modèle Core Data lors de la republication de l'appli.

  • Tu as combien d'attributs dans Product ?


  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #5

    Comment accèdes-toi les products ? Tu utilises un NSFetchedResultsController ?


     


    Pour les trier hors de Core Data, tu peux prendre l'array et faire qqch comme suivant :



    let sortedProducts = products.sorted(by:
    {
    (product1, product2) -> Bool in

    return... // compares les deux "dates"
    })
  • @Colas_ : j'ai 5 attributs


     


    @Joanna Carter : j'utilise ceci pour extraire les données :



    let
    fetchRequest = NSFetchRequest()

    // Create Entity Description
    let entityDescription = NSEntityDescription.entityForName("Product", inManagedObjectContext: self.managedObjectContext)

    // Configure Fetch Request
    fetchRequest.entity = entityDescription

    do {
    let result = try self.managedObjectContext.executeFetchRequest(fetchRequest)
    print(result)

    } catch {
    let fetchError = error as NSError
    print(fetchError)
    }


    En revanche je ne comprends pas bien ton code, comment je fais si je veux trier mes produits par la date d'entrée en stock de la plus ancienne à  la plus récente (ou l'inverse) ?


    dans ma table j'ai en gros :


     


    ID : 1


    Produit : produit 1


    Date entrée : 14 février 2017


     


    ID : 2


    Produit : produit 2


    Date entrée : 01 février 2017


     


    etc.


     


    merci

  • Joanna CarterJoanna Carter Membre, Modérateur
    Si tu voulais trier sur l'entierité du string de ton date :

    let sortedProducts = products.sorted(by:
    {
    (product1, product2) -> Bool in

    return product1.date < product2.date // ascendant
    // ou
    return product1.date > product2.date // descendant
    })

    Mais dans ton cas, il te faut séparer les composants de tes strings, les réarranger et renvoyer le resultat de la comparaison.
  • Joanna CarterJoanna Carter Membre, Modérateur

    Exemple utilisant une struct juste pour tester



    struct Product
    {
    var product: String?

    var date: String?
    }

    Et du code pour faire le test :



    {
    // lookup pour valeur numérique du mois
    let months = ["janvier" : "01", "février" : "02", "mars" : "03", "avril" : "04", "mai" : "05", "juin" : "06", "juillet" : "07", "août" : "08", "septembre" : "09", "octobre" : "10", "novembre" : "11", "décembre" : "12"]

    // données pour le test
    let products = [Product(product: "Stone", date: "14 février 2017"), Product(product: "Paper", date: "05 septembre 2016"), Product(product: "Scissors", date: "01 février 2017")]

    let sortedProducts = products.sorted
    {
    // séparer les trois parties du premier string, puis les renverser
    var dateComponents0 = $0.date.components(separatedBy: " ").reversed() as [String]

    // remplacer le nom du premier mois avec sa valeur numérique
    dateComponents0[1] = months[dateComponents0[1]]!

    // séparer les trois parties du deuxième string, puis les renverser
    var dateComponents1 = $1.date.components(separatedBy: " ").reversed() as [String]

    // remplacer le nom du deuxième mois avec sa valeur numérique
    dateComponents1[1] = months[dateComponents1[1]]!

    // renvoyer le résultat de la comparaison des deux dates, maintenant en format yyyymmdd
    return dateComponents0.joined() < dateComponents1.joined()
    }

    print(sortedProducts)
    }
  • LarmeLarme Membre
    février 2017 modifié #9

    C'est bizarre ton machin.


    En Objective-C, j'aurais utilisé un NSDateFormatter plutôt que du parsing manuel de la String.



    NSDateFormatter *dateFormatter = [NSDateFormatter alloc] init];
    //Set Correct settings/dateFormat to dateFormatter
    NSArray *sorted = [products sortedArrayUsingComparator:^NSComparisonResult(ClassProduct *a, ClassProduct *b) {
       NSDate *dateA = [dateFormatter dateFromString:[a dateString]];
       NSDate *dateB = [dateFormatter dateFromString:[b dateString]];
       return [dateA compare:dateB];
    }];

  • Joanna CarterJoanna Carter Membre, Modérateur


     


    C'est bizarre ton machin.


    En Objective-C, j'aurais utilisé un NSDateFormatter plutôt que du parsing manuel de la String.



    NSDateFormatter *dateFormatter = [NSDateFormatter alloc] init];
    //Set Correct settings/dateFormat to dateFormatter
    NSArray *sorted = [products sortedArrayUsingComparator:^NSComparisonResult(ClassProduct *a, ClassProduct *b) {
       NSDate *dateA = [dateFormatter dateFromString:[a dateString]];
       NSDate *dateB = [dateFormatter dateFromString:[b dateString]];
       return [dateA compare:dateB];
    }];



     


    Effectivement, oui, mais seulement presque.


     


    Moi, j'ai supposé que les strings des dates pourrait être en format non-standard ou que l'iBidule de l'utilisateur utilise une autre locale que français.


     


    Heureusement, si mon orthographe des noms des mois et égale à  ça des données de helio, après expérimentation (en Swift) :



    let products = [Product(product: "Stone", date: "14 février 2017"), Product(product: "Paper", date: "05 septembre 2016"), Product(product: "Scissors", date: "01 février 2017")]

    let sortedProducts = products.sorted
    {
    let dateformatter = DateFormatter()

    dateformatter.dateFormat = "dd MMMM yyyy"

    dateformatter.locale = Locale(identifier: "fr_FR")

    let date0 = dateformatter.date(from: $0.date!)

    let date1 = dateformatter.date(from: $1.date!)

    return date0! < date1!
    }

    print(sortedProducts)


    C'est vachement plus jolie  8--)



  • Effectivement, oui, mais seulement presque.


     


    Moi, j'ai supposé que les strings des dates pourrait être en format non-standard ou que l'iBidule de l'utilisateur utilise une autre locale que français.


     


    Heureusement, si mon orthographe des noms des mois et égale à  ça des données de helio, après expérimentation (en Swift) :



    let products = [Product(product: "Stone", date: "14 février 2017"), Product(product: "Paper", date: "05 septembre 2016"), Product(product: "Scissors", date: "01 février 2017")]

    let sortedProducts = products.sorted
    {
    let dateformatter = DateFormatter()

    dateformatter.dateFormat = "dd MMMM yyyy"

    dateformatter.locale = Locale(identifier: "fr_FR")

    let date0 = dateformatter.date(from: $0.date!)

    let date1 = dateformatter.date(from: $1.date!)

    return date0! < date1!
    }

    print(sortedProducts)


    C'est vachement plus jolie  8--)




    Je pense que c'est encore mieux si tu sors le DateFormatter du closure. à‰vitant n alloc/init à  chaque fois, ce qui est le plus coûteux dans le DateFormatter. C'est du pinaillage, mais bon.

  • Joanna CarterJoanna Carter Membre, Modérateur


    Je pense que c'est encore mieux si tu sors le DateFormatter du closure. à‰vitant n alloc/init à  chaque fois, ce qui est le plus coûteux dans le DateFormatter. C'est du pinaillage, mais bon.




     


    Et t'as raison là    Du coup, le code le plus correct :



    let products = [Product(product: "Stone", date: "14 février 2017"), Product(product: "Paper", date: "05 septembre 2016"), Product(product: "Scissors", date: "01 février 2017")]

    let dateFormatter = DateFormatter()

    dateFormatter.dateFormat = "dd MMMM yyyy"

    dateFormatter.locale = Locale(identifier: "fr_FR")

    let sortedProducts = products.sorted
    {
    let date0 = dateformatter.date(from: $0.date!)

    let date1 = dateformatter.date(from: $1.date!)

    return date0! < date1!
    }

    print(sortedProducts)
  • Merci à  vous !


  • ça fonctionne bien, en revanche je fais comment pour récupérer mes données à  partir de sortedProducts ?


    je n'ai plus de value(forkey: ) pour sortedProducts.


    Merci. 


  • LarmeLarme Membre
    février 2017 modifié #15

    ça fonctionne bien, en revanche je fais comment pour récupérer mes données à  partir de sortedProducts ?

    je n'ai plus de value(forkey: ) pour sortedProducts.

    Merci.




    Tu as zappé un truc.
    let products est un array d'objects de classe Products.
    let sortedProducts est un array d'objects de classe Products.


     


    Donc


    let productN = sortedProduct[n]

    Et c'est bon.

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