Comment puis-je facilement dupliquer/copier un objet existant

j'ai un objet Realm qui a plusieurs relations, n'importe qui a un bon snippet de code qui généralise une méthode de copie, pour créer un duplicate dans la base de données.

10
demandé sur mvo 2015-05-09 23:25:37

4 réponses

Dans mon cas, je voulais juste créer un objet et de ne pas persister. donc

Swift 3

pour créer un clone d'objet utilisateur dans swift il suffit d'utiliser

let newUser = User(value: oldUser);

le nouvel objet utilisateur ne persiste pas.

8
répondu Cerlin Boss 2017-10-13 10:25:29

Vous pouvez utiliser les méthodes suivantes pour créer une copie de votre objet, tant que ce n'est pas une clé primaire:

realm.create(ObjectType.self, withValue: existingObject)
6
répondu segiddins 2015-05-11 17:01:31

j'ai eu le même problème et trouvé une solution simple pour obtenir une copie d'un royaume de l'objet. Fondamentalement, vous avez juste besoin de rendre l'objet conforme au protocole NSCopying, quelque chose comme:

import RealmSwift
import Realm
import ObjectMapper

class Original: Object, NSCopying{
   dynamic var originalId = 0
   dynamic var firstName = ""
   dynamic var lastName = ""

override static func primaryKey() -> String? {
    return "originalId"
}

init(originalId: Int, firstName: String, lastName: String){
    super.init()

    self.originalId = originalId
    self.firstName = firstName
    self.lastName = lastName
}

func copy(with zone: NSZone? = nil) -> Any {
    let copy = Original(originalId: originalId, firstName: firstName, lastName: lastName)

    return copy
}
}

alors vous appelez juste la méthode "copy ()" sur l'objet:

class ViewController: UIViewController {
   var original = Original()
   override func viewDidLoad() {
       super.viewDidLoad()

       var myCopy = original.copy()
   }
}

ce qui est bien d'avoir une copie, c'est que je peux la modifier sans avoir à être dans une transaction d'écriture de domaine. Utile lorsque les utilisateurs éditent certaines données mais n'ont pas encore cliqué sur Enregistrer ou ont simplement changé leur esprit.

2
répondu Ahmad 2017-02-14 12:38:41

comme ce problème est toujours vivant, je poste ma solution qui fonctionne mais doit encore être améliorée. J'ai créé une extension de classe objet qui a cette méthode dupliquée qui prend un objet objOut et remplit les propriétés plates en se regardant. Quand une propriété non-plate est trouvée (alias un objet imbriqué) que l'on saute.

// Duplicate object with its flat properties
func duplicate(objOut: Object) -> Object {

    // Mirror object type
    let objectType: Mirror = Mirror(reflecting: self);

    // Iterate on object properties
    for child in objectType.children {

        // Get label
        let label = child.label!

        // Handler for flat properties, skip complex objects
        switch String(describing: type(of: child.value)) {
        case "Double", "Int", "Int64", "String":
            objOut.setValue(self.value(forKey: label)!, forKey: label)
            break
        default:
            break
        }
    }

    return objOut
}

dans la classe Manager pour mes Royaumes j'ai la méthode copyFromRealm() que j'utilise pour créer mes copies d'objets. Pour vous donner une pratique exemple voici la structure de ma classe de nomination:

Appointment object
    - flat properties
    - one UpdateInfo object
        - flat properties
    - one AddressLocation object
        - flat properties
        - one Address object
            - flat properties
        - one Coordinates object
            - flat properies
    - a list of ExtraInfo
        - each ExtraInfo object
            - flat properties

Voici comment j'ai implémenté la méthode copyFromRealm ():

// Creates copy out of realm
func copyFromRealm() -> Appointment {

    // Duplicate base object properties
    let cpAppointment = self.duplicate(objOut: Appointment()) as! Appointment

    // Duplicate UIU object
    cpAppointment.uiu = self.uiu?.duplicate(objOut: UpdateInfo()) as? UpdateInfo

    // Duplicate AddressLocation object
    let cpAddress = self.addressLocation?.address?.duplicate(objOut: Address()) as? Address
    let cpCoordinates = self.addressLocation?.coordinates?.duplicate(objOut: Coordinates()) as? Coordinates
    cpAppointment.addressLocation = self.addressLocation?.duplicate(objOut: AddressLocation()) as? AddressLocation
    cpAppointment.addressLocation?.address = cpAddress
    cpAppointment.addressLocation?.coordinates = cpCoordinates

    // Duplicate each ExtraInfo
    for other in self.others {
        cpAppointment.others.append(other.duplicate(objOut: ExtraInfo()) as! ExtraInfo)
    }

    return cpAppointment
}

Je n'ai pas pu trouver une bonne et raisonnable façon de travailler avec des objets imbriqués dans ma méthode duplicate (). J'ai pensé à la récursion, mais la complexité du code a trop augmenté.

ce n'est pas optimal mais fonctionne, si je trouve un moyen de gérer aussi objet imbriqué je vais mettre à jour cette réponse.

0
répondu LucioB 2017-02-01 17:46:43