2017-01-04 1 views
0

Pour mes modèles de serveur API j'utilise constructeur comme ça:Sous NSManagedObject pour initialiser facile

@implementation MenuAPIModel 

-(instancetype)initWithServerData:(id)data{ 

    self = [super initWithServerData:data]; 
    return self; 
} 

-(void)performMapping{ 

    _basketId = self.serverData[@"basket_id"]; 
    _orderId = self.serverData[@"order_id"]; 
    _itemId = self.serverData[@"id"]; 
    _name = self.serverData[@"name"] == [NSNull null] ? @"" : self.serverData[@"persons"]; 
    _payedFrom = [self.dfDetail dateFromString:self.serverData[@"payed_from"]] == nil ? [self.dfBasic dateFromString:self.serverData[@"payed_from"]] : [self.dfDetail dateFromString:self.serverData[@"payed_from"]]; 
    _payedTill = [self.dfBasic dateFromString:self.serverData[@"payed_till"]] == nil ? [self.dfBasic dateFromString:self.serverData[@"payed_till"]] : [self.dfDetail dateFromString:self.serverData[@"payed_till"]]; 
    _persons = self.serverData[@"persons"] == [NSNull null] ? @"2-3" : self.serverData[@"persons"]; 
    _price = self.serverData[@"price"] == [NSNull null] ? @(0) : self.serverData[@"price"]; 
    _price3 = self.serverData[@"price3"] == [NSNull null] ? @(0) : self.serverData[@"price3"]; 
    _price12 = self.serverData[@"price12"] == [NSNull null] ? @(0) : self.serverData[@"price12"]; 
    _status = self.serverData[@"status"] == [NSNull null] ? @"not_payed" : self.serverData[@"persons"]; 
} 

, je peux créer un objet avec simplement écrit: [MenuAPIModel initWithServerData:data];

Maintenant, je sous-classe NSManagedObject et je me demande, comment Puis-je sous-classer ces 4 fichiers créés par XCode pour moi, pour faire un constructeur comme celui ci-dessus?

Répondre

1

Vous pouvez créer genre d'aide qui peut avoir la suite la mise en œuvre (il est juste exemple si je Swift):

static open func createObject <T : NSManagedObject> (_ objectType : T.Type, record : Dictionary<String, Any>? = nil, context : NSManagedObjectContext) -> (T) 
{ 
    let newObject = NSEntityDescription.insertNewObject(forEntityName: String(describing: objectType), into: context) 

    // Error never occured 

    var typedNewObject = newObject as! T 

    guard let trueRecord = record 
    else 
    { 
     return typedNewObject 
    } 

    typedNewObject = updateObject(typedNewObject, record: trueRecord, context: context) 

    return typedNewObject 
} 

static open func updateObject <T : NSManagedObject> (_ object : T, record : Dictionary<String, Any>, context : NSManagedObjectContext) -> (T) 
{ 
    for (key, value) in record 
    { 
     setValue(value, key: key, object: object) 
    } 

    return object 
} 

static public func setValue (_ value : Any, key : String, object : NSManagedObject) -> (Void) 
{ 
    object.setValue(value, forKey: key) 
} 

Avec ces méthodes, vous pouvez alors saisir:

let myNewObject = Helper.createObject(YourClassName.self, record: yourDictionary, context: yourContext) // Helper, or any other class name you give it. 

J'espère que ce assez proche de ce dont vous avez besoin.

1

Je ne comprends pas bien ce que vous voulez sous-classe, mais pour utiliser CoreData vos modèles doivent sous-classe NSManagedObject, donc si vous voulez sous-classe d'une classe de modèle personnalisé que vous avez écrit, cette classe doit sous-classe NSManagedObject.

Maintenant, les nouveaux modèles XCode pour NSManagedObject crée une classe et une catégorie pour chaque modèle que vous déclarez dans xcdatamodel. Et vous auriez quelque chose comme ça.

MenuAPIModel + CoreDataProperties.h

@interface MenuAPIModel (CoreDataProperties) { 
} 
@property(nonatomic, strong) NSNumber *basketId 
.....other properties that you have 
@end 

MenuAPIModel + CoreDataProperties.m

@implementation MenuAPIModel (CoreDataProperties) 
@dynamic basketId 
@dynamic ....other properties ... 
@end 

MenuAPIModel.h

@interface MenuAPIModel : NSManagedObject 
+(instancetype)initWithServerData:(id)serverData; 
@end 

MenuAPIModel.m

@implementation MenuAPIModel 

+(instancetype)initWithServerData:(id)serverData { 
    NSManagedObjectContext *context = ...get the current context... 
    MenuAPIModel *model = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([MenuAPIModel class])inManagedObjectContext:context]; 
    model.basketId = serverData[@"basket_id"]; 
    ...other parsing.... 
    return model; 
} 

Comme vous pouvez le voir, vous pouvez utiliser ces classes & catégories créées par défaut par XCode, en ajoutant juste une méthode supplémentaire. Juste un rappel, NSManagedObject ne peut pas être créé en utilisant alloc] init];, il doit être créé en utilisant le NSManagedObjectContext.

+0

Je vois, vous mettez toute la logique dans le modèle de l'API. Mais je veux faire l'inverse - créer et remplir le modèle de données de base basé sur la classe API Model terminée. Par exemple, comment créer quelque chose comme [modèle initWithData: instance de MenuAPIModell]; ? –

+0

@EvgeniyKleban Vous pouvez remplir le modèle de données de base comme vous voulez, la partie importante est comment vous initiez le modèle de données de code (comme je l'ai fait). – danypata