@interface Customer : NSObject @property (nonatomic, assign) NSInteger customerId; @property (nonatomic, copy) NSString *fullName; @end
Approche par champ individuel : ```
// Sauvegarde
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:customerId forKey:@"customerId"];
[defaults setObject:fullName forKey:@"fullName"];
[defaults synchronize];
// Lecture
NSInteger retrievedId = [defaults integerForKey:@"customerId"];
NSString *retrievedName = [defaults stringForKey:@"fullName"];
Approche par objet complet : ```
// Sauvegarde [[NSUserDefaults standardUserDefaults] setObject:self forKey:@"customer"];
// Lecture Customer *cachedCustomer = [[NSUserDefaults standardUserDefaults] objectForKey:@"customer"];
**2. Archivage d'objets (NSKeyedArchiver)** L'archivage nécessite la conformité au protocole NSCoding. Il faut implémenter deux méthodes obligatoires : encodeWithCoder: et initWithCoder:. Il est également recommandé d'adopter le protocole NSCopying via copyWithZone:. ```
@interface Customer : NSObject <nscoding nscopying="">
@property (nonatomic, assign) NSInteger customerId;
@property (nonatomic, copy) NSString *fullName;
@end
@implementation Customer
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:@(self.customerId) forKey:@"customerId"];
[encoder encodeObject:self.fullName forKey:@"fullName"];
}
- (instancetype)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (self) {
self.customerId = [[decoder decodeObjectForKey:@"customerId"] integerValue];
self.fullName = [decoder decodeObjectForKey:@"fullName"];
}
return self;
}
- (id)copyWithZone:(NSZone *)zone {
Customer *copy = [[[self class] allocWithZone:zone] init];
copy.customerId = self.customerId;
copy.fullName = [self.fullName copyWithZone:zone];
return copy;
}
+ (BOOL)persistToDisk:(Customer *)customer {
NSString *docsDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *filePath = [docsDir stringByAppendingPathComponent:@"customer.dat"];
return [NSKeyedArchiver archiveRootObject:customer toFile:filePath];
}
@end
</nscoding>
3. SQLite3 SQLite est un moteur de base de données relationnelle embarqué, publié en 2000 par D. Richard Hipp. Il s'intègre directement au processus de l'application, partageant le même espace mémoire, ce qui élimine tout overhead réseau. Sa portabilité, sa légèreté et sa fiabilité en font un choix adapté aux appareils mobiles. Le verrouillage s'effectue au niveau de la base et les permissions reposnet uniquement sur le système de fichiers. Il est déconseillé d'utiliser l'API C de SQLite directement. Préférez des wrappers éprouvés comme FMDB (https://github.com/ccgus/fmdb) qui encapsule proprement les opérations SQLite. 4. Core Data Core Data s'appuie sur SQLite pour le stockage mais masque entièrement la complexité du SQL. La modélisation s'effectue via l'éditeur de modèle de données d'Xcode, où l'on définit les entittés, leurs attributs et relations. Exemple de création ou mise à jour : ```
NSManagedObjectContext *moc = [appDelegate managedObjectContext]; NSError *error;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Entry"]; fetchRequest.predicate = [NSPredicate predicateWithFormat:@"identifier == %d", entryId];
NSArray *results = [moc executeFetchRequest:fetchRequest error:&error];
NSManagedObject *entry = nil; if (results.count > 0) { entry = results.firstObject; } else { entry = [NSEntityDescription insertNewObjectForEntityForName:@"Entry" inManagedObjectContext:moc]; [entry setValue:@(entryId) forKey:@"identifier"]; } [entry setValue:inputField.text forKey:@"content"]; [moc save:&error];
Récupération des données : ```
NSManagedObjectContext *moc = [appDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Entry"];
NSError *error;
NSArray *entries = [moc executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *item in entries) {
NSNumber *identifier = [item valueForKey:@"identifier"];
NSString *content = [item valueForKey:@"content"];
}