Private attributes/properties and Core Data - swift

I am attempting to transform one of my model objects into a Core Data managed Entity, the object has a private list of sub-objects.
I don't want users of the object to be able to access the list, but instead create, update and calculate values using the business logic in the object, something akin to:
struct MyObject {
private let listOStuff: [String]
func updateBusinessLogic(value: String): MyObject {
// business logic here
return ... // new version of MyObject
}
}
I understand I can use an extension to add the required business logic to the managed object; but is Core Data able to handle the property/attribute being private?
Thanks
PS this is the closest answer I can see to my problem, but I don't think it is the same.

Related

How do I access custom objects for my app?

I have a working linked list data structure for my Swift project but I do not know where to create the object so it can be manipulated. The object needs to persist throughout the app and accessible from different views controllers.
Someone please point me in the right direction. Still looking for help.
Can't if I can create the object I'll be able to connect the data from taps and swipes.
If you want to use only one, unique linked list in you app, you can use a singleton.
class LinkedList {
static let shared = LinkedList()
private init(){}
private var head: Node?
private var tail: Node?
func append(node: Node) {
// your implementation
}
func getHead() -> Node? {
return head
}
// some other methods
}
The private init makes sure that the only possible instance of the LinkedList that you can get is the static one.
You access it like this:
var myUniqueLinkedList = LinkedList.shared
If you want to read more about singletons check this out:
https://cocoacasts.com/what-is-a-singleton-and-how-to-create-one-in-swift
Singletons are a rather controversial topic: What is so bad about singletons?

Core Data Background Thread Returning Inserted NSManagedObject

In my app I am using a NSPersistantContainer with two NSManagedObjectContexts (viewContext & background context). All my read operations are performed on view context, while all my write operations are performed on the background context (shown below).
Creating a new Animal class
class func new(_ eid: String) {
//Create Animal Entity
let container = CoreDataService.persistentContainer
container.performBackgroundTask { (context) in
let mo = Animal(context: context)
mo.eid = eid
mo.lastModified = Date()
mo.purchaseDate = Date()
mo.uuid = UUID()
do {
try context.save()
}
catch let error {
print(error)
}
}
}
The problem I am having is I need to return the newly created NSManagedObject (Animal) back to the manager class, where the Animal.new(eid) was called, to be used to show the object properties.
I have experimented with using a completion handler, but had issues returning the value, as was using a background NSManagedObject in the main thread.
Using possible new function
Animal.new(eid) { (animal) in
if let animal = animal {
}
What is the best approach for returning a newly created NSManagedObject, created in a background context?
What I do is to keep my CoreData managed objects within my CoreDataManager class, not exposing them out to the rest of my framework. So methods that are to create one or more managed objects would accept the data as an unmanaged object, and then create the managed object but not return it (as callers already have the unmanaged object). When fetching from the CoreDataManager, I'd create and populate a unmanaged object(s) and return that.
Now part of why I do this is because I'm using CoreData in a framework, such that I'd never want to hand a managed object to a client app of my framework. But it also solves other problems like the one you described.
(When I write apps, I use Realm, and those objects can go straight to app's UI classes because Realm is so much easier to, erm, manage. :)

Need help understand interfaces and/or abstract classes in angular2

I am new to the angular2 world. I am trying to create interfaces for certain components and then implement these interfaces in my models so I can make sure they will be able to work properly.
One thing I have noticed is that if I create new instances of these objects they work fine but when I pull data from a restful call, I use the type casting to turn the data into the type of object I expect. The following code is a pseudo example.
I come from a Java/C++ background so I am hoping someone can see what I'm trying to do and explain to me how to get this working correctly.
Thanks In Advance!
Doesn't work ---
private vehicles: Vehicle[];
this._vehicleService.loadVehicles().subscribe(
vehicles => this.vehicles = <Vehicle[]>vehicles);
Does Work ---
vehicles : Vehicle[];
vehicles.push(new Vehicle(1, 'Old Junker'));
vehicles.push(new Vehicle(2, 'Old Junker2'));
Example class/interface setup.
#Component
export class SelectableComponent {
options : Selectable[]
// Access options.label and options.value
}
export interface Selectable {
label(): string;
value(): any;
}
export class Vehicle implements Selectable {
constructor (
public id: number,
public description: string,
){}
get label() : any {
return this.description;
}
get value() : any {
return this.id;
}
}
What happens here is that the object retrieved from the backend is just a plain Javascript object that gets cast to a Vehicle:
this._vehicleService.loadVehicles().subscribe(
vehicles => this.vehicles = <Vehicle[]>vehicles);
Objects in this array will have all the data of a Vehicle, but none of the behavior of an instance of the Vehicle class, which can be quite confusing as you mention.
The simplest is instead of casting them, calling new and creating an instance of Vehicle immediately while retrieving them from the backend.
But using a long constructor call can be cumbersome, especially if Vehicle has a lot of properties and you need to pass them all to the constructor one by one.
A way to fix this is to create an auxiliary method in the Vehicle class:
class Vehicle {
constructor(private name, private year) {
}
static fromJson({name,year}) {
return new Vehicle(name, year);
}
}
And then use it in return from the backend to create an array of Vehicles, instead of casting them:
this._vehicleService.loadVehicles().subscribe(
vehicles => this.vehicles = vehicles.map(Vehicle.fromJson));
This way the vehicles in the result will have not only all the data of a vehicle, but also the behavior of the Vehicle class, because they are instances on Vehicle.
The main difference between classes and interfaces in TypeScript is that interfaces don't exist at runtime. They are "only" there for compilation and type checking.
Casting an element to an interface / class "only" tells TypeScript that the object follows the structure of it but it's not actually an instance of the type. It's a bit disturbing at a first sight. The main consequence (in the case of a class) is that casting doesn't allow you to use methods of the class.
I already casted this way:
private vehicles: Vehicle[];
this._vehicleService.loadVehicles().subscribe(
vehicles => this.vehicles = <Vehicle[]>vehicles);
What is the exact compilation error you have?

Wicket - Wrapped collection Model "transformation"

I have a domain object which has a collection of primitive values, which represent the primary keys of another domain object ("Person").
I have a Wicket component that takes IModel<List<Person>>, and allows you to view, remove, and add Persons to the list.
I would like to write a wrapper which implements IModel<List<Person>>, but which is backed by a PropertyModel<List<Long>> from the original domain object.
View-only is easy (Scala syntax for brevity):
class PersonModel(wrappedModel: IModel[List[Long]]) extends LoadableDetachableModel[List[Person]] {
#SpringBean dao: PersonDao =_
def load: List[Person] = {
// Returns a collection of Persons for each id
wrappedModel.getObject().map { id: Long =>
dao.getPerson(id)
}
}
}
But how might I write this to allow for adding and removing from the original List of Longs?
Or is a Model not the best place to do this translation?
Thanks!
You can do something like this:
class PersonModel extends Model<List<Person>> {
private transient List<Person> cache;
private IModel<List<String>> idModel;
public PersonModel( IModel<List<String>> idModel ) {
this.idModel = idModel;
}
public List<Person> getObject() {
if ( cache == null ) {
cache = convertIdsToPersons( idModel.getObject() );
return cache;
}
public void setObject( List<Person> ob ) {
cache = null;
idModel.setObject( convertPersonsToIds( ob ) );
}
}
This isn't very good code but it shows the general idea. One thing you need to consider is how this whole thing will be serialised between requests, you might be better off extending LoadableDetachableModel instead.
Another thing is the cache: it's there to avoid having to convert the list every time getObject() is called within a request. You may or may not need it in practice (depends on a lot of factors, including the speed of the conversion), but if you use it, it means that if something else is modifying the underlying collection, the changes may not be picked up by this model.
I'm not quite sure I understand your question and I don't understand the syntax of Scala.
But, to remove an entity from a list, you can provide a link that simply removes it using your dao. You must be using a repeater to populate your Person list so each repeater entry will have its own Model which can be passed to the deletion link.
Take a look at this Wicket example that uses a link with a repeater to select a contact. You just need to adapt it to delete your Person instead of selecting it.
As for modifying the original list of Longs, you can use the ListView.removeLink() method to get a link component that removes an entry from the backing list.

Dependency Injection - use with Data Transfer Objects (DTOs)?

Consider the code below (which has been simplified). I have a service class that returns a list of specific DTO objects that each implement their own specific interface. In the actual code these are getting populated by iterating thru a Dataset as I'm working with legacy code.
Questions:
How do we create/use a DTO without newing them up or using the Service Locator anti-pattern? It doesn't make much sense to compose an empty DTO object in the Composition Root and inject it into the Service class via the constructor, because I'd actually be using the DTO as a temporary variable of sorts while populating a list.
In the code you can see an example of me newing up the DTO. But this doesn't feel much
better than if I made the DTOs not implement interfaces in the first place. So should they not implement interfaces then and thus, not use DI with DTOs?
public class Services : IServices
{
public IList<IDTO> GetDTOs()
{
...
List<IDTO> dtos = new List<IDTO>();
foreach (c in d)
{
DTO dto = new DTO();
dto.x = c.x;
dto.y = c.y;
dto.z = c.z;
dtos.Add(dto);
}
return dtos;
}
}
it doesn't make much sense to me to use any DI for DTOs. I would probably use the Factory Pattern to get DTOs for my model objects.
DTOs don't need their life cycle managed by the container; I would just new them. Dont over-engineer.
I don't think DTOs should implement interfaces, because they aren't likely to implement behavior that will change.
They also shouldn't be injected. Not all objects should be. I think this is an appropriate call to new: create the object, use it, let it go out of scope and be GC'd.
Have a look at AutoMapper. And I agree with #duffymo, I wouldn't use interfaces with DTO's. AutoMapper is a convention-based object to object mapper that will create and populate your DTO's for you. If nothing else it will save you a lot of typing. I've been through the exercise of writing conversion routines to/from DTO's with associated typos. I wish I had found AutoMapper a bit sooner. In the case of your example (where I've nominally made the "from" object of type Order):
public class Services : IServices
{
public IList<DTO> GetDTOs()
{
...
Mapper.CreateMap<Order, DTO>(); // move map creation to startup routine
var dtos = new List<DTO>();
foreach (c in d)
{
dtos.Add( Mapper.Map<Order, DTO>(c));
}
return dtos;
}
}
Or using LINQ
public class Services : IServices
{
public IList<DTO> GetDTOs()
{
...
Mapper.CreateMap<Order, DTO>(); // move map creation to startup routine
return d.Select(c => Mapper.Map<Order, DTO>(c)).ToList();
}
}