Is it possible to use Realm (in Swift) without subclassing Object? - ios

I'd like to use Realm in Swift without subclassing Object; using Plain Old Swift Objects rather than Realm objects. The reason being I want to keep the Realm abstraction from leaking from my data layers into presentation.
Is this possible?
I could probably have a dedicated Realm object and then perform a mapping to a POSO but that shouldn't be necessary, really.

Yes, you can do that by using Unrealm library. Instead of inheriting from Object class you must just conform to the protocol Realmable. Even more, this enables you save value types (structs) as well!
Example:

To use Realm, you must subclass Realm Object. The Realm.add(_:update:) method requires an Object argument.

You can find some example of abstraction here:
https://medium.com/#gonzalezreal/using-realm-with-value-types-b69947741e8b

Related

Upcasting NSObject to RLMObject

How would you upcast an NSObject to a RLMObject?
Say you have a model object that's of type NSObject, and say you wanted to dynamically upcast it to RLMObject, how would you do it?
It's worth mentioning that RLMObject's properties can't be populated at runtime, else I probably would've done it through <objc/runtime.h>. (I mean.. They technically can... It would just be too much of a hack)
What I'm trying to do:
The main purpose behind this is to create a caching framework that would dynamically choose between interchangeable caching dependencies such as Realm, SQLite, Core Data, etc. For example, I imagine having a preprocessor flag to hopefully switch from using Realm to SQLite, without having to change my models subclass.
This would require all of my models being a subclass of NSObject, simply because RLMObject wouldn't make sense in a SQLite environment for example.
I've been thinking about this a whole lot, and here's my approach:
1) Loop through the NSObject's properties at runtime & create a key/value object of them
2) Create a subclass of RLMObject at runtime and copy the property list from the passed NSObject model
3) Utilize Realm's initWithValue: to populate the properties
What's your opinion?
It looks like this method that you mention - RLMObject.initWithValue or a static equivalent createInDefaultRealmWithValue has to be called on an RLMObject subclass, or else it throws an exception: "Object type 'RLMObject' is not managed by the Realm".
You need a dynamic schema creation API (what underlies RLMObject), that I don't see being a public API.
An alternative would be to manually encode the object to some dictionary or NSData and attach it to a fixed RLMObject subclass.
You might lose some Realm features by not inheriting RLMObject like knowing when the object becomes dirty, but still probably get some success.
I think you'll get the same problem with Core Data. Normally Core Data supports only NSManagedObject subclasses, and moreover it requires you to define a fixed schema in advance in a model file (represented in code by NSManagedObjectModel).
Of course you could just treat your objects as dictionaries of property names and values, and place them into a giant ("type","id","property","value") table, but it is not the best approach (likely to be slow).
The same strategy is possible to implement with the SQLite backend. Interesting to see which schema would you choose for this.
I'd recommend to look at key-value stores as the backend for this, and avoid SQL. Or treat SQL as a key-value store, as in ("type+id", "encoded_object_data") :)

Cache Array of Custom Objects in Swift3

I need to persist an array of custom objects from session to session for a user. The array will be filled with 1-14 fairly simple and lightweight custom swift objects like so:
[Obj1, Obj2, Obj3]
What I want to do is when viewWillDisappear is called, persist this data so that when the user comes back to the screen, I can use these exact objects again. What is the best way to do this? I've looked into using core data, but I don't want to setup a data model for these objects, just store them as is without any relationships or anything.
Please note that the app makes use of a very computationally taxing algorithm, of which these objects play a central role. As such, I need to keep these objects as light as possible. Therefore, I don't want to make the objects conform to NSCoding as it isn't necessary to the central role of the object
If making your class an Objective-C class that conforms to NSCoding proves to actually have a substantial performance impact (I'm skeptical), then you can make a second container that subclasses NSCoding that's used solely for storage. Add an initializer to your current lightweight Swift class/struct that initializes the instance from this container object, and vice versa. Any time you need to serialize/deserialize, you just use this container object as an intermediate.
This buys you the functionality at minimal cost when reading/writing, but leaves regular usage performance unaffected.
If you can make the object a subclass of NSObject then you can have it conform to NSCoding and use NSKeyedArchiver and NSKeyedUnarchiver to serialize and deserialize your objects.

Making a single copy of a singleton

a design question:
I have a singleton (in objective-C but it doesn't really matter)
The singleton is a class (object) that is actually a data structure that many classes access, and is single (hence - a singleton)
Now I want to add the ability to undo - which is actually saving a snapshot of the state of the object - so I can go back to it.
What I actually need to do is to break the singleton-ness of the object (need one copy of it).
But this will not allow me to share it conveniently between all the classes.
Ideas?
"The singleton is a class (object) that is actually a data structure that many classes access, and is single"
I think it is easier to make your singleton object have a collection of the data structure. Then you just create copies of the data structure instead of copies of singleton.
The singleton pattern came in vogue about 10 years ago when design patterns were first being adopted by developers. In the years since then, the singleton has fallen into disuse because it is notoriously difficult to mock in unit tests. So the simplest answer is to abandon the singleton pattern completely in favor of a more friendly pattern.
You could implement a - (id) copy method in your singleton class.
In this method, allocate a new instance of your class, and set all it's properties to a copy of your shared instance's properties.

Why isn't there a default implementation of NSCoding?

I understand how to use NSCoding to convert my objects to archive objects. That's not my question.
What I'm wondering is why there isn't a default implementation of NSCoding that could handle probably 99% of cases.
For instance, every time I write a custom class that I want to archive, I perform the following:
Implement -(void)encodeWithCoder: and -(id)initWithCoder:.
Go down my property list, writing a pair of statements (one encode, one decode) for each property.
If the property is an object, I use the encode/decodeObject method.
If the property is a value, I use the corresponding encode/decode method.
I always use the property's name as my key.
I would suspect that almost every implementation of NSCoding is exactly like mine, with the only changes being the particular properties that need to be manipulated.
It seems to me that this would be a perfect place for a standard implementation, with the option to override if your particular case if funky.
Do I have a misunderstanding of what's going on? If not, could I add a category on NSObject to implement this common method on all objects in my projects?
I suspect that the answer to your question is simply that NSCoding was designed long before Objective-C properties existed. (NSCoding was part of the OpenStep spec in 1994, whereas properties arrived with Objective-C 2.0 in 2007.) Additionally, some classes have properties that are not appropriate to be serialized for later.
However, your proposed solution could be a great time-saver! At least one such solution already exists. Check out AutoCoding.

Objective C - Add property in runtime

I'd like to add an ivar to an existing objective-c class in runtime, but documentation states that an ivar cannot be an existing class, so I think property could still solve my issue.
As stated here class_addProperty(...) returns true, but when I try to access the ivar by it's name (or the property name) it always returns nil. What could be the issue causing this to happen?
You won't be able to add an ivar to the class at runtime. You can think of the class, and its ivars, as something like a C struct. It's layout is defined at compile time.
You can add properties at runtime (since these are just methods), and you can implement their getters and setters, but you'll need to come up with a different way to store any data that they represent.
Are you looking for something similar with some other programming language?
it looks like adding properties in AS3, but objc think the best would you use to store NSDictionary objects by keys.

Resources