[Résolu] Transmettre une Entity Relationship comme un Int ou un String

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

Bonjour,


en gros, dans mon coreData, j'ai une entité de base - Patients :



import Foundation
import CoreData

@objc(Patients)
class Patients: NSManagedObject {
@NSManaged var nom: String
etc
}

J'ai aussi plusieurs Relationships :


Par exemple :


Au sein du code précédent.



@NSManaged var uneRelationship: UneRelationship?

Puis dans l'entité associé, évidemment :



import Foundation
import CoreData

@objc(UneRelationship)
class UneRelationship: NSManagedObject {
@NSManaged var blablabla: String
etc
@NSManaged var patients: Patients
}

Voilà  pour le coreData tout simple.


 


 


 


 


 


 


 


 


 


Je suis en train de construire une méthode qui doit travailler sur toutes ces fameuses entity Relationship avec Patients.


 


Si je travaille sur une seule entity, pas de problèmes.



let fetchEntity: FetchEntity = FetchEntity()
let fetchResults: NSArray = fetchEntity.getFetchResults("Patients", predicateField: listeDesVariables.nomString)

let singlePatient: Patients = fetchResults.lastObject as! Patients

if let ecran = singlePatient.uneRelationship {
...
}


Mais j'aurai besoin de faire un truc du genre :



if let ecran = singlePatient.variableRepresentantNimporteQuelleEntity {
...
}

Et c'est là  où je bloque.


 


Pour un String, on fait :



var unString: String

Pour un Int :



var unInt: Int

Mais pour une variableRepresentantNimporteQuelleEntity, qui peut être uneRelationship ou uneAutreRelationship ou encoreUneAutreRelationship, quel est le type ?


 


Puisque :


uneRelationship est de type UneRelationship


et


uneAutreRelationship est de type UneAutreRelationship


et


encoreUneAutreRelationship est de type EncoreUneAutreRelationship


 


quel est le type de la variable qui pourrait représenter n'importe laquelle de ce entité ?


 


à‰videmment le but est d'éviter de faire un énorme switch...


 


Merci d'avance...


Mots clés:

Réponses

  • A force d'essais, j'ai réussi à  faire ce que je voulais.


    Récupérer dans une boucle, les entity Relationship.


     


    Je met le code, si ça peut aider.


    C'est la méthode "getField()"



    import UIKit
    import CoreData

    class FetchEntity {

    func getEntity(entityName: String) -> NSEntityDescription {
    let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: GeContext!)
    return entityDescription!
    }

    func getFetchResults(entityName: String, predicateField: String) -> NSArray {
    let fetchRequest: NSFetchRequest = NSFetchRequest()
    fetchRequest.entity = getEntity(entityName)
    fetchRequest.returnsObjectsAsFaults = false

    let predicate: NSPredicate = NSPredicate(format: "nom == '\(predicateField)'")
    fetchRequest.predicate = predicate
    let fetchResults: NSArray = GeContext!.executeFetchRequest(fetchRequest, error: nil)!

    return fetchResults
    }

    func getField(entityName: String,field: String, fetchResults: NSArray)-> String {
    let fetchRequest: NSFetchRequest = NSFetchRequest()
    fetchRequest.entity = getEntity(entityName)
    fetchRequest.returnsObjectsAsFaults = false

    let fetchResults: NSArray = GeContext!.executeFetchRequest(fetchRequest, error: nil)!

    var retourField = ""
    if fetchResults.count > 0 {
    for result in fetchResults as! [NSManagedObject] {
    if let singleField = result.valueForKey(field) as? String {
    retourField = singleField
    }
    }
    }
    return retourField
    }
    }

    Puis l'appel de la méthode



    let fetchEntity: FetchEntity = FetchEntity()
    let fetchResults: NSArray = fetchEntity.getFetchResults("Patients", predicateField: listeDesVariables.nomString)

    var angleStart = CGFloat(0)
    var angleEnd = CGFloat(0)
    var roueColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0)

    angleStart = CGFloat((fetchEntity.getField(entites[indexRoues], field: "angleStart", fetchResults: fetchResults) as NSString).doubleValue)
    angleEnd = CGFloat((fetchEntity.getField(entites[indexRoues], field: "angleEnd", fetchResults: fetchResults) as NSString).doubleValue)
    let recupRoueColor = fetchEntity.getField(entites[indexRoues], field: "roueColor", fetchResults: fetchResults)
    if recupRoueColor == "1" {
    roueColor = RoueVerteColor
    } else {
    roueColor = RoueRougeColor
    }
    resultatRoues[indexRoues].startAngleSent = angleStart
    resultatRoues[indexRoues].endAngleSent = angleEnd
    resultatRoues[indexRoues].roueColorSent = roueColor
    boutons[indexRoues].addSubview(resultatRoues[indexRoues])

    Je met donc résolu.


     


    :D

  • Hello,


     


    J'ai l'impression que ton code n'est pas optimisé. Pourquoi passes-tu fetchResults (NSArray) en paramètres dans le getField ?


  • busterTheobusterTheo Membre
    octobre 2015 modifié #4

    Oh purée, t'as grave raison, c'est un reste de recherche/tests/copier/coller.


     


    ComD'hab, t'as l'oe“il.


     


    Merci d'avoir pris le temps, samir, je vais virer ça tout de suite.


     


          :p


  • AliGatorAliGator Membre, Modérateur
    octobre 2015 modifié #5
    Sinon en alternative à  MagicalRecord mais pensé dès le début en Swift et pour Swift, il y a QueryKit. Encore une alternative qui pourrait te simplifier grandement la vie et le code !
  • busterTheobusterTheo Membre
    octobre 2015 modifié #6

    Ah merci Aliator, je l'ai downloadé.


     


    ça a l'ai bien aussi.


     


    Je regarderais dès que je serais sorti de mon projet, car j'avance bien, et je touche presque à  la fin, à  part mes problème de memory grows.


     


    Mais je créerai un post là -dessus.


     


    Encore merci. 


  • samirsamir Membre
    octobre 2015 modifié #7


    Ah merci Aliator, je l'ai downloadé.




     


    Tu dis ça au "Guardian of Consistency" de CocoaPods. Tu va te faire gronder toi si tu télécharges les sources à  l'ancienne et que tu n'utilises pas CocoaPods ;).


     


    Bon courage pour finir ton application !


  • busterTheobusterTheo Membre
    octobre 2015 modifié #8

    :o Ben il m'a donné le lien pour cela, non ?


    C'est un lien github. J'ai lu puis downloadé pour la suite.


  • busterTheobusterTheo Membre
    octobre 2015 modifié #9

    samir, en fait sur l'histoire du fetchResults, je me suis carrément enflammé.


    Bon, sur ce sujet, je ne change rien, t'avais raison de toutes façon.


     


    Par contre, en changeant de "patients" (autre enregistrement coreData dans le tableView), je me suis rendu compte que je récupérais toujours les même données. ça craint.


     


    Voir le code que je jugeais bon, plus haut.


     


    Donc, j'ai un peu trituré tout ça, et je me retrouve avec le même problème. Voir le titre du post.


     


    J'ai viré la transmission de l'entity de base, car je l'ai déjà  au départ. J'avais ça pour attaquer la relationsShiop, et ça marche pas.


     


    Je n'en suis qu'au départ, je n'arrive même pas à  choper la relationShip, alors quand j'en serais à  récupérer un de ses champs, on va rigoler.


     


    Mais bon, concernant le premier niveau d'attaque...


     


    Je simplifie mon code pour que ce ne soit pas trop l'embrouille. Donc le return est vide pour l'instant.


    Je travaille sur les printlns.



    func getField(field: String, fetchResults: NSArray)-> String {

    println("field = \(field)")

    var retourField = ""
    if fetchResults.count > 0 {
    let singlePatient: Patients = fetchResults.lastObject as! Patients
    for result in fetchResults as! [NSManagedObject] {
    if let singleField = singlePatient.valueForKey("nom") as? String {
    println("singleField = \(singleField)")

    // retourField = singleField
    }
    }
    }
    return retourField
    }

    Là , j'ai bien println :



     


     


    field = uneRelationship

    et 



     


    singleField = aaa



     


    aaa étant le champ "nom" pour le predicateField (voir plus haut (func getFetchResults())


     


    Mais quand je remplace



    if let singleField = singlePatient.valueForKey("nom") as? String {

    par



    if let singleField = singlePatient.valueForKey(field) as? String {

    Il ne récupère pas le field - Pfff - C'est sur, dans le coreData 



     


     


    uneRelationship est de type UneRelationship

     


    et non pas string. D'où le titre.


    Puisque dans ce projet, il faudrait que ce soit en variable, et transmis à  une méthode.


     


    J'ai ça 


     



     


     


    field = uneRelationship

     


    mais c'est tout - Normal.


     


    Ah, en écrivant ce post, j'ai fait une petite modif et ça s'arrange en faisant ça :



    if let singleField: AnyObject = singlePatient.valueForKey(field) {

    Dingue, c'est en faisant la remarque sur le string, que j'ai pensé à  le virer, et donc xCode, pour une fois, ne dit pas que des conneries (enfin j'espère) - Dixit le AnyObject.


     


     


    J'ai donc maintenant, cela :


     



     


     


    singleField = <UneRelationship: 0x7fc29a74ee80> (entity: UneRelationship; id: 0xd000000000080004 <x-coredata://7C4C6B04-6AAC-42F8-80CD-7A6FAF58B95D/E1L1/p2> ; data: <fault>)

    Très intéressant.


     


    Il ne me reste plus qu'à  récupérer maintenant les champs de cette entité (relationShip)


     


    Je m'y attelle demain.


     


    Merci d'avance pour les remarques


  • En gros, si ne dois pas transmettre et récupérer une variable représentant cette entity relationship,


    je sais le faire.



    let singlePatient: Patients = fetchResults.lastObject as! Patients

    if let laRelationship = singlePatient. uneRelationship {
    unChamp.text = laRelationship.unDesAttributsDeLaRelationship
    }

    Voilà , l'idée, c'est cette histoire de variable d'entity et surtout de son type qui varie en fonction de l'entity transmise.



    @NSManaged var uneRelationship: UneRelationship?
    @NSManaged var uneAutreRelationship: UneAutreRelationship?
  • busterTheobusterTheo Membre
    octobre 2015 modifié #11

    Bon ben j'avais ôter le "Résolu", et du coup je vais le remettre.


     


    J'ai pu pousser mes investigations, et j'ai trouvé.


    Là , c'est sur. Je change de "patients" et les données sont bien différentes et associées au patient.


     


    Je suis vraiment désolé d'occuper le forum, alors que je trouve tout seul la solution à  mon problème.


    Mais peut-être que ces délires (on ne sait jamais) pourront éclairer certain collègues.


     


    En tout cas en résumé je suis un grand fan de :



    if let toto = titi {
    ...
    }

    et de 



    kekChoZ.valueForKey(unTruc)

    et évidemment de :



    : AnyObject

    Et aussi de :



    as! String 

    ou :



    as? String 

    Voici le code...


     


    La classe :



    import UIKit
    import CoreData

    class FetchEntity {

    func getEntity(entityName: String) -> NSEntityDescription {
    let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: GeContext!)
    return entityDescription!
    }

    func getFetchResults(entityName: String, predicateField: String) -> NSArray {
    let fetchRequest: NSFetchRequest = NSFetchRequest()
    fetchRequest.entity = getEntity(entityName)
    fetchRequest.returnsObjectsAsFaults = false

    let predicate: NSPredicate = NSPredicate(format: "nom == '\(predicateField)'")
    fetchRequest.predicate = predicate
    let fetchResults: NSArray = GeContext!.executeFetchRequest(fetchRequest, error: nil)!

    return fetchResults
    }

    func getField(relatShip: String, field: String,fetchResults: NSArray)-> String {
    var retourField = ""
    if fetchResults.count > 0 {
    let singlePatient: Patients = fetchResults.lastObject as! Patients
    for result in fetchResults as! [NSManagedObject] {
    if let singleRelShip: AnyObject = singlePatient.valueForKey(relatShip) {
    if let singleField: AnyObject = singleRelShip.valueForKey(field) {
    retourField = singleField as! String
    }
    }
    }
    }
    return retourField
    }
    }

    Et l'appel :



    func roueResultat(indexRoues: Int) {
    let fetchEntity: FetchEntity = FetchEntity()
    let fetchResults: NSArray = fetchEntity.getFetchResults("Patients", predicateField: listeDesVariables.nomString)

    var angleStart = CGFloat(0)
    var angleEnd = CGFloat(0)
    var roueColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0)

    angleStart = CGFloat((fetchEntity.getField(entites[indexRoues], field: "angleStart", fetchResults: fetchResults) as NSString).doubleValue)
    angleEnd = CGFloat((fetchEntity.getField(entites[indexRoues], field: "angleEnd", fetchResults: fetchResults) as NSString).doubleValue)
    let recupRoueColor = fetchEntity.getField(entites[indexRoues], field: "roueColor", fetchResults: fetchResults)
    if recupRoueColor == "1" {
    roueColor = RoueVerteColor
    } else {
    roueColor = RoueRougeColor
    }

    resultatRoues[indexRoues].startAngleSent = angleStart
    resultatRoues[indexRoues].endAngleSent = angleEnd
    resultatRoues[indexRoues].roueColorSent = roueColor
    boutons[indexRoues].addSubview(resultatRoues[indexRoues])
    }

    Encore merci pour l'aide des barmen.


    :p   :p   :p


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