2015-10-01 3 views
16

Ho impostato un'API REST all'oggetto realm in iOS. Tuttavia ho riscontrato un problema con la creazione di una bandiera preferita nel mio oggetto. Ho creato un bool preferito, tuttavia ogni volta che l'oggetto viene aggiornato dall'API imposta nuovamente il preferito su false false. Qui voglio che questo flag non sia aggiornato, poiché il preferito è solo memorizzato localmente. Come posso raggiungere questo obiettivo?Impedisci al reame di sovrascrivere una proprietà durante l'aggiornamento di un oggetto

class Pet: Object{ 
    dynamic var id: Int = 1 
    dynamic var title: String = "" 
    dynamic var type: String = "" 
    dynamic var favorite: Bool = false 


    override class func primaryKey() -> String { 
     return "id" 
    } 
} 

CreateOrUpdate

let pet = Pet() 
pet.id = 2 
pet.name = "Dog" 
pet.type = "German Shephard" 


try! realm.write { 
    realm.add(pet, update: true) 
} 
+0

Stai dicendo che non vuoi salvare 'preferito' in Realm? In tal caso, rimuovere 'dynamic' mentre le proprietà dinamiche vengono salvate in Realm. – Abhinav

+0

sto dicendo che il 'preferito' non è memorizzato nel database remoto, quindi ogni volta che apri l'app e aggiunge nuovi oggetti e aggiorna esistenti in base alla chiave primaria' id' imposterà il valore preferito al valore predefinito ('false '). Posso evitare che si aggiorni al valore predefinito? –

+0

Questo è strano. Avrei pensato che i metodi 'createOrUpdate' in Realm non avrebbero toccato le proprietà che non sono specificate nel dizionario. Puoi includere il codice di esempio in cui stai effettivamente salvando/aggiornando i dati dell'API su Realm? – TiM

risposta

15

Ci sono due modi per risolvere questo:

1. Utilizzare un Proprietà ignorata:

Si può dire Reame che una certa proprietà non dovrebbe essere persistito Per evitare che la vostra proprietà favorite sarà persisteva da Realm che devi fare questo:

class Pet: Object{ 
    dynamic var id: Int = 1 
    dynamic var title: String = "" 
    dynamic var type: String = "" 
    dynamic var favorite: Bool = false 

    override class func primaryKey() -> String { 
     return "id" 
    } 

    override static func ignoredProperties() -> [String] { 
     return ["favorite"] 
    } 
} 

o si potrebbe

2. Eseguire un aggiornamento parziale

Oppure si potrebbe dire esplicitamente quali Realm le proprietà devono essere aggiornate quando si aggiorna l'oggetto Pet:

try! realm.write { 
    realm.create(Pet.self, value: ["id": 2, "name": "Dog", "type": "German Shepard"], update: true) 
} 

In questo modo la proprietà favorite non verrà modificata.

Conclusione

C'è una grande differenza tra i due approcci:

Ignorato Proprietà: Realm non memorizzerà la proprietà favorite a tutti. È tua responsabilità tenerne traccia.

Aggiornamento parziale: Il dominio memorizzerà la proprietà "preferita", ma non verrà aggiornata.

Suppongo che gli aggiornamenti parziali siano ciò di cui hai bisogno per il tuo scopo.

+0

tu risparmi il mio tempo ... grazie –

15

Se si vuole essere più esplicito, non c'è terza opzione:

3. recuperare il valore corrente per l'aggiornamento

// Using the add/update method 
let pet = Pet() 
pet.id = 2 
pet.name = "Dog" 
pet.type = "German Shephard" 

if let currentObject = realm.object(ofType: Pet.self, forPrimaryKey: 2) { 
    pet.favorite = currentObject.favorite 
} 

try! realm.write { 
    realm.add(pet, update: true) 
} 

// Using the create/update method 
var favorite = false 
if let currentObject = realm.object(ofType: Pet.self, forPrimaryKey: 2) { 
    favorite = currentObject.favorite 
} 

// Other properties on the pet, such as a list will remain unchanged 
try! realm.write { 
    realm.create(Pet.self, value: ["id": 2, "name": "Dog", "type": "German Shephard", "favorite": favorite], update: true) 
} 
+1

Trovo questa opzione molto più valida di quelli nella risposta accettata. –

+0

ha trovato questa soluzione ottimale. La soluzione 1 non aggiunge l'oggetto e la soluzione 2 sembra un lavoro disordinato. Grazie per questa terza opzione! – SoundShock

+0

Questa dovrebbe essere la risposta accettata. –

0

4. NSUserDefaults (o qualsiasi altro archivio dati, Davvero)

Mi sono imbattuto nello stesso problema e ho optato per l'altra opzione più tradizionale di salvare le cose in un altro archivio dati (NSUserDefaults). Nel mio caso, stavo memorizzando l'ultima volta che un utente ha visualizzato un articolo e la memorizzazione di questi dati in NSUserDefaults sembrava appropriata.Ho fatto qualcosa di simile al seguente:

In primo luogo, definire una chiave unica per l'oggetto che si sta memorizzando (self qui è l'oggetto del modello sta osservando e resa):

- (NSString *)lastViewedDateKey { 
    // Note each item gets a unique key with <className>_<itemId> guaranteeing us uniqueness 
    return [NSString stringWithFormat:@"%@_%ld", self.class.className, (long)self.itemId]; 
} 

Poi, quando un utente visualizza la elemento, impostare la chiave:

- (void)setLastViewedToNow { 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
    [userDefaults setObject:[NSDate date] forKey:self.lastViewedDateKey]; 
    [userDefaults synchronize]; 
} 

Più tardi, lo uso come questo:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
NSDate *createdOnDate = <passed in from elsewhere>; 
NSDate *lastViewedDate = [userDefaults objectForKey:self.lastViewedDateKey]; 
if (!lastViewedDate || [createdOnDate compare:lastViewedDate] == NSOrderedDescending) { 
    ... 
} 

Diversamente dalle soluzioni di cui sopra: 1. Non esiste la persistenza dei dati. 2. Questo crea un altro posto in cui è necessario definire le proprietà di un oggetto e probabilmente porterà ad errori se si dimentica di aggiornare questo elenco ogni volta che viene aggiunta una nuova proprietà. 3. Se si stanno eseguendo aggiornamenti batch di grandi dimensioni, tornare indietro attraverso ogni oggetto non è molto pratico e sicuramente causerà dolore lungo la strada.

Spero che questo dia a qualcuno un'altra opzione se ne ha bisogno.