How to add property in RLMObject which Realm ignores? - objective-c

I want to add a property of type boolean in a derived RLMObject which is only needed during runtime. So it's not part of the database table. Is there a way to mark the property as not part of the table in Realm?
The reason I need this, is because I want to save the selected state of a uitablecell during runtime. This means, I don't need an extra field in the database table.
I hope my question is clear, thank you.

I think you will want to use ignored properties of Realm:
edit: included the Swift docs link, but the question is about ObjC
https://realm.io/docs/objc/latest/#ignored-properties
Override Object.ignoredProperties() to prevent Realm from persisting model properties. Realm won’t interfere with the regular operation of these properties: they’ll be backed by ivars and you can freely override their setters and getters.

Realm is noSql database so it has no tables - it stores graph of dependencies. That is why you can just create separate 'settings' class, include it in your realm module (#RealmModule) and store single instance of it in realm file for that module. This will be the single instance of that object in database.

Related

Name for class with `get existing or create new` logic

I have an User class, a repository with find method for finding existing user (in a storage) and a factory, which creates new user on demand.
No my question is where would I put the getExistingOrMakeNew method?
I guess it doesn't really fit to respository/factory classes - if so it should be isolated to a separate class. What would be the right name? Is there a known pattern for this?
Maybe just create a factory that have access to repository and can use it during creation process?

How can I set additional properties when an object is persisted from a database using NHibernate?

I'm creating an application that creates a Catalog of files. The data of the catalog will be stored in a database through NHibernate, but the actual files are just stored on a file system. I've abstracted the interface to the file system into an interface called IFileSystemAdaptor.
When an object is persisted from the database I need to set its IFileSystemAdaptor FileSystemAdaptor property so that its methods and properties can access the file system.
For example a user may later call AddAttachment(string filename, Stream data) on the persisted object. This will cause it to write the stream to the specified file name through its IFileSystemAdaptor, and add the new file name to its AttachmenFileNames property which will later be saved to the database.
Where can I insert code to set the the FileSystemAdaptor property for objects that are persisted from the database? Should I add a layer of abstraction between the Session/SessionFactory that sets the FileSystemAdaptor property before returning objects? Or is there someway I can inject this functinality into the SessionFactory so it returns objects with the FileSystemAdaptor already set?
You could write a IPostLoadEventListener to set up your property after getting the entity from the database. Or use a custom bytecode provider to inject your entity with the IFileSystemAdaptor implementation.
I would treat that as an infrastructure concern. Your business logic could interact with the IFileSystemAdaptor and you could use Inversion of Control to pass concrete instances of FileSystemAdaptor to your business logic (the mapping between interface and concrete instance would be defined in web.config or app.config). This would allow you to create unit tests that pass in a mock instance of FileSystemAdaptor so your business logic would not have a dependency on the file system.
I would suggest implementing that class in a layer / project dedicated to infrastructure concerns or possibly an "Application Services" layer intended for application logic that is not necessarily business logic.
Another (potentially unpopular?) option might be to simply use service location for this. I've found this an acceptable way to provide limited services to entities without getting into the complexity of using a custom bytecode provider, etc.

How to pass user details between objects in VB.net?

I'm redesigning an old VB6 application into VB.net and there is one thing I'm not sure on the best way to do.
In the VB6 application whenever we created a new instance of a component, we would pass in the user details (user name and the like) so we new who was performing the tasks. However, no that I'm redesigning I've created some nice class designs, but I'm having to add in user details into every class and it just looks wrong.
Is there a VB.net way of doing this so my classes can just have class specific details? Some way so that if my classes need to know who is performing a task, they can get the information themselves, rather than having it passed in whenever the objects are created?
You could put the details of the current user in a class that is accessible by all class instances of your application.
One place you could consider putting it is in the MyApplication class. You could also create a module and place it there.
Could you wrap the current user details into an object, and pass the object when you create the others? They would just keep a reference, and delegate to the user object for user-specific stuff.
That seems like the obvious way?

Core Data returns NSManagedObject instead of Concrete class, but only when using . accessor

I have set up a Core Data model where I have two objects, say Person and Address. A person has an address, and an address can belong to many people. I have modelled it in core data as such (so the double arrow points to Person, while the single arrow goes to Address)
I have then created two classes for those objects, and implemented some custom methods in those classes. In the Core Data model I have entered the names of the classes into them.
If I fetch an Address from Core Data directly, it gives me the actual concrete class and I can call my custom methods on it.
If on the other hand I fetch a Person and try to access the Address through Person (eg: person.address) I get back an NSManagedObject that is an address (eg: I can get to all the core data attributes I've set on it) but it doesn't respond to my custom methods, because it's of type NSManagedObject instead of Address. Is this a limitation of Core Data or am I doing something wrong? If it is a limitation are there any work arounds?
Did you create those classes using the modeller (Select an Entity, File > new file.., Managed Object Class, then select the Model Entity)?
A while ago I had a similar problem because I didn't create my managed object models using the Modeller. What I did to make sure everything was up and running was to copy and save my custom methods (and everything else I'd implemented) and start from scratch using the modeller. Then I was able to customize my model classes again and everything worked just fine.
I know this is not a complete answer but perhaps it can help you until someone explains exactly what is going on.
Cheers!
You probably just forgot to set the name of the class in the model when you created the entity - it defaults to NSManagedObject. Click on Person and Address in the modeller and check, on the far right side where the Entity properties are listed, that the Class field is filled in correctly with the name of the corresponding objective C class and isn't just the default NSManagedObject setting.
Your implementation file for the class probably hasn't been added to the Target that you are running.
(Get Info on the .m file -> Check the targets tab)
If your xcdatamodel has the Class set, if it can't find it at run time it will still work, you will just get NSManagedObject instances back instead. Which will actually work just fine, until you try to add another method to the class, as you have found.

Load configuration constants dynamically invoking the setters?

I'm looking for a nice way to set my configuration constants. My idea was to create a singleton with my config properties. Say mySingletonConf with: URL, USERID, PASSWORD. During the initialization of the sharedInstance, a configuration file should be read to set the properties in mySingletonConf.
Should I use properties for this type of constants? I take they should be class-level properties?
Is it possible to set the configuration dynamically? I. e.
by reading all Setter-Methods of mySingletonConf, then searching the loaded configuration (.plist-Dictionary) for the key == property name and then invoke the settter with the value?
It would be nice to have the things set dynamically, in case new constants are needed. Then I would just have to create new properties and adjust the configuration files.
Am I on the right track?
Thanks for any help!
NSUserDefaults can take care of a lot of stuff and it ensures that the configuration is user-specific, so if multiple users on the same Mac use your program they can configure your program independently. There is also an object in Interface Builder for binding your user interface elements to, making things even easier. If you do want to make your configuration system-wide, you should use the Core Foundation Preference Utilities.
For storing passwords, you can use Apple's Keychain Services. A user is able to specify which programs are allowed to use the stored password (which would ideally be just yours). Storing passwords in NSUserDefaults is also an option if the password is not of any particular importance.
Don't re-invent the wheel; application-wide user-or-host-specific configuration services are provided for you.
Well, it is possible :)
I ended up writing the mentioned Singleton, which has readonly public properties and readwrite access from within the class (used Categories for that, see private setter example).
The vars of the class are filled with values from the .plist file during the initialization. I used the Runtime API to get the list of variables (just search for "objective-c list of variables" on Stackoverflow) and get the value from the loaded.plist dictionary using the var name as key.
The the values can be use almost as constants:
MyConstants* testConstants = [MyConstants sharedInstance];
NSLog(testConstants.PARAM1);